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>
81 /* #define DEBUG_CONTENT 1 */
83 /* #define DEBUG_TYPE 1 */
85 /* #define DEBUG_CONTENT_REGEXP 1 */
87 /* #define DEBUG_AUTOMATA 1 */
89 /* #define DEBUG_IDC */
91 /* #define DEBUG_IDC_NODE_TABLE */
93 /* #define WXS_ELEM_DECL_CONS_ENABLED */
96 #ifndef DEBUG_IDC_NODE_TABLE
97 #define DEBUG_IDC_NODE_TABLE
101 /* #define ENABLE_PARTICLE_RESTRICTION 1 */
103 #define ENABLE_REDEFINE
105 /* #define ENABLE_NAMED_LOCALS */
107 /* #define ENABLE_IDC_NODE_TABLES_TEST */
109 #define DUMP_CONTENT_MODEL
111 #ifdef LIBXML_READER_ENABLED
112 /* #define XML_SCHEMA_READER_ENABLED */
115 #define UNBOUNDED (1 << 30)
117 xmlGenericError(xmlGenericErrorContext, \
118 "Unimplemented block at %s:%d\n", \
121 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
124 * The XML Schemas namespaces
126 static const xmlChar
*xmlSchemaNs
= (const xmlChar
*)
127 "http://www.w3.org/2001/XMLSchema";
129 static const xmlChar
*xmlSchemaInstanceNs
= (const xmlChar
*)
130 "http://www.w3.org/2001/XMLSchema-instance";
132 static const xmlChar
*xmlNamespaceNs
= (const xmlChar
*)
133 "http://www.w3.org/2000/xmlns/";
136 * Come casting macros.
138 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
139 #define PCTXT_CAST (xmlSchemaParserCtxtPtr)
140 #define VCTXT_CAST (xmlSchemaValidCtxtPtr)
141 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
142 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
143 #define WXS_PTC_CAST (xmlSchemaParticlePtr)
144 #define WXS_TYPE_CAST (xmlSchemaTypePtr)
145 #define WXS_ELEM_CAST (xmlSchemaElementPtr)
146 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
147 #define WXS_ATTR_CAST (xmlSchemaAttributePtr)
148 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
149 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
150 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
151 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
152 #define WXS_IDC_CAST (xmlSchemaIDCPtr)
153 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
154 #define WXS_LIST_CAST (xmlSchemaItemListPtr)
157 * Macros to query common properties of components.
159 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
161 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
163 * Macros for element declarations.
165 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
167 #define WXS_SUBST_HEAD(item) (item)->refDecl
169 * Macros for attribute declarations.
171 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
173 * Macros for attribute uses.
175 #define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
177 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
179 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
181 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
183 * Macros for attribute groups.
185 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
186 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
188 * Macros for particles.
190 #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
192 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
194 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
196 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
198 * Macros for model groups definitions.
200 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
202 * Macros for model groups.
204 #define WXS_IS_MODEL_GROUP(i) \
205 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
206 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
207 ((i)->type == XML_SCHEMA_TYPE_ALL))
209 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
211 * Macros for schema buckets.
213 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
214 ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
216 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
217 ((t) == XML_SCHEMA_SCHEMA_IMPORT))
219 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
221 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
223 * Macros for complex/simple types.
225 #define WXS_IS_ANYTYPE(i) \
226 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
227 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
229 #define WXS_IS_COMPLEX(i) \
230 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
231 ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
233 #define WXS_IS_SIMPLE(item) \
234 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
235 ((item->type == XML_SCHEMA_TYPE_BASIC) && \
236 (item->builtInType != XML_SCHEMAS_ANYTYPE)))
238 #define WXS_IS_ANY_SIMPLE_TYPE(i) \
239 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
240 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
242 #define WXS_IS_RESTRICTION(t) \
243 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
245 #define WXS_IS_EXTENSION(t) \
246 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
248 #define WXS_IS_TYPE_NOT_FIXED(i) \
249 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
250 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
252 #define WXS_IS_TYPE_NOT_FIXED_1(item) \
253 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
254 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
256 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
258 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
260 * Macros for exclusively for complex types.
262 #define WXS_HAS_COMPLEX_CONTENT(item) \
263 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
264 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
265 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
267 #define WXS_HAS_SIMPLE_CONTENT(item) \
268 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
269 (item->contentType == XML_SCHEMA_CONTENT_BASIC))
271 #define WXS_HAS_MIXED_CONTENT(item) \
272 (item->contentType == XML_SCHEMA_CONTENT_MIXED)
274 #define WXS_EMPTIABLE(t) \
275 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
277 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
279 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
281 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
283 * Macros for exclusively for simple types.
285 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
287 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
289 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
291 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
293 * Misc parser context macros.
295 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
297 #define WXS_HAS_BUCKETS(ctx) \
298 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
299 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
301 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
303 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
305 #define WXS_SCHEMA(ctx) (ctx)->schema
307 #define WXS_ADD_LOCAL(ctx, item) \
308 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
310 #define WXS_ADD_GLOBAL(ctx, item) \
311 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
313 #define WXS_ADD_PENDING(ctx, item) \
314 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
316 * xmlSchemaItemList macros.
318 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
322 #define IS_SCHEMA(node, type) \
323 ((node != NULL) && (node->ns != NULL) && \
324 (xmlStrEqual(node->name, (const xmlChar *) type)) && \
325 (xmlStrEqual(node->ns->href, xmlSchemaNs)))
327 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
330 * Since we put the default/fixed values into the dict, we can
331 * use pointer comparison for those values.
332 * REMOVED: (xmlStrEqual((v1), (v2)))
334 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
336 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
338 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
340 #define HFAILURE if (res == -1) goto exit_failure;
342 #define HERROR if (res != 0) goto exit_error;
344 #define HSTOP(ctx) if ((ctx)->stop) goto exit;
346 * Some flags used for various schema constraints.
348 #define SUBSET_RESTRICTION 1<<0
349 #define SUBSET_EXTENSION 1<<1
350 #define SUBSET_SUBSTITUTION 1<<2
351 #define SUBSET_LIST 1<<3
352 #define SUBSET_UNION 1<<4
354 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo
;
355 typedef xmlSchemaNodeInfo
*xmlSchemaNodeInfoPtr
;
357 typedef struct _xmlSchemaItemList xmlSchemaItemList
;
358 typedef xmlSchemaItemList
*xmlSchemaItemListPtr
;
359 struct _xmlSchemaItemList
{
360 void **items
; /* used for dynamic addition of schemata */
361 int nbItems
; /* used for dynamic addition of schemata */
362 int sizeItems
; /* used for dynamic addition of schemata */
365 #define XML_SCHEMA_CTXT_PARSER 1
366 #define XML_SCHEMA_CTXT_VALIDATOR 2
368 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt
;
369 typedef xmlSchemaAbstractCtxt
*xmlSchemaAbstractCtxtPtr
;
370 struct _xmlSchemaAbstractCtxt
{
371 int type
; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
372 void *dummy
; /* Fix alignment issues */
375 typedef struct _xmlSchemaBucket xmlSchemaBucket
;
376 typedef xmlSchemaBucket
*xmlSchemaBucketPtr
;
378 #define XML_SCHEMA_SCHEMA_MAIN 0
379 #define XML_SCHEMA_SCHEMA_IMPORT 1
380 #define XML_SCHEMA_SCHEMA_INCLUDE 2
381 #define XML_SCHEMA_SCHEMA_REDEFINE 3
384 * xmlSchemaSchemaRelation:
386 * Used to create a graph of schema relationships.
388 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation
;
389 typedef xmlSchemaSchemaRelation
*xmlSchemaSchemaRelationPtr
;
390 struct _xmlSchemaSchemaRelation
{
391 xmlSchemaSchemaRelationPtr next
;
392 int type
; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
393 const xmlChar
*importNamespace
;
394 xmlSchemaBucketPtr bucket
;
397 #define XML_SCHEMA_BUCKET_MARKED 1<<0
398 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
400 struct _xmlSchemaBucket
{
403 const xmlChar
*schemaLocation
;
404 const xmlChar
*origTargetNamespace
;
405 const xmlChar
*targetNamespace
;
407 xmlSchemaSchemaRelationPtr relations
;
412 xmlSchemaItemListPtr globals
; /* Global components. */
413 xmlSchemaItemListPtr locals
; /* Local components. */
418 * (extends xmlSchemaBucket)
420 * Reflects a schema. Holds some information
421 * about the schema and its toplevel components. Duplicate
422 * toplevel components are not checked at this level.
424 typedef struct _xmlSchemaImport xmlSchemaImport
;
425 typedef xmlSchemaImport
*xmlSchemaImportPtr
;
426 struct _xmlSchemaImport
{
427 int type
; /* Main OR import OR include. */
429 const xmlChar
*schemaLocation
; /* The URI of the schema document. */
430 /* For chameleon includes, @origTargetNamespace will be NULL */
431 const xmlChar
*origTargetNamespace
;
433 * For chameleon includes, @targetNamespace will be the
434 * targetNamespace of the including schema.
436 const xmlChar
*targetNamespace
;
437 xmlDocPtr doc
; /* The schema node-tree. */
438 /* @relations will hold any included/imported/redefined schemas. */
439 xmlSchemaSchemaRelationPtr relations
;
444 xmlSchemaItemListPtr globals
;
445 xmlSchemaItemListPtr locals
;
446 /* The imported schema. */
451 * (extends xmlSchemaBucket)
453 typedef struct _xmlSchemaInclude xmlSchemaInclude
;
454 typedef xmlSchemaInclude
*xmlSchemaIncludePtr
;
455 struct _xmlSchemaInclude
{
458 const xmlChar
*schemaLocation
;
459 const xmlChar
*origTargetNamespace
;
460 const xmlChar
*targetNamespace
;
462 xmlSchemaSchemaRelationPtr relations
;
467 xmlSchemaItemListPtr globals
; /* Global components. */
468 xmlSchemaItemListPtr locals
; /* Local components. */
470 /* The owning main or import schema bucket. */
471 xmlSchemaImportPtr ownerImport
;
475 * xmlSchemaBasicItem:
477 * The abstract base type for schema components.
479 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem
;
480 typedef xmlSchemaBasicItem
*xmlSchemaBasicItemPtr
;
481 struct _xmlSchemaBasicItem
{
482 xmlSchemaTypeType type
;
483 void *dummy
; /* Fix alignment issues */
487 * xmlSchemaAnnotItem:
489 * The abstract base type for annotated schema components.
490 * (Extends xmlSchemaBasicItem)
492 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem
;
493 typedef xmlSchemaAnnotItem
*xmlSchemaAnnotItemPtr
;
494 struct _xmlSchemaAnnotItem
{
495 xmlSchemaTypeType type
;
496 xmlSchemaAnnotPtr annot
;
502 * The abstract base type for tree-like structured schema components.
503 * (Extends xmlSchemaAnnotItem)
505 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem
;
506 typedef xmlSchemaTreeItem
*xmlSchemaTreeItemPtr
;
507 struct _xmlSchemaTreeItem
{
508 xmlSchemaTypeType type
;
509 xmlSchemaAnnotPtr annot
;
510 xmlSchemaTreeItemPtr next
;
511 xmlSchemaTreeItemPtr children
;
515 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
517 * xmlSchemaAttributeUsePtr:
519 * The abstract base type for tree-like structured schema components.
520 * (Extends xmlSchemaTreeItem)
522 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse
;
523 typedef xmlSchemaAttributeUse
*xmlSchemaAttributeUsePtr
;
524 struct _xmlSchemaAttributeUse
{
525 xmlSchemaTypeType type
;
526 xmlSchemaAnnotPtr annot
;
527 xmlSchemaAttributeUsePtr next
; /* The next attr. use. */
529 * The attr. decl. OR a QName-ref. to an attr. decl. OR
530 * a QName-ref. to an attribute group definition.
532 xmlSchemaAttributePtr attrDecl
;
536 int occurs
; /* required, optional */
537 const xmlChar
* defValue
;
538 xmlSchemaValPtr defVal
;
542 * xmlSchemaAttributeUseProhibPtr:
544 * A helper component to reflect attribute prohibitions.
545 * (Extends xmlSchemaBasicItem)
547 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib
;
548 typedef xmlSchemaAttributeUseProhib
*xmlSchemaAttributeUseProhibPtr
;
549 struct _xmlSchemaAttributeUseProhib
{
550 xmlSchemaTypeType type
; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
553 const xmlChar
*targetNamespace
;
560 typedef struct _xmlSchemaRedef xmlSchemaRedef
;
561 typedef xmlSchemaRedef
*xmlSchemaRedefPtr
;
562 struct _xmlSchemaRedef
{
563 xmlSchemaRedefPtr next
;
564 xmlSchemaBasicItemPtr item
; /* The redefining component. */
565 xmlSchemaBasicItemPtr reference
; /* The referencing component. */
566 xmlSchemaBasicItemPtr target
; /* The to-be-redefined component. */
567 const xmlChar
*refName
; /* The name of the to-be-redefined component. */
568 const xmlChar
*refTargetNs
; /* The target namespace of the
569 to-be-redefined comp. */
570 xmlSchemaBucketPtr targetBucket
; /* The redefined schema. */
574 * xmlSchemaConstructionCtxt:
576 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt
;
577 typedef xmlSchemaConstructionCtxt
*xmlSchemaConstructionCtxtPtr
;
578 struct _xmlSchemaConstructionCtxt
{
579 xmlSchemaPtr mainSchema
; /* The main schema. */
580 xmlSchemaBucketPtr mainBucket
; /* The main schema bucket */
582 xmlSchemaItemListPtr buckets
; /* List of schema buckets. */
583 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
584 xmlSchemaBucketPtr bucket
; /* The current schema bucket */
585 xmlSchemaItemListPtr pending
; /* All Components of all schemas that
587 xmlHashTablePtr substGroups
;
588 xmlSchemaRedefPtr redefs
;
589 xmlSchemaRedefPtr lastRedef
;
592 #define XML_SCHEMAS_PARSE_ERROR 1
593 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
595 struct _xmlSchemaParserCtxt
{
597 void *errCtxt
; /* user specific error context */
598 xmlSchemaValidityErrorFunc error
; /* the callback in case of errors */
599 xmlSchemaValidityWarningFunc warning
; /* the callback in case of warning */
602 xmlStructuredErrorFunc serror
;
604 xmlSchemaConstructionCtxtPtr constructor
;
605 int ownsConstructor
; /* TODO: Move this to parser *flags*. */
607 /* xmlSchemaPtr topschema; */
608 /* xmlHashTablePtr namespaces; */
610 xmlSchemaPtr schema
; /* The main schema in use */
615 int preserve
; /* Whether the doc should be freed */
621 * Used to build complex element content models
624 xmlAutomataStatePtr start
;
625 xmlAutomataStatePtr end
;
626 xmlAutomataStatePtr state
;
628 xmlDictPtr dict
; /* dictionary for interned string names */
629 xmlSchemaTypePtr ctxtType
; /* The current context simple/complex type */
631 xmlSchemaValidCtxtPtr vctxt
;
635 int stop
; /* If the parser should stop; i.e. a critical error. */
636 const xmlChar
*targetNamespace
;
637 xmlSchemaBucketPtr redefined
; /* The schema to be redefined. */
639 xmlSchemaRedefPtr redef
; /* Used for redefinitions. */
640 int redefCounter
; /* Used for redefinitions. */
641 xmlSchemaItemListPtr attrProhibs
;
647 * A component reference item (not a schema component)
648 * (Extends xmlSchemaBasicItem)
650 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef
;
651 typedef xmlSchemaQNameRef
*xmlSchemaQNameRefPtr
;
652 struct _xmlSchemaQNameRef
{
653 xmlSchemaTypeType type
;
654 xmlSchemaBasicItemPtr item
; /* The resolved referenced item. */
655 xmlSchemaTypeType itemType
;
657 const xmlChar
*targetNamespace
;
664 * A particle component.
665 * (Extends xmlSchemaTreeItem)
667 typedef struct _xmlSchemaParticle xmlSchemaParticle
;
668 typedef xmlSchemaParticle
*xmlSchemaParticlePtr
;
669 struct _xmlSchemaParticle
{
670 xmlSchemaTypeType type
;
671 xmlSchemaAnnotPtr annot
;
672 xmlSchemaTreeItemPtr next
; /* next particle */
673 xmlSchemaTreeItemPtr children
; /* the "term" (e.g. a model group,
674 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
682 * xmlSchemaModelGroup:
684 * A model group component.
685 * (Extends xmlSchemaTreeItem)
687 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup
;
688 typedef xmlSchemaModelGroup
*xmlSchemaModelGroupPtr
;
689 struct _xmlSchemaModelGroup
{
690 xmlSchemaTypeType type
; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
691 xmlSchemaAnnotPtr annot
;
692 xmlSchemaTreeItemPtr next
; /* not used */
693 xmlSchemaTreeItemPtr children
; /* first particle (OR "element decl" OR "wildcard") */
697 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
698 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
700 * xmlSchemaModelGroupDef:
702 * A model group definition component.
703 * (Extends xmlSchemaTreeItem)
705 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef
;
706 typedef xmlSchemaModelGroupDef
*xmlSchemaModelGroupDefPtr
;
707 struct _xmlSchemaModelGroupDef
{
708 xmlSchemaTypeType type
; /* XML_SCHEMA_TYPE_GROUP */
709 xmlSchemaAnnotPtr annot
;
710 xmlSchemaTreeItemPtr next
; /* not used */
711 xmlSchemaTreeItemPtr children
; /* the "model group" */
713 const xmlChar
*targetNamespace
;
718 typedef struct _xmlSchemaIDC xmlSchemaIDC
;
719 typedef xmlSchemaIDC
*xmlSchemaIDCPtr
;
722 * xmlSchemaIDCSelect:
724 * The identity-constraint "field" and "selector" item, holding the
727 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect
;
728 typedef xmlSchemaIDCSelect
*xmlSchemaIDCSelectPtr
;
729 struct _xmlSchemaIDCSelect
{
730 xmlSchemaIDCSelectPtr next
;
732 int index
; /* an index position if significant for IDC key-sequences */
733 const xmlChar
*xpath
; /* the XPath expression */
734 void *xpathComp
; /* the compiled XPath expression */
740 * The identity-constraint definition component.
741 * (Extends xmlSchemaAnnotItem)
744 struct _xmlSchemaIDC
{
745 xmlSchemaTypeType type
;
746 xmlSchemaAnnotPtr annot
;
747 xmlSchemaIDCPtr next
;
750 const xmlChar
*targetNamespace
;
751 xmlSchemaIDCSelectPtr selector
;
752 xmlSchemaIDCSelectPtr fields
;
754 xmlSchemaQNameRefPtr ref
;
760 * The augmented IDC information used for validation.
762 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug
;
763 typedef xmlSchemaIDCAug
*xmlSchemaIDCAugPtr
;
764 struct _xmlSchemaIDCAug
{
765 xmlSchemaIDCAugPtr next
; /* next in a list */
766 xmlSchemaIDCPtr def
; /* the IDC definition */
767 int keyrefDepth
; /* the lowest tree level to which IDC
768 tables need to be bubbled upwards */
772 * xmlSchemaPSVIIDCKeySequence:
774 * The key sequence of a node table item.
776 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey
;
777 typedef xmlSchemaPSVIIDCKey
*xmlSchemaPSVIIDCKeyPtr
;
778 struct _xmlSchemaPSVIIDCKey
{
779 xmlSchemaTypePtr type
;
784 * xmlSchemaPSVIIDCNode:
786 * The node table item of a node table.
788 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode
;
789 typedef xmlSchemaPSVIIDCNode
*xmlSchemaPSVIIDCNodePtr
;
790 struct _xmlSchemaPSVIIDCNode
{
792 xmlSchemaPSVIIDCKeyPtr
*keys
;
799 * xmlSchemaPSVIIDCBinding:
801 * The identity-constraint binding item of the [identity-constraint table].
803 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding
;
804 typedef xmlSchemaPSVIIDCBinding
*xmlSchemaPSVIIDCBindingPtr
;
805 struct _xmlSchemaPSVIIDCBinding
{
806 xmlSchemaPSVIIDCBindingPtr next
; /* next binding of a specific node */
807 xmlSchemaIDCPtr definition
; /* the IDC definition */
808 xmlSchemaPSVIIDCNodePtr
*nodeTable
; /* array of key-sequences */
809 int nbNodes
; /* number of entries in the node table */
810 int sizeNodes
; /* size of the node table */
811 xmlSchemaItemListPtr dupls
;
815 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
816 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
818 #define XPATH_STATE_OBJ_MATCHES -2
819 #define XPATH_STATE_OBJ_BLOCKED -3
821 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher
;
822 typedef xmlSchemaIDCMatcher
*xmlSchemaIDCMatcherPtr
;
825 * xmlSchemaIDCStateObj:
827 * The state object used to evaluate XPath expressions.
829 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj
;
830 typedef xmlSchemaIDCStateObj
*xmlSchemaIDCStateObjPtr
;
831 struct _xmlSchemaIDCStateObj
{
833 xmlSchemaIDCStateObjPtr next
; /* next if in a list */
834 int depth
; /* depth of creation */
835 int *history
; /* list of (depth, state-id) tuples */
838 xmlSchemaIDCMatcherPtr matcher
; /* the correspondent field/selector
840 xmlSchemaIDCSelectPtr sel
;
844 #define IDC_MATCHER 0
847 * xmlSchemaIDCMatcher:
849 * Used to evaluate IDC selectors (and fields).
851 struct _xmlSchemaIDCMatcher
{
853 int depth
; /* the tree depth at creation time */
854 xmlSchemaIDCMatcherPtr next
; /* next in the list */
855 xmlSchemaIDCMatcherPtr nextCached
; /* next in the cache list */
856 xmlSchemaIDCAugPtr aidc
; /* the augmented IDC item */
858 xmlSchemaPSVIIDCKeyPtr
**keySeqs
; /* the key-sequences of the target
861 xmlSchemaItemListPtr targets
; /* list of target-node
862 (xmlSchemaPSVIIDCNodePtr) entries */
863 xmlHashTablePtr htab
;
867 * Element info flags.
869 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0
870 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
871 #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2
872 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3
874 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4
875 #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5
876 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6
878 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7
879 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8
880 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9
881 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10
886 * Holds information of an element node.
888 struct _xmlSchemaNodeInfo
{
892 const xmlChar
*localName
;
893 const xmlChar
*nsName
;
894 const xmlChar
*value
;
895 xmlSchemaValPtr val
; /* the pre-computed value if any */
896 xmlSchemaTypePtr typeDef
; /* the complex/simple type definition if any */
898 int flags
; /* combination of node info flags */
903 xmlSchemaElementPtr decl
; /* the element/attribute declaration */
905 xmlSchemaPSVIIDCBindingPtr idcTable
; /* the table of PSVI IDC bindings
906 for the scope element*/
907 xmlSchemaIDCMatcherPtr idcMatchers
; /* the IDC matchers for the scope
909 xmlRegExecCtxtPtr regexCtxt
;
911 const xmlChar
**nsBindings
; /* Namespace bindings on this element */
916 int appliedXPath
; /* Indicates that an XPath has been applied. */
919 #define XML_SCHEMAS_ATTR_UNKNOWN 1
920 #define XML_SCHEMAS_ATTR_ASSESSED 2
921 #define XML_SCHEMAS_ATTR_PROHIBITED 3
922 #define XML_SCHEMAS_ATTR_ERR_MISSING 4
923 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5
924 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
925 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
926 #define XML_SCHEMAS_ATTR_DEFAULT 8
927 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
928 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
929 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
930 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
931 #define XML_SCHEMAS_ATTR_WILD_SKIP 13
932 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
933 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
934 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
935 #define XML_SCHEMAS_ATTR_META 17
937 * @metaType values of xmlSchemaAttrInfo.
939 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
940 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
941 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
942 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
943 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
945 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo
;
946 typedef xmlSchemaAttrInfo
*xmlSchemaAttrInfoPtr
;
947 struct _xmlSchemaAttrInfo
{
951 const xmlChar
*localName
;
952 const xmlChar
*nsName
;
953 const xmlChar
*value
;
954 xmlSchemaValPtr val
; /* the pre-computed value if any */
955 xmlSchemaTypePtr typeDef
; /* the complex/simple type definition if any */
956 int flags
; /* combination of node info flags */
958 xmlSchemaAttributePtr decl
; /* the attribute declaration */
959 xmlSchemaAttributeUsePtr use
; /* the attribute use */
962 const xmlChar
*vcValue
; /* the value constraint value */
963 xmlSchemaNodeInfoPtr parent
;
967 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
969 * xmlSchemaValidCtxt:
971 * A Schemas validation context
973 struct _xmlSchemaValidCtxt
{
975 void *errCtxt
; /* user specific data block */
976 xmlSchemaValidityErrorFunc error
; /* the callback in case of errors */
977 xmlSchemaValidityWarningFunc warning
; /* the callback in case of warning */
978 xmlStructuredErrorFunc serror
;
980 xmlSchemaPtr schema
; /* The schema in use */
982 xmlParserInputBufferPtr input
;
984 xmlSAXHandlerPtr sax
;
985 xmlParserCtxtPtr parserCtxt
;
986 void *user_data
; /* TODO: What is this for? */
994 /* xmlSchemaTypePtr type; */
996 xmlRegExecCtxtPtr regexp
;
997 xmlSchemaValPtr value
;
1001 xmlNodePtr validationRoot
;
1002 xmlSchemaParserCtxtPtr pctxt
;
1006 xmlSchemaNodeInfoPtr
*elemInfos
; /* array of element information */
1008 xmlSchemaNodeInfoPtr inode
; /* the current element information */
1010 xmlSchemaIDCAugPtr aidcs
; /* a list of augmented IDC information */
1012 xmlSchemaIDCStateObjPtr xpathStates
; /* first active state object. */
1013 xmlSchemaIDCStateObjPtr xpathStatePool
; /* first stored state object. */
1014 xmlSchemaIDCMatcherPtr idcMatcherCache
; /* Cache for IDC matcher objects. */
1016 xmlSchemaPSVIIDCNodePtr
*idcNodes
; /* list of all IDC node-table entries*/
1020 xmlSchemaPSVIIDCKeyPtr
*idcKeys
; /* list of all IDC node-table entries */
1028 #ifdef LIBXML_READER_ENABLED
1029 xmlTextReaderPtr reader
;
1032 xmlSchemaAttrInfoPtr
*attrInfos
;
1037 xmlSchemaItemListPtr nodeQNames
;
1039 int createIDCNodeTables
;
1040 int psviExposeIDCNodeTables
;
1042 /* Locator for error reporting in streaming mode */
1043 xmlSchemaValidityLocatorFunc locFunc
;
1048 * xmlSchemaSubstGroup:
1052 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup
;
1053 typedef xmlSchemaSubstGroup
*xmlSchemaSubstGroupPtr
;
1054 struct _xmlSchemaSubstGroup
{
1055 xmlSchemaElementPtr head
;
1056 xmlSchemaItemListPtr members
;
1062 * an entry in hash tables to quickly look up keys/uniques
1064 typedef struct _xmlIDCHashEntry xmlIDCHashEntry
;
1065 typedef xmlIDCHashEntry
*xmlIDCHashEntryPtr
;
1066 struct _xmlIDCHashEntry
{
1067 xmlIDCHashEntryPtr next
; /* next item with same hash */
1068 int index
; /* index into associated item list */
1071 /************************************************************************
1073 * Some predeclarations *
1075 ************************************************************************/
1077 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt
,
1078 xmlSchemaPtr schema
,
1080 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt
,
1081 xmlSchemaPtr schema
,
1084 xmlSchemaTypeFixup(xmlSchemaTypePtr type
,
1085 xmlSchemaAbstractCtxtPtr ctxt
);
1086 static const xmlChar
*
1087 xmlSchemaFacetTypeToString(xmlSchemaTypeType type
);
1089 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1092 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl
,
1093 xmlSchemaParserCtxtPtr ctxt
);
1095 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt
);
1096 static xmlSchemaWhitespaceValueType
1097 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type
);
1098 static xmlSchemaTreeItemPtr
1099 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
1100 xmlNodePtr node
, xmlSchemaTypeType type
,
1102 static const xmlChar
*
1103 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item
);
1104 static xmlSchemaTypeLinkPtr
1105 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type
);
1107 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt
,
1108 const char *funcName
,
1109 const char *message
) LIBXML_ATTR_FORMAT(3,0);
1111 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt
,
1112 xmlSchemaTypePtr type
,
1113 xmlSchemaTypePtr baseType
,
1116 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl
,
1117 xmlSchemaParserCtxtPtr ctxt
);
1119 xmlSchemaComponentListFree(xmlSchemaItemListPtr list
);
1120 static xmlSchemaQNameRefPtr
1121 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt
,
1122 xmlSchemaPtr schema
,
1125 /************************************************************************
1127 * Helper functions *
1129 ************************************************************************/
1132 * xmlSchemaItemTypeToStr:
1133 * @type: the type of the schema item
1135 * Returns the component name of a schema item.
1137 static const xmlChar
*
1138 xmlSchemaItemTypeToStr(xmlSchemaTypeType type
)
1141 case XML_SCHEMA_TYPE_BASIC
:
1142 return(BAD_CAST
"simple type definition");
1143 case XML_SCHEMA_TYPE_SIMPLE
:
1144 return(BAD_CAST
"simple type definition");
1145 case XML_SCHEMA_TYPE_COMPLEX
:
1146 return(BAD_CAST
"complex type definition");
1147 case XML_SCHEMA_TYPE_ELEMENT
:
1148 return(BAD_CAST
"element declaration");
1149 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
1150 return(BAD_CAST
"attribute use");
1151 case XML_SCHEMA_TYPE_ATTRIBUTE
:
1152 return(BAD_CAST
"attribute declaration");
1153 case XML_SCHEMA_TYPE_GROUP
:
1154 return(BAD_CAST
"model group definition");
1155 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
1156 return(BAD_CAST
"attribute group definition");
1157 case XML_SCHEMA_TYPE_NOTATION
:
1158 return(BAD_CAST
"notation declaration");
1159 case XML_SCHEMA_TYPE_SEQUENCE
:
1160 return(BAD_CAST
"model group (sequence)");
1161 case XML_SCHEMA_TYPE_CHOICE
:
1162 return(BAD_CAST
"model group (choice)");
1163 case XML_SCHEMA_TYPE_ALL
:
1164 return(BAD_CAST
"model group (all)");
1165 case XML_SCHEMA_TYPE_PARTICLE
:
1166 return(BAD_CAST
"particle");
1167 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
1168 return(BAD_CAST
"unique identity-constraint");
1169 /* return(BAD_CAST "IDC (unique)"); */
1170 case XML_SCHEMA_TYPE_IDC_KEY
:
1171 return(BAD_CAST
"key identity-constraint");
1172 /* return(BAD_CAST "IDC (key)"); */
1173 case XML_SCHEMA_TYPE_IDC_KEYREF
:
1174 return(BAD_CAST
"keyref identity-constraint");
1175 /* return(BAD_CAST "IDC (keyref)"); */
1176 case XML_SCHEMA_TYPE_ANY
:
1177 return(BAD_CAST
"wildcard (any)");
1178 case XML_SCHEMA_EXTRA_QNAMEREF
:
1179 return(BAD_CAST
"[helper component] QName reference");
1180 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
:
1181 return(BAD_CAST
"[helper component] attribute use prohibition");
1183 return(BAD_CAST
"Not a schema component");
1188 * xmlSchemaGetComponentTypeStr:
1189 * @type: the type of the schema item
1191 * Returns the component name of a schema item.
1193 static const xmlChar
*
1194 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item
)
1196 switch (item
->type
) {
1197 case XML_SCHEMA_TYPE_BASIC
:
1198 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item
))
1199 return(BAD_CAST
"complex type definition");
1201 return(BAD_CAST
"simple type definition");
1203 return(xmlSchemaItemTypeToStr(item
->type
));
1208 * xmlSchemaGetComponentNode:
1209 * @item: a schema component
1211 * Returns node associated with the schema component.
1212 * NOTE that such a node need not be available; plus, a component's
1213 * node need not to reflect the component directly, since there is no
1214 * one-to-one relationship between the XML Schema representation and
1215 * the component representation.
1218 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item
)
1220 switch (item
->type
) {
1221 case XML_SCHEMA_TYPE_ELEMENT
:
1222 return (((xmlSchemaElementPtr
) item
)->node
);
1223 case XML_SCHEMA_TYPE_ATTRIBUTE
:
1224 return (((xmlSchemaAttributePtr
) item
)->node
);
1225 case XML_SCHEMA_TYPE_COMPLEX
:
1226 case XML_SCHEMA_TYPE_SIMPLE
:
1227 return (((xmlSchemaTypePtr
) item
)->node
);
1228 case XML_SCHEMA_TYPE_ANY
:
1229 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE
:
1230 return (((xmlSchemaWildcardPtr
) item
)->node
);
1231 case XML_SCHEMA_TYPE_PARTICLE
:
1232 return (((xmlSchemaParticlePtr
) item
)->node
);
1233 case XML_SCHEMA_TYPE_SEQUENCE
:
1234 case XML_SCHEMA_TYPE_CHOICE
:
1235 case XML_SCHEMA_TYPE_ALL
:
1236 return (((xmlSchemaModelGroupPtr
) item
)->node
);
1237 case XML_SCHEMA_TYPE_GROUP
:
1238 return (((xmlSchemaModelGroupDefPtr
) item
)->node
);
1239 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
1240 return (((xmlSchemaAttributeGroupPtr
) item
)->node
);
1241 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
1242 case XML_SCHEMA_TYPE_IDC_KEY
:
1243 case XML_SCHEMA_TYPE_IDC_KEYREF
:
1244 return (((xmlSchemaIDCPtr
) item
)->node
);
1245 case XML_SCHEMA_EXTRA_QNAMEREF
:
1246 return(((xmlSchemaQNameRefPtr
) item
)->node
);
1247 /* TODO: What to do with NOTATIONs?
1248 case XML_SCHEMA_TYPE_NOTATION:
1249 return (((xmlSchemaNotationPtr) item)->node);
1251 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
1252 return (((xmlSchemaAttributeUsePtr
) item
)->node
);
1260 * xmlSchemaGetNextComponent:
1261 * @item: a schema component
1263 * Returns the next sibling of the schema component.
1265 static xmlSchemaBasicItemPtr
1266 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item
)
1268 switch (item
->type
) {
1269 case XML_SCHEMA_TYPE_ELEMENT
:
1270 return ((xmlSchemaBasicItemPtr
) ((xmlSchemaElementPtr
) item
)->next
);
1271 case XML_SCHEMA_TYPE_ATTRIBUTE
:
1272 return ((xmlSchemaBasicItemPtr
) ((xmlSchemaAttributePtr
) item
)->next
);
1273 case XML_SCHEMA_TYPE_COMPLEX
:
1274 case XML_SCHEMA_TYPE_SIMPLE
:
1275 return ((xmlSchemaBasicItemPtr
) ((xmlSchemaTypePtr
) item
)->next
);
1276 case XML_SCHEMA_TYPE_ANY
:
1277 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE
:
1279 case XML_SCHEMA_TYPE_PARTICLE
:
1280 return ((xmlSchemaBasicItemPtr
) ((xmlSchemaParticlePtr
) item
)->next
);
1281 case XML_SCHEMA_TYPE_SEQUENCE
:
1282 case XML_SCHEMA_TYPE_CHOICE
:
1283 case XML_SCHEMA_TYPE_ALL
:
1285 case XML_SCHEMA_TYPE_GROUP
:
1287 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
1288 return ((xmlSchemaBasicItemPtr
) ((xmlSchemaAttributeGroupPtr
) item
)->next
);
1289 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
1290 case XML_SCHEMA_TYPE_IDC_KEY
:
1291 case XML_SCHEMA_TYPE_IDC_KEYREF
:
1292 return ((xmlSchemaBasicItemPtr
) ((xmlSchemaIDCPtr
) item
)->next
);
1301 * xmlSchemaFormatQName:
1302 * @buf: the string buffer
1303 * @namespaceName: the namespace name
1304 * @localName: the local name
1306 * Returns the given QName in the format "{namespaceName}localName" or
1307 * just "localName" if @namespaceName is NULL.
1309 * Returns the localName if @namespaceName is NULL, a formatted
1312 static const xmlChar
*
1313 xmlSchemaFormatQName(xmlChar
**buf
,
1314 const xmlChar
*namespaceName
,
1315 const xmlChar
*localName
)
1318 if (namespaceName
!= NULL
) {
1319 *buf
= xmlStrdup(BAD_CAST
"{");
1320 *buf
= xmlStrcat(*buf
, namespaceName
);
1321 *buf
= xmlStrcat(*buf
, BAD_CAST
"}");
1323 if (localName
!= NULL
) {
1324 if (namespaceName
== NULL
)
1326 *buf
= xmlStrcat(*buf
, localName
);
1328 *buf
= xmlStrcat(*buf
, BAD_CAST
"(NULL)");
1330 return ((const xmlChar
*) *buf
);
1333 static const xmlChar
*
1334 xmlSchemaFormatQNameNs(xmlChar
**buf
, xmlNsPtr ns
, const xmlChar
*localName
)
1337 return (xmlSchemaFormatQName(buf
, ns
->href
, localName
));
1339 return (xmlSchemaFormatQName(buf
, NULL
, localName
));
1342 static const xmlChar
*
1343 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item
)
1348 switch (item
->type
) {
1349 case XML_SCHEMA_TYPE_ELEMENT
:
1350 return (((xmlSchemaElementPtr
) item
)->name
);
1351 case XML_SCHEMA_TYPE_ATTRIBUTE
:
1352 return (((xmlSchemaAttributePtr
) item
)->name
);
1353 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
1354 return (((xmlSchemaAttributeGroupPtr
) item
)->name
);
1355 case XML_SCHEMA_TYPE_BASIC
:
1356 case XML_SCHEMA_TYPE_SIMPLE
:
1357 case XML_SCHEMA_TYPE_COMPLEX
:
1358 return (((xmlSchemaTypePtr
) item
)->name
);
1359 case XML_SCHEMA_TYPE_GROUP
:
1360 return (((xmlSchemaModelGroupDefPtr
) item
)->name
);
1361 case XML_SCHEMA_TYPE_IDC_KEY
:
1362 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
1363 case XML_SCHEMA_TYPE_IDC_KEYREF
:
1364 return (((xmlSchemaIDCPtr
) item
)->name
);
1365 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
1366 if (WXS_ATTRUSE_DECL(item
) != NULL
) {
1367 return(xmlSchemaGetComponentName(
1368 WXS_BASIC_CAST
WXS_ATTRUSE_DECL(item
)));
1371 case XML_SCHEMA_EXTRA_QNAMEREF
:
1372 return (((xmlSchemaQNameRefPtr
) item
)->name
);
1373 case XML_SCHEMA_TYPE_NOTATION
:
1374 return (((xmlSchemaNotationPtr
) item
)->name
);
1377 * Other components cannot have names.
1384 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1385 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1387 static const xmlChar *
1388 xmlSchemaGetQNameRefName(void *ref)
1390 return(((xmlSchemaQNameRefPtr) ref)->name);
1393 static const xmlChar *
1394 xmlSchemaGetQNameRefTargetNs(void *ref)
1396 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1400 static const xmlChar
*
1401 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item
)
1406 switch (item
->type
) {
1407 case XML_SCHEMA_TYPE_ELEMENT
:
1408 return (((xmlSchemaElementPtr
) item
)->targetNamespace
);
1409 case XML_SCHEMA_TYPE_ATTRIBUTE
:
1410 return (((xmlSchemaAttributePtr
) item
)->targetNamespace
);
1411 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
1412 return (((xmlSchemaAttributeGroupPtr
) item
)->targetNamespace
);
1413 case XML_SCHEMA_TYPE_BASIC
:
1414 return (BAD_CAST
"http://www.w3.org/2001/XMLSchema");
1415 case XML_SCHEMA_TYPE_SIMPLE
:
1416 case XML_SCHEMA_TYPE_COMPLEX
:
1417 return (((xmlSchemaTypePtr
) item
)->targetNamespace
);
1418 case XML_SCHEMA_TYPE_GROUP
:
1419 return (((xmlSchemaModelGroupDefPtr
) item
)->targetNamespace
);
1420 case XML_SCHEMA_TYPE_IDC_KEY
:
1421 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
1422 case XML_SCHEMA_TYPE_IDC_KEYREF
:
1423 return (((xmlSchemaIDCPtr
) item
)->targetNamespace
);
1424 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
1425 if (WXS_ATTRUSE_DECL(item
) != NULL
) {
1426 return(xmlSchemaGetComponentTargetNs(
1427 WXS_BASIC_CAST
WXS_ATTRUSE_DECL(item
)));
1429 /* TODO: Will returning NULL break something? */
1431 case XML_SCHEMA_EXTRA_QNAMEREF
:
1432 return (((xmlSchemaQNameRefPtr
) item
)->targetNamespace
);
1433 case XML_SCHEMA_TYPE_NOTATION
:
1434 return (((xmlSchemaNotationPtr
) item
)->targetNamespace
);
1437 * Other components cannot have names.
1444 static const xmlChar
*
1445 xmlSchemaGetComponentQName(xmlChar
**buf
,
1448 return (xmlSchemaFormatQName(buf
,
1449 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr
) item
),
1450 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr
) item
)));
1453 static const xmlChar
*
1454 xmlSchemaGetComponentDesignation(xmlChar
**buf
, void *item
)
1456 xmlChar
*str
= NULL
;
1458 *buf
= xmlStrcat(*buf
, WXS_ITEM_TYPE_NAME(item
));
1459 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1460 *buf
= xmlStrcat(*buf
, xmlSchemaGetComponentQName(&str
,
1461 (xmlSchemaBasicItemPtr
) item
));
1462 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1467 static const xmlChar
*
1468 xmlSchemaGetIDCDesignation(xmlChar
**buf
, xmlSchemaIDCPtr idc
)
1470 return(xmlSchemaGetComponentDesignation(buf
, idc
));
1474 * xmlSchemaWildcardPCToString:
1475 * @pc: the type of processContents
1477 * Returns a string representation of the type of
1480 static const xmlChar
*
1481 xmlSchemaWildcardPCToString(int pc
)
1484 case XML_SCHEMAS_ANY_SKIP
:
1485 return (BAD_CAST
"skip");
1486 case XML_SCHEMAS_ANY_LAX
:
1487 return (BAD_CAST
"lax");
1488 case XML_SCHEMAS_ANY_STRICT
:
1489 return (BAD_CAST
"strict");
1491 return (BAD_CAST
"invalid process contents");
1496 * xmlSchemaGetCanonValueWhtspExt:
1497 * @val: the precomputed value
1498 * @retValue: the returned value
1499 * @ws: the whitespace type of the value
1500 * @for_hash: non-zero if this is supposed to generate a string for hashing
1502 * Get a the canonical representation of the value.
1503 * The caller has to free the returned retValue.
1505 * Returns 0 if the value could be built and -1 in case of
1506 * API errors or if the value type is not supported yet.
1509 xmlSchemaGetCanonValueWhtspExt_1(xmlSchemaValPtr val
,
1510 xmlSchemaWhitespaceValueType ws
,
1515 xmlSchemaValType valType
;
1516 const xmlChar
*value
, *value2
= NULL
;
1519 if ((retValue
== NULL
) || (val
== NULL
))
1521 list
= xmlSchemaValueGetNext(val
) ? 1 : 0;
1525 valType
= xmlSchemaGetValType(val
);
1527 case XML_SCHEMAS_STRING
:
1528 case XML_SCHEMAS_NORMSTRING
:
1529 case XML_SCHEMAS_ANYSIMPLETYPE
:
1530 value
= xmlSchemaValueGetAsString(val
);
1531 if (value
!= NULL
) {
1532 if (ws
== XML_SCHEMA_WHITESPACE_COLLAPSE
)
1533 value2
= xmlSchemaCollapseString(value
);
1534 else if (ws
== XML_SCHEMA_WHITESPACE_REPLACE
)
1535 value2
= xmlSchemaWhiteSpaceReplace(value
);
1541 if (xmlSchemaGetCanonValue(val
, &value2
) == -1) {
1543 xmlFree((xmlChar
*) value2
);
1544 goto internal_error
;
1546 if (for_hash
&& valType
== XML_SCHEMAS_DECIMAL
) {
1547 /* We can mostly use the canonical value for hashing,
1548 except in the case of decimal. There the canonical
1549 representation requires a trailing '.0' even for
1550 non-fractional numbers, but for the derived integer
1551 types it forbids any decimal point. Nevertheless they
1552 compare equal if the value is equal. We need to generate
1553 the same hash value for this to work, and it's easiest
1554 to just cut off the useless '.0' suffix for the
1556 int len
= xmlStrlen(value2
);
1557 if (len
> 2 && value2
[len
-1] == '0' && value2
[len
-2] == '.')
1558 ((xmlChar
*)value2
)[len
-2] = 0;
1562 if (*retValue
== NULL
)
1563 if (value
== NULL
) {
1565 *retValue
= xmlStrdup(BAD_CAST
"");
1567 *retValue
= xmlStrdup(value
);
1568 else if (value
!= NULL
) {
1570 *retValue
= xmlStrcat((xmlChar
*) *retValue
, BAD_CAST
" ");
1571 *retValue
= xmlStrcat((xmlChar
*) *retValue
, value
);
1573 FREE_AND_NULL(value2
)
1574 val
= xmlSchemaValueGetNext(val
);
1575 } while (val
!= NULL
);
1579 if (*retValue
!= NULL
)
1580 xmlFree((xmlChar
*) (*retValue
));
1582 xmlFree((xmlChar
*) value2
);
1587 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val
,
1588 xmlSchemaWhitespaceValueType ws
,
1591 return xmlSchemaGetCanonValueWhtspExt_1(val
, ws
, retValue
, 0);
1595 xmlSchemaGetCanonValueHash(xmlSchemaValPtr val
,
1598 return xmlSchemaGetCanonValueWhtspExt_1(val
, XML_SCHEMA_WHITESPACE_COLLAPSE
,
1603 * xmlSchemaFormatItemForReport:
1604 * @buf: the string buffer
1605 * @itemDes: the designation of the item
1606 * @itemName: the name of the item
1607 * @item: the item as an object
1608 * @itemNode: the node of the item
1609 * @local: the local name
1610 * @parsing: if the function is used during the parse
1612 * Returns a representation of the given item used
1613 * for error reports.
1615 * The following order is used to build the resulting
1616 * designation if the arguments are not NULL:
1617 * 1a. If itemDes not NULL -> itemDes
1618 * 1b. If (itemDes not NULL) and (itemName not NULL)
1619 * -> itemDes + itemName
1620 * 2. If the preceding was NULL and (item not NULL) -> item
1621 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
1623 * If the itemNode is an attribute node, the name of the attribute
1624 * will be appended to the result.
1626 * Returns the formatted string and sets @buf to the resulting value.
1629 xmlSchemaFormatItemForReport(xmlChar
**buf
,
1630 const xmlChar
*itemDes
,
1631 xmlSchemaBasicItemPtr item
,
1632 xmlNodePtr itemNode
)
1634 xmlChar
*str
= NULL
;
1642 if (itemDes
!= NULL
) {
1643 *buf
= xmlStrdup(itemDes
);
1644 } else if (item
!= NULL
) {
1645 switch (item
->type
) {
1646 case XML_SCHEMA_TYPE_BASIC
: {
1647 xmlSchemaTypePtr type
= WXS_TYPE_CAST item
;
1649 if (WXS_IS_ATOMIC(type
))
1650 *buf
= xmlStrdup(BAD_CAST
"atomic type 'xs:");
1651 else if (WXS_IS_LIST(type
))
1652 *buf
= xmlStrdup(BAD_CAST
"list type 'xs:");
1653 else if (WXS_IS_UNION(type
))
1654 *buf
= xmlStrdup(BAD_CAST
"union type 'xs:");
1656 *buf
= xmlStrdup(BAD_CAST
"simple type 'xs:");
1657 *buf
= xmlStrcat(*buf
, type
->name
);
1658 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1661 case XML_SCHEMA_TYPE_SIMPLE
: {
1662 xmlSchemaTypePtr type
= WXS_TYPE_CAST item
;
1664 if (type
->flags
& XML_SCHEMAS_TYPE_GLOBAL
) {
1665 *buf
= xmlStrdup(BAD_CAST
"");
1667 *buf
= xmlStrdup(BAD_CAST
"local ");
1669 if (WXS_IS_ATOMIC(type
))
1670 *buf
= xmlStrcat(*buf
, BAD_CAST
"atomic type");
1671 else if (WXS_IS_LIST(type
))
1672 *buf
= xmlStrcat(*buf
, BAD_CAST
"list type");
1673 else if (WXS_IS_UNION(type
))
1674 *buf
= xmlStrcat(*buf
, BAD_CAST
"union type");
1676 *buf
= xmlStrcat(*buf
, BAD_CAST
"simple type");
1677 if (type
->flags
& XML_SCHEMAS_TYPE_GLOBAL
) {
1678 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1679 *buf
= xmlStrcat(*buf
, type
->name
);
1680 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1684 case XML_SCHEMA_TYPE_COMPLEX
: {
1685 xmlSchemaTypePtr type
= WXS_TYPE_CAST item
;
1687 if (type
->flags
& XML_SCHEMAS_TYPE_GLOBAL
)
1688 *buf
= xmlStrdup(BAD_CAST
"");
1690 *buf
= xmlStrdup(BAD_CAST
"local ");
1691 *buf
= xmlStrcat(*buf
, BAD_CAST
"complex type");
1692 if (type
->flags
& XML_SCHEMAS_TYPE_GLOBAL
) {
1693 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1694 *buf
= xmlStrcat(*buf
, type
->name
);
1695 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1699 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
: {
1700 xmlSchemaAttributeUsePtr ause
;
1702 ause
= WXS_ATTR_USE_CAST item
;
1703 *buf
= xmlStrdup(BAD_CAST
"attribute use ");
1704 if (WXS_ATTRUSE_DECL(ause
) != NULL
) {
1705 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1706 *buf
= xmlStrcat(*buf
,
1707 xmlSchemaGetComponentQName(&str
, WXS_ATTRUSE_DECL(ause
)));
1709 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1711 *buf
= xmlStrcat(*buf
, BAD_CAST
"(unknown)");
1715 case XML_SCHEMA_TYPE_ATTRIBUTE
: {
1716 xmlSchemaAttributePtr attr
;
1718 attr
= (xmlSchemaAttributePtr
) item
;
1719 *buf
= xmlStrdup(BAD_CAST
"attribute decl.");
1720 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1721 *buf
= xmlStrcat(*buf
, xmlSchemaFormatQName(&str
,
1722 attr
->targetNamespace
, attr
->name
));
1724 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1727 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
1728 xmlSchemaGetComponentDesignation(buf
, item
);
1730 case XML_SCHEMA_TYPE_ELEMENT
: {
1731 xmlSchemaElementPtr elem
;
1733 elem
= (xmlSchemaElementPtr
) item
;
1734 *buf
= xmlStrdup(BAD_CAST
"element decl.");
1735 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1736 *buf
= xmlStrcat(*buf
, xmlSchemaFormatQName(&str
,
1737 elem
->targetNamespace
, elem
->name
));
1738 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1741 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
1742 case XML_SCHEMA_TYPE_IDC_KEY
:
1743 case XML_SCHEMA_TYPE_IDC_KEYREF
:
1744 if (item
->type
== XML_SCHEMA_TYPE_IDC_UNIQUE
)
1745 *buf
= xmlStrdup(BAD_CAST
"unique '");
1746 else if (item
->type
== XML_SCHEMA_TYPE_IDC_KEY
)
1747 *buf
= xmlStrdup(BAD_CAST
"key '");
1749 *buf
= xmlStrdup(BAD_CAST
"keyRef '");
1750 *buf
= xmlStrcat(*buf
, ((xmlSchemaIDCPtr
) item
)->name
);
1751 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1753 case XML_SCHEMA_TYPE_ANY
:
1754 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE
:
1755 *buf
= xmlStrdup(xmlSchemaWildcardPCToString(
1756 ((xmlSchemaWildcardPtr
) item
)->processContents
));
1757 *buf
= xmlStrcat(*buf
, BAD_CAST
" wildcard");
1759 case XML_SCHEMA_FACET_MININCLUSIVE
:
1760 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
1761 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
1762 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
1763 case XML_SCHEMA_FACET_TOTALDIGITS
:
1764 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
1765 case XML_SCHEMA_FACET_PATTERN
:
1766 case XML_SCHEMA_FACET_ENUMERATION
:
1767 case XML_SCHEMA_FACET_WHITESPACE
:
1768 case XML_SCHEMA_FACET_LENGTH
:
1769 case XML_SCHEMA_FACET_MAXLENGTH
:
1770 case XML_SCHEMA_FACET_MINLENGTH
:
1771 *buf
= xmlStrdup(BAD_CAST
"facet '");
1772 *buf
= xmlStrcat(*buf
, xmlSchemaFacetTypeToString(item
->type
));
1773 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1775 case XML_SCHEMA_TYPE_GROUP
: {
1776 *buf
= xmlStrdup(BAD_CAST
"model group def.");
1777 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1778 *buf
= xmlStrcat(*buf
, xmlSchemaGetComponentQName(&str
, item
));
1779 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1783 case XML_SCHEMA_TYPE_SEQUENCE
:
1784 case XML_SCHEMA_TYPE_CHOICE
:
1785 case XML_SCHEMA_TYPE_ALL
:
1786 case XML_SCHEMA_TYPE_PARTICLE
:
1787 *buf
= xmlStrdup(WXS_ITEM_TYPE_NAME(item
));
1789 case XML_SCHEMA_TYPE_NOTATION
: {
1790 *buf
= xmlStrdup(WXS_ITEM_TYPE_NAME(item
));
1791 *buf
= xmlStrcat(*buf
, BAD_CAST
" '");
1792 *buf
= xmlStrcat(*buf
, xmlSchemaGetComponentQName(&str
, item
));
1793 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1796 /* Falls through. */
1803 if ((named
== 0) && (itemNode
!= NULL
)) {
1806 if (itemNode
->type
== XML_ATTRIBUTE_NODE
)
1807 elem
= itemNode
->parent
;
1810 *buf
= xmlStrdup(BAD_CAST
"Element '");
1811 if (elem
->ns
!= NULL
) {
1812 *buf
= xmlStrcat(*buf
,
1813 xmlSchemaFormatQName(&str
, elem
->ns
->href
, elem
->name
));
1816 *buf
= xmlStrcat(*buf
, elem
->name
);
1817 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1820 if ((itemNode
!= NULL
) && (itemNode
->type
== XML_ATTRIBUTE_NODE
)) {
1821 *buf
= xmlStrcat(*buf
, BAD_CAST
", attribute '");
1822 if (itemNode
->ns
!= NULL
) {
1823 *buf
= xmlStrcat(*buf
, xmlSchemaFormatQName(&str
,
1824 itemNode
->ns
->href
, itemNode
->name
));
1827 *buf
= xmlStrcat(*buf
, itemNode
->name
);
1828 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1832 return (xmlEscapeFormatString(buf
));
1836 * xmlSchemaFormatFacetEnumSet:
1837 * @buf: the string buffer
1838 * @type: the type holding the enumeration facets
1840 * Builds a string consisting of all enumeration elements.
1842 * Returns a string of all enumeration elements.
1844 static const xmlChar
*
1845 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt
,
1846 xmlChar
**buf
, xmlSchemaTypePtr type
)
1848 xmlSchemaFacetPtr facet
;
1849 xmlSchemaWhitespaceValueType ws
;
1850 xmlChar
*value
= NULL
;
1859 * Use the whitespace type of the base type.
1861 ws
= xmlSchemaGetWhiteSpaceFacetValue(type
->baseType
);
1862 for (facet
= type
->facets
; facet
!= NULL
; facet
= facet
->next
) {
1863 if (facet
->type
!= XML_SCHEMA_FACET_ENUMERATION
)
1866 res
= xmlSchemaGetCanonValueWhtspExt(facet
->val
,
1869 xmlSchemaInternalErr(actxt
,
1870 "xmlSchemaFormatFacetEnumSet",
1871 "compute the canonical lexical representation");
1878 *buf
= xmlStrdup(BAD_CAST
"'");
1880 *buf
= xmlStrcat(*buf
, BAD_CAST
", '");
1881 *buf
= xmlStrcat(*buf
, BAD_CAST value
);
1882 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
1883 if (value
!= NULL
) {
1884 xmlFree((xmlChar
*)value
);
1889 * The enumeration facet of a type restricts the enumeration
1890 * facet of the ancestor type; i.e., such restricted enumerations
1891 * do not belong to the set of the given type. Thus we break
1892 * on the first found enumeration.
1896 type
= type
->baseType
;
1897 } while ((type
!= NULL
) && (type
->type
!= XML_SCHEMA_TYPE_BASIC
));
1899 return ((const xmlChar
*) *buf
);
1902 /************************************************************************
1906 ************************************************************************/
1910 xmlSchemaErrMemory(const char *msg
)
1912 __xmlSimpleError(XML_FROM_SCHEMASP
, XML_ERR_NO_MEMORY
, NULL
, NULL
,
1918 xmlSchemaPSimpleErr(const char *msg
)
1920 __xmlSimpleError(XML_FROM_SCHEMASP
, XML_ERR_NO_MEMORY
, NULL
, NULL
,
1925 * xmlSchemaPErrMemory:
1926 * @node: a context node
1927 * @extra: extra information
1929 * Handle an out of memory condition
1932 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt
,
1933 const char *extra
, xmlNodePtr node
)
1937 __xmlSimpleError(XML_FROM_SCHEMASP
, XML_ERR_NO_MEMORY
, node
, NULL
,
1943 * @ctxt: the parsing context
1944 * @node: the context node
1945 * @error: the error code
1946 * @msg: the error message
1950 * Handle a parser error
1952 static void LIBXML_ATTR_FORMAT(4,0)
1953 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
, int error
,
1954 const char *msg
, const xmlChar
* str1
, const xmlChar
* str2
)
1956 xmlGenericErrorFunc channel
= NULL
;
1957 xmlStructuredErrorFunc schannel
= NULL
;
1963 channel
= ctxt
->error
;
1964 data
= ctxt
->errCtxt
;
1965 schannel
= ctxt
->serror
;
1967 __xmlRaiseError(schannel
, channel
, data
, ctxt
, node
, XML_FROM_SCHEMASP
,
1968 error
, XML_ERR_ERROR
, NULL
, 0,
1969 (const char *) str1
, (const char *) str2
, NULL
, 0, 0,
1975 * @ctxt: the parsing context
1976 * @node: the context node
1977 * @node: the current child
1978 * @error: the error code
1979 * @msg: the error message
1983 * Handle a parser error
1985 static void LIBXML_ATTR_FORMAT(5,0)
1986 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
,
1987 xmlNodePtr child
, int error
,
1988 const char *msg
, const xmlChar
* str1
, const xmlChar
* str2
)
1991 xmlSchemaPErr(ctxt
, child
, error
, msg
, str1
, str2
);
1993 xmlSchemaPErr(ctxt
, node
, error
, msg
, str1
, str2
);
1999 * @ctxt: the parsing context
2000 * @node: the context node
2001 * @error: the error code
2002 * @strData1: extra data
2003 * @strData2: extra data
2004 * @strData3: extra data
2006 * @str1: extra parameter for the message display
2007 * @str2: extra parameter for the message display
2008 * @str3: extra parameter for the message display
2009 * @str4: extra parameter for the message display
2010 * @str5: extra parameter for the message display
2012 * Handle a parser error
2014 static void LIBXML_ATTR_FORMAT(7,0)
2015 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
, int error
,
2016 const xmlChar
* strData1
, const xmlChar
* strData2
,
2017 const xmlChar
* strData3
, const char *msg
, const xmlChar
* str1
,
2018 const xmlChar
* str2
, const xmlChar
* str3
, const xmlChar
* str4
,
2019 const xmlChar
* str5
)
2022 xmlGenericErrorFunc channel
= NULL
;
2023 xmlStructuredErrorFunc schannel
= NULL
;
2029 channel
= ctxt
->error
;
2030 data
= ctxt
->errCtxt
;
2031 schannel
= ctxt
->serror
;
2033 __xmlRaiseError(schannel
, channel
, data
, ctxt
, node
, XML_FROM_SCHEMASP
,
2034 error
, XML_ERR_ERROR
, NULL
, 0,
2035 (const char *) strData1
, (const char *) strData2
,
2036 (const char *) strData3
, 0, 0, msg
, str1
, str2
,
2040 /************************************************************************
2042 * Allround error functions *
2044 ************************************************************************/
2047 * xmlSchemaVTypeErrMemory:
2048 * @node: a context node
2049 * @extra: extra information
2051 * Handle an out of memory condition
2054 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt
,
2055 const char *extra
, xmlNodePtr node
)
2059 ctxt
->err
= XML_SCHEMAV_INTERNAL
;
2061 __xmlSimpleError(XML_FROM_SCHEMASV
, XML_ERR_NO_MEMORY
, node
, NULL
,
2065 static void LIBXML_ATTR_FORMAT(2,0)
2066 xmlSchemaPSimpleInternalErr(xmlNodePtr node
,
2067 const char *msg
, const xmlChar
*str
)
2069 __xmlSimpleError(XML_FROM_SCHEMASP
, XML_SCHEMAP_INTERNAL
, node
,
2070 msg
, (const char *) str
);
2073 #define WXS_ERROR_TYPE_ERROR 1
2074 #define WXS_ERROR_TYPE_WARNING 2
2076 * xmlSchemaErr4Line:
2077 * @ctxt: the validation context
2078 * @errorLevel: the error level
2079 * @error: the error code
2080 * @node: the context node
2081 * @line: the line number
2082 * @msg: the error message
2088 * Handle a validation error
2090 static void LIBXML_ATTR_FORMAT(6,0)
2091 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt
,
2092 xmlErrorLevel errorLevel
,
2093 int error
, xmlNodePtr node
, int line
, const char *msg
,
2094 const xmlChar
*str1
, const xmlChar
*str2
,
2095 const xmlChar
*str3
, const xmlChar
*str4
)
2097 xmlStructuredErrorFunc schannel
= NULL
;
2098 xmlGenericErrorFunc channel
= NULL
;
2102 if (ctxt
->type
== XML_SCHEMA_CTXT_VALIDATOR
) {
2103 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) ctxt
;
2104 const char *file
= NULL
;
2106 if (errorLevel
!= XML_ERR_WARNING
) {
2109 channel
= vctxt
->error
;
2111 channel
= vctxt
->warning
;
2113 schannel
= vctxt
->serror
;
2114 data
= vctxt
->errCtxt
;
2117 * Error node. If we specify a line number, then
2118 * do not channel any node to the error function.
2121 if ((node
== NULL
) &&
2122 (vctxt
->depth
>= 0) &&
2123 (vctxt
->inode
!= NULL
)) {
2124 node
= vctxt
->inode
->node
;
2127 * Get filename and line if no node-tree.
2129 if ((node
== NULL
) &&
2130 (vctxt
->parserCtxt
!= NULL
) &&
2131 (vctxt
->parserCtxt
->input
!= NULL
)) {
2132 file
= vctxt
->parserCtxt
->input
->filename
;
2133 line
= vctxt
->parserCtxt
->input
->line
;
2134 col
= vctxt
->parserCtxt
->input
->col
;
2138 * Override the given node's (if any) position
2139 * and channel only the given line number.
2145 if (vctxt
->doc
!= NULL
)
2146 file
= (const char *) vctxt
->doc
->URL
;
2147 else if ((vctxt
->parserCtxt
!= NULL
) &&
2148 (vctxt
->parserCtxt
->input
!= NULL
))
2149 file
= vctxt
->parserCtxt
->input
->filename
;
2151 if (vctxt
->locFunc
!= NULL
) {
2152 if ((file
== NULL
) || (line
== 0)) {
2155 vctxt
->locFunc(vctxt
->locCtxt
, &f
, &l
);
2162 if ((file
== NULL
) && (vctxt
->filename
!= NULL
))
2163 file
= vctxt
->filename
;
2165 __xmlRaiseError(schannel
, channel
, data
, ctxt
,
2166 node
, XML_FROM_SCHEMASV
,
2167 error
, errorLevel
, file
, line
,
2168 (const char *) str1
, (const char *) str2
,
2169 (const char *) str3
, 0, col
, msg
, str1
, str2
, str3
, str4
);
2171 } else if (ctxt
->type
== XML_SCHEMA_CTXT_PARSER
) {
2172 xmlSchemaParserCtxtPtr pctxt
= (xmlSchemaParserCtxtPtr
) ctxt
;
2173 if (errorLevel
!= XML_ERR_WARNING
) {
2176 channel
= pctxt
->error
;
2178 channel
= pctxt
->warning
;
2180 schannel
= pctxt
->serror
;
2181 data
= pctxt
->errCtxt
;
2182 __xmlRaiseError(schannel
, channel
, data
, ctxt
,
2183 node
, XML_FROM_SCHEMASP
, error
,
2184 errorLevel
, NULL
, 0,
2185 (const char *) str1
, (const char *) str2
,
2186 (const char *) str3
, 0, 0, msg
, str1
, str2
, str3
, str4
);
2195 * @ctxt: the validation context
2196 * @node: the context node
2197 * @error: the error code
2198 * @msg: the error message
2203 * Handle a validation error
2205 static void LIBXML_ATTR_FORMAT(4,0)
2206 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt
,
2207 int error
, xmlNodePtr node
, const char *msg
,
2208 const xmlChar
*str1
, const xmlChar
*str2
, const xmlChar
*str3
)
2210 xmlSchemaErr4Line(actxt
, XML_ERR_ERROR
, error
, node
, 0,
2211 msg
, str1
, str2
, str3
, NULL
);
2214 static void LIBXML_ATTR_FORMAT(4,0)
2215 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt
,
2216 int error
, xmlNodePtr node
, const char *msg
,
2217 const xmlChar
*str1
, const xmlChar
*str2
,
2218 const xmlChar
*str3
, const xmlChar
*str4
)
2220 xmlSchemaErr4Line(actxt
, XML_ERR_ERROR
, error
, node
, 0,
2221 msg
, str1
, str2
, str3
, str4
);
2224 static void LIBXML_ATTR_FORMAT(4,0)
2225 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt
,
2226 int error
, xmlNodePtr node
, const char *msg
,
2227 const xmlChar
*str1
, const xmlChar
*str2
)
2229 xmlSchemaErr4(actxt
, error
, node
, msg
, str1
, str2
, NULL
, NULL
);
2233 xmlSchemaFormatNodeForError(xmlChar
** msg
,
2234 xmlSchemaAbstractCtxtPtr actxt
,
2237 xmlChar
*str
= NULL
;
2240 if ((node
!= NULL
) &&
2241 (node
->type
!= XML_ELEMENT_NODE
) &&
2242 (node
->type
!= XML_ATTRIBUTE_NODE
))
2245 * Don't try to format other nodes than element and
2247 * Play safe and return an empty string.
2249 *msg
= xmlStrdup(BAD_CAST
"");
2254 * Work on tree nodes.
2256 if (node
->type
== XML_ATTRIBUTE_NODE
) {
2257 xmlNodePtr elem
= node
->parent
;
2259 *msg
= xmlStrdup(BAD_CAST
"Element '");
2260 if (elem
->ns
!= NULL
)
2261 *msg
= xmlStrcat(*msg
, xmlSchemaFormatQName(&str
,
2262 elem
->ns
->href
, elem
->name
));
2264 *msg
= xmlStrcat(*msg
, xmlSchemaFormatQName(&str
,
2267 *msg
= xmlStrcat(*msg
, BAD_CAST
"', ");
2268 *msg
= xmlStrcat(*msg
, BAD_CAST
"attribute '");
2270 *msg
= xmlStrdup(BAD_CAST
"Element '");
2272 if (node
->ns
!= NULL
)
2273 *msg
= xmlStrcat(*msg
, xmlSchemaFormatQName(&str
,
2274 node
->ns
->href
, node
->name
));
2276 *msg
= xmlStrcat(*msg
, xmlSchemaFormatQName(&str
,
2279 *msg
= xmlStrcat(*msg
, BAD_CAST
"': ");
2280 } else if (actxt
->type
== XML_SCHEMA_CTXT_VALIDATOR
) {
2281 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) actxt
;
2283 * Work on node infos.
2285 if (vctxt
->inode
->nodeType
== XML_ATTRIBUTE_NODE
) {
2286 xmlSchemaNodeInfoPtr ielem
=
2287 vctxt
->elemInfos
[vctxt
->depth
];
2289 *msg
= xmlStrdup(BAD_CAST
"Element '");
2290 *msg
= xmlStrcat(*msg
, xmlSchemaFormatQName(&str
,
2291 ielem
->nsName
, ielem
->localName
));
2293 *msg
= xmlStrcat(*msg
, BAD_CAST
"', ");
2294 *msg
= xmlStrcat(*msg
, BAD_CAST
"attribute '");
2296 *msg
= xmlStrdup(BAD_CAST
"Element '");
2298 *msg
= xmlStrcat(*msg
, xmlSchemaFormatQName(&str
,
2299 vctxt
->inode
->nsName
, vctxt
->inode
->localName
));
2301 *msg
= xmlStrcat(*msg
, BAD_CAST
"': ");
2302 } else if (actxt
->type
== XML_SCHEMA_CTXT_PARSER
) {
2304 * Hmm, no node while parsing?
2305 * Return an empty string, in case NULL will break something.
2307 *msg
= xmlStrdup(BAD_CAST
"");
2314 * xmlSchemaFormatItemForReport() also returns an escaped format
2315 * string, so do this before calling it below (in the future).
2317 xmlEscapeFormatString(msg
);
2320 * VAL TODO: The output of the given schema component is currently
2324 if ((type
!= NULL
) && (xmlSchemaIsGlobalItem(type
))) {
2325 *msg
= xmlStrcat(*msg
, BAD_CAST
" [");
2326 *msg
= xmlStrcat(*msg
, xmlSchemaFormatItemForReport(&str
,
2327 NULL
, type
, NULL
, 0));
2329 *msg
= xmlStrcat(*msg
, BAD_CAST
"]");
2335 static void LIBXML_ATTR_FORMAT(3,0)
2336 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt
,
2337 const char *funcName
,
2338 const char *message
,
2339 const xmlChar
*str1
,
2340 const xmlChar
*str2
)
2342 xmlChar
*msg
= NULL
;
2346 msg
= xmlStrdup(BAD_CAST
"Internal error: %s, ");
2347 msg
= xmlStrcat(msg
, BAD_CAST message
);
2348 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
2350 if (actxt
->type
== XML_SCHEMA_CTXT_VALIDATOR
)
2351 xmlSchemaErr3(actxt
, XML_SCHEMAV_INTERNAL
, NULL
,
2352 (const char *) msg
, (const xmlChar
*) funcName
, str1
, str2
);
2353 else if (actxt
->type
== XML_SCHEMA_CTXT_PARSER
)
2354 xmlSchemaErr3(actxt
, XML_SCHEMAP_INTERNAL
, NULL
,
2355 (const char *) msg
, (const xmlChar
*) funcName
, str1
, str2
);
2360 static void LIBXML_ATTR_FORMAT(3,0)
2361 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt
,
2362 const char *funcName
,
2363 const char *message
)
2365 xmlSchemaInternalErr2(actxt
, funcName
, message
, NULL
, NULL
);
2369 static void LIBXML_ATTR_FORMAT(3,0)
2370 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt
,
2371 const char *funcName
,
2372 const char *message
,
2373 const xmlChar
*str1
,
2374 const xmlChar
*str2
)
2376 xmlSchemaInternalErr2(ACTXT_CAST pctxt
, funcName
, message
,
2381 static void LIBXML_ATTR_FORMAT(5,0)
2382 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt
,
2383 xmlParserErrors error
,
2385 xmlSchemaBasicItemPtr item
,
2386 const char *message
,
2387 const xmlChar
*str1
, const xmlChar
*str2
,
2388 const xmlChar
*str3
, const xmlChar
*str4
)
2390 xmlChar
*msg
= NULL
;
2392 if ((node
== NULL
) && (item
!= NULL
) &&
2393 (actxt
->type
== XML_SCHEMA_CTXT_PARSER
)) {
2394 node
= WXS_ITEM_NODE(item
);
2395 xmlSchemaFormatItemForReport(&msg
, NULL
, item
, NULL
);
2396 msg
= xmlStrcat(msg
, BAD_CAST
": ");
2398 xmlSchemaFormatNodeForError(&msg
, actxt
, node
);
2399 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
2400 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
2401 xmlSchemaErr4(actxt
, error
, node
,
2402 (const char *) msg
, str1
, str2
, str3
, str4
);
2406 static void LIBXML_ATTR_FORMAT(5,0)
2407 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt
,
2408 xmlParserErrors error
,
2410 xmlSchemaBasicItemPtr item
,
2411 const char *message
,
2412 const xmlChar
*str1
,
2413 const xmlChar
*str2
)
2415 xmlSchemaCustomErr4(actxt
, error
, node
, item
,
2416 message
, str1
, str2
, NULL
, NULL
);
2421 static void LIBXML_ATTR_FORMAT(5,0)
2422 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt
,
2423 xmlParserErrors error
,
2425 xmlSchemaTypePtr type ATTRIBUTE_UNUSED
,
2426 const char *message
,
2427 const xmlChar
*str1
,
2428 const xmlChar
*str2
,
2429 const xmlChar
*str3
)
2431 xmlChar
*msg
= NULL
;
2433 xmlSchemaFormatNodeForError(&msg
, actxt
, node
);
2434 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
2435 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
2437 /* URGENT TODO: Set the error code to something sane. */
2438 xmlSchemaErr4Line(actxt
, XML_ERR_WARNING
, error
, node
, 0,
2439 (const char *) msg
, str1
, str2
, str3
, NULL
);
2446 static void LIBXML_ATTR_FORMAT(5,0)
2447 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt
,
2448 xmlParserErrors error
,
2449 xmlSchemaPSVIIDCNodePtr idcNode
,
2450 xmlSchemaTypePtr type ATTRIBUTE_UNUSED
,
2451 const char *message
,
2452 const xmlChar
*str1
,
2453 const xmlChar
*str2
)
2455 xmlChar
*msg
= NULL
, *qname
= NULL
;
2457 msg
= xmlStrdup(BAD_CAST
"Element '%s': ");
2458 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
2459 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
2460 xmlSchemaErr4Line(ACTXT_CAST vctxt
, XML_ERR_ERROR
,
2461 error
, NULL
, idcNode
->nodeLine
, (const char *) msg
,
2462 xmlSchemaFormatQName(&qname
,
2463 vctxt
->nodeQNames
->items
[idcNode
->nodeQNameID
+1],
2464 vctxt
->nodeQNames
->items
[idcNode
->nodeQNameID
]),
2466 FREE_AND_NULL(qname
);
2471 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt
,
2475 return (node
->type
);
2476 if ((actxt
->type
== XML_SCHEMA_CTXT_VALIDATOR
) &&
2477 (((xmlSchemaValidCtxtPtr
) actxt
)->inode
!= NULL
))
2478 return ( ((xmlSchemaValidCtxtPtr
) actxt
)->inode
->nodeType
);
2483 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item
)
2485 switch (item
->type
) {
2486 case XML_SCHEMA_TYPE_COMPLEX
:
2487 case XML_SCHEMA_TYPE_SIMPLE
:
2488 if (item
->flags
& XML_SCHEMAS_TYPE_GLOBAL
)
2491 case XML_SCHEMA_TYPE_GROUP
:
2493 case XML_SCHEMA_TYPE_ELEMENT
:
2494 if ( ((xmlSchemaElementPtr
) item
)->flags
&
2495 XML_SCHEMAS_ELEM_GLOBAL
)
2498 case XML_SCHEMA_TYPE_ATTRIBUTE
:
2499 if ( ((xmlSchemaAttributePtr
) item
)->flags
&
2500 XML_SCHEMAS_ATTR_GLOBAL
)
2503 /* Note that attribute groups are always global. */
2511 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt
,
2512 xmlParserErrors error
,
2514 const xmlChar
*value
,
2515 xmlSchemaTypePtr type
,
2518 xmlChar
*msg
= NULL
;
2520 xmlSchemaFormatNodeForError(&msg
, actxt
, node
);
2522 if (displayValue
|| (xmlSchemaEvalErrorNodeType(actxt
, node
) ==
2523 XML_ATTRIBUTE_NODE
))
2524 msg
= xmlStrcat(msg
, BAD_CAST
"'%s' is not a valid value of ");
2526 msg
= xmlStrcat(msg
, BAD_CAST
"The character content is not a valid "
2529 if (! xmlSchemaIsGlobalItem(type
))
2530 msg
= xmlStrcat(msg
, BAD_CAST
"the local ");
2532 msg
= xmlStrcat(msg
, BAD_CAST
"the ");
2534 if (WXS_IS_ATOMIC(type
))
2535 msg
= xmlStrcat(msg
, BAD_CAST
"atomic type");
2536 else if (WXS_IS_LIST(type
))
2537 msg
= xmlStrcat(msg
, BAD_CAST
"list type");
2538 else if (WXS_IS_UNION(type
))
2539 msg
= xmlStrcat(msg
, BAD_CAST
"union type");
2541 if (xmlSchemaIsGlobalItem(type
)) {
2542 xmlChar
*str
= NULL
;
2543 msg
= xmlStrcat(msg
, BAD_CAST
" '");
2544 if (type
->builtInType
!= 0) {
2545 msg
= xmlStrcat(msg
, BAD_CAST
"xs:");
2546 str
= xmlStrdup(type
->name
);
2548 const xmlChar
*qName
= xmlSchemaFormatQName(&str
, type
->targetNamespace
, type
->name
);
2550 str
= xmlStrdup(qName
);
2552 msg
= xmlStrcat(msg
, xmlEscapeFormatString(&str
));
2553 msg
= xmlStrcat(msg
, BAD_CAST
"'");
2556 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
2557 if (displayValue
|| (xmlSchemaEvalErrorNodeType(actxt
, node
) ==
2558 XML_ATTRIBUTE_NODE
))
2559 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
, NULL
);
2561 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, NULL
, NULL
);
2565 static const xmlChar
*
2566 xmlSchemaFormatErrorNodeQName(xmlChar
** str
,
2567 xmlSchemaNodeInfoPtr ni
,
2571 if (node
->ns
!= NULL
)
2572 return (xmlSchemaFormatQName(str
, node
->ns
->href
, node
->name
));
2574 return (xmlSchemaFormatQName(str
, NULL
, node
->name
));
2575 } else if (ni
!= NULL
)
2576 return (xmlSchemaFormatQName(str
, ni
->nsName
, ni
->localName
));
2581 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt
,
2582 xmlParserErrors error
,
2583 xmlSchemaAttrInfoPtr ni
,
2586 xmlChar
*msg
= NULL
, *str
= NULL
;
2588 xmlSchemaFormatNodeForError(&msg
, actxt
, node
);
2589 msg
= xmlStrcat(msg
, BAD_CAST
"The attribute '%s' is not allowed.\n");
2590 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
,
2591 xmlSchemaFormatErrorNodeQName(&str
, (xmlSchemaNodeInfoPtr
) ni
, node
),
2597 static void LIBXML_ATTR_FORMAT(5,0)
2598 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt
,
2599 xmlParserErrors error
,
2601 xmlSchemaTypePtr type ATTRIBUTE_UNUSED
,
2602 const char *message
,
2607 xmlChar
*str
= NULL
, *msg
= NULL
;
2608 xmlChar
*localName
, *nsName
;
2609 const xmlChar
*cur
, *end
;
2612 xmlSchemaFormatNodeForError(&msg
, actxt
, node
);
2613 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
2614 msg
= xmlStrcat(msg
, BAD_CAST
".");
2616 * Note that is does not make sense to report that we have a
2617 * wildcard here, since the wildcard might be unfolded into
2618 * multiple transitions.
2620 if (nbval
+ nbneg
> 0) {
2621 if (nbval
+ nbneg
> 1) {
2622 str
= xmlStrdup(BAD_CAST
" Expected is one of ( ");
2624 str
= xmlStrdup(BAD_CAST
" Expected is ( ");
2627 for (i
= 0; i
< nbval
+ nbneg
; i
++) {
2631 if ((cur
[0] == 'n') && (cur
[1] == 'o') && (cur
[2] == 't') &&
2634 str
= xmlStrcat(str
, BAD_CAST
"##other");
2637 * Get the local name.
2643 localName
= xmlStrdup(BAD_CAST
"*");
2646 while ((*end
!= 0) && (*end
!= '|'))
2648 localName
= xmlStrncat(localName
, BAD_CAST cur
, end
- cur
);
2653 * Skip "*|*" if they come with negated expressions, since
2654 * they represent the same negated wildcard.
2656 if ((nbneg
== 0) || (*end
!= '*') || (*localName
!= '*')) {
2658 * Get the namespace name.
2662 nsName
= xmlStrdup(BAD_CAST
"{*}");
2668 nsName
= xmlStrdup(BAD_CAST
"{##other:");
2670 nsName
= xmlStrdup(BAD_CAST
"{");
2672 nsName
= xmlStrncat(nsName
, BAD_CAST cur
, end
- cur
);
2673 nsName
= xmlStrcat(nsName
, BAD_CAST
"}");
2675 str
= xmlStrcat(str
, BAD_CAST nsName
);
2676 FREE_AND_NULL(nsName
)
2678 FREE_AND_NULL(localName
);
2682 str
= xmlStrcat(str
, BAD_CAST localName
);
2683 FREE_AND_NULL(localName
);
2685 if (i
< nbval
+ nbneg
-1)
2686 str
= xmlStrcat(str
, BAD_CAST
", ");
2688 str
= xmlStrcat(str
, BAD_CAST
" ).\n");
2689 msg
= xmlStrcat(msg
, xmlEscapeFormatString(&str
));
2692 msg
= xmlStrcat(msg
, BAD_CAST
"\n");
2693 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, NULL
, NULL
);
2697 static void LIBXML_ATTR_FORMAT(8,0)
2698 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt
,
2699 xmlParserErrors error
,
2701 const xmlChar
*value
,
2702 unsigned long length
,
2703 xmlSchemaTypePtr type
,
2704 xmlSchemaFacetPtr facet
,
2705 const char *message
,
2706 const xmlChar
*str1
,
2707 const xmlChar
*str2
)
2709 xmlChar
*str
= NULL
, *msg
= NULL
;
2710 xmlSchemaTypeType facetType
;
2711 int nodeType
= xmlSchemaEvalErrorNodeType(actxt
, node
);
2713 xmlSchemaFormatNodeForError(&msg
, actxt
, node
);
2714 if (error
== XML_SCHEMAV_CVC_ENUMERATION_VALID
) {
2715 facetType
= XML_SCHEMA_FACET_ENUMERATION
;
2717 * If enumerations are validated, one must not expect the
2718 * facet to be given.
2721 facetType
= facet
->type
;
2722 msg
= xmlStrcat(msg
, BAD_CAST
"[");
2723 msg
= xmlStrcat(msg
, BAD_CAST
"facet '");
2724 msg
= xmlStrcat(msg
, xmlSchemaFacetTypeToString(facetType
));
2725 msg
= xmlStrcat(msg
, BAD_CAST
"'] ");
2726 if (message
== NULL
) {
2728 * Use a default message.
2730 if ((facetType
== XML_SCHEMA_FACET_LENGTH
) ||
2731 (facetType
== XML_SCHEMA_FACET_MINLENGTH
) ||
2732 (facetType
== XML_SCHEMA_FACET_MAXLENGTH
)) {
2734 char len
[25], actLen
[25];
2736 /* FIXME, TODO: What is the max expected string length of the
2739 if (nodeType
== XML_ATTRIBUTE_NODE
)
2740 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' has a length of '%s'; ");
2742 msg
= xmlStrcat(msg
, BAD_CAST
"The value has a length of '%s'; ");
2744 snprintf(len
, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet
));
2745 snprintf(actLen
, 24, "%lu", length
);
2747 if (facetType
== XML_SCHEMA_FACET_LENGTH
)
2748 msg
= xmlStrcat(msg
,
2749 BAD_CAST
"this differs from the allowed length of '%s'.\n");
2750 else if (facetType
== XML_SCHEMA_FACET_MAXLENGTH
)
2751 msg
= xmlStrcat(msg
,
2752 BAD_CAST
"this exceeds the allowed maximum length of '%s'.\n");
2753 else if (facetType
== XML_SCHEMA_FACET_MINLENGTH
)
2754 msg
= xmlStrcat(msg
,
2755 BAD_CAST
"this underruns the allowed minimum length of '%s'.\n");
2757 if (nodeType
== XML_ATTRIBUTE_NODE
)
2758 xmlSchemaErr3(actxt
, error
, node
, (const char *) msg
,
2759 value
, (const xmlChar
*) actLen
, (const xmlChar
*) len
);
2761 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
,
2762 (const xmlChar
*) actLen
, (const xmlChar
*) len
);
2764 } else if (facetType
== XML_SCHEMA_FACET_ENUMERATION
) {
2765 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' is not an element "
2766 "of the set {%s}.\n");
2767 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
,
2768 xmlSchemaFormatFacetEnumSet(actxt
, &str
, type
));
2769 } else if (facetType
== XML_SCHEMA_FACET_PATTERN
) {
2770 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' is not accepted "
2771 "by the pattern '%s'.\n");
2772 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
,
2774 } else if (facetType
== XML_SCHEMA_FACET_MININCLUSIVE
) {
2775 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' is less than the "
2776 "minimum value allowed ('%s').\n");
2777 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
,
2779 } else if (facetType
== XML_SCHEMA_FACET_MAXINCLUSIVE
) {
2780 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' is greater than the "
2781 "maximum value allowed ('%s').\n");
2782 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
,
2784 } else if (facetType
== XML_SCHEMA_FACET_MINEXCLUSIVE
) {
2785 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' must be greater than "
2787 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
,
2789 } else if (facetType
== XML_SCHEMA_FACET_MAXEXCLUSIVE
) {
2790 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' must be less than "
2792 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
,
2794 } else if (facetType
== XML_SCHEMA_FACET_TOTALDIGITS
) {
2795 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' has more "
2796 "digits than are allowed ('%s').\n");
2797 xmlSchemaErr(actxt
, error
, node
, (const char*) msg
, value
,
2799 } else if (facetType
== XML_SCHEMA_FACET_FRACTIONDIGITS
) {
2800 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' has more fractional "
2801 "digits than are allowed ('%s').\n");
2802 xmlSchemaErr(actxt
, error
, node
, (const char*) msg
, value
,
2804 } else if (nodeType
== XML_ATTRIBUTE_NODE
) {
2805 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' is not facet-valid.\n");
2806 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, value
, NULL
);
2808 msg
= xmlStrcat(msg
, BAD_CAST
"The value is not facet-valid.\n");
2809 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, NULL
, NULL
);
2812 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
2813 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
2814 xmlSchemaErr(actxt
, error
, node
, (const char *) msg
, str1
, str2
);
2820 #define VERROR(err, type, msg) \
2821 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2823 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2825 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2826 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2828 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
2832 * xmlSchemaPMissingAttrErr:
2833 * @ctxt: the schema validation context
2834 * @ownerItem: the owner as a schema object
2835 * @ownerElem: the owner as an element node
2836 * @node: the parent element node of the missing attribute node
2837 * @type: the corresponding type of the attribute node
2839 * Reports an illegal attribute.
2842 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt
,
2843 xmlParserErrors error
,
2844 xmlSchemaBasicItemPtr ownerItem
,
2845 xmlNodePtr ownerElem
,
2847 const char *message
)
2849 xmlChar
*des
= NULL
;
2851 xmlSchemaFormatItemForReport(&des
, NULL
, ownerItem
, ownerElem
);
2853 if (message
!= NULL
)
2854 xmlSchemaPErr(ctxt
, ownerElem
, error
, "%s: %s.\n", BAD_CAST des
, BAD_CAST message
);
2856 xmlSchemaPErr(ctxt
, ownerElem
, error
,
2857 "%s: The attribute '%s' is required but missing.\n",
2858 BAD_CAST des
, BAD_CAST name
);
2864 * xmlSchemaPResCompAttrErr:
2865 * @ctxt: the schema validation context
2866 * @error: the error code
2867 * @ownerItem: the owner as a schema object
2868 * @ownerElem: the owner as an element node
2869 * @name: the name of the attribute holding the QName
2870 * @refName: the referenced local name
2871 * @refURI: the referenced namespace URI
2872 * @message: optional message
2874 * Used to report QName attribute values that failed to resolve
2875 * to schema components.
2878 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt
,
2879 xmlParserErrors error
,
2880 xmlSchemaBasicItemPtr ownerItem
,
2881 xmlNodePtr ownerElem
,
2883 const xmlChar
*refName
,
2884 const xmlChar
*refURI
,
2885 xmlSchemaTypeType refType
,
2886 const char *refTypeStr
)
2888 xmlChar
*des
= NULL
, *strA
= NULL
;
2890 xmlSchemaFormatItemForReport(&des
, NULL
, ownerItem
, ownerElem
);
2891 if (refTypeStr
== NULL
)
2892 refTypeStr
= (const char *) xmlSchemaItemTypeToStr(refType
);
2893 xmlSchemaPErrExt(ctxt
, ownerElem
, error
,
2895 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2896 "%s.\n", BAD_CAST des
, BAD_CAST name
,
2897 xmlSchemaFormatQName(&strA
, refURI
, refName
),
2898 BAD_CAST refTypeStr
, NULL
);
2904 * xmlSchemaPCustomAttrErr:
2905 * @ctxt: the schema parser context
2906 * @error: the error code
2907 * @ownerDes: the designation of the owner
2908 * @ownerItem: the owner as a schema object
2909 * @attr: the illegal attribute node
2911 * Reports an illegal attribute during the parse.
2914 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt
,
2915 xmlParserErrors error
,
2917 xmlSchemaBasicItemPtr ownerItem
,
2921 xmlChar
*des
= NULL
;
2923 if (ownerDes
== NULL
)
2924 xmlSchemaFormatItemForReport(&des
, NULL
, ownerItem
, attr
->parent
);
2925 else if (*ownerDes
== NULL
) {
2926 xmlSchemaFormatItemForReport(ownerDes
, NULL
, ownerItem
, attr
->parent
);
2931 xmlSchemaPErrExt(ctxt
, NULL
, error
, NULL
, NULL
, NULL
,
2932 "%s, attribute '%s': %s.\n",
2933 BAD_CAST des
, (const xmlChar
*) "Unknown",
2934 (const xmlChar
*) msg
, NULL
, NULL
);
2936 xmlSchemaPErrExt(ctxt
, (xmlNodePtr
) attr
, error
, NULL
, NULL
, NULL
,
2937 "%s, attribute '%s': %s.\n",
2938 BAD_CAST des
, attr
->name
, (const xmlChar
*) msg
, NULL
, NULL
);
2940 if (ownerDes
== NULL
)
2945 * xmlSchemaPIllegalAttrErr:
2946 * @ctxt: the schema parser context
2947 * @error: the error code
2948 * @ownerItem: the attribute's owner item
2949 * @attr: the illegal attribute node
2951 * Reports an illegal attribute during the parse.
2954 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt
,
2955 xmlParserErrors error
,
2956 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED
,
2959 xmlChar
*strA
= NULL
, *strB
= NULL
;
2961 xmlSchemaFormatNodeForError(&strA
, ACTXT_CAST ctxt
, attr
->parent
);
2962 xmlSchemaErr4(ACTXT_CAST ctxt
, error
, (xmlNodePtr
) attr
,
2963 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA
,
2964 xmlSchemaFormatQNameNs(&strB
, attr
->ns
, attr
->name
),
2966 FREE_AND_NULL(strA
);
2967 FREE_AND_NULL(strB
);
2971 * xmlSchemaPCustomErr:
2972 * @ctxt: the schema parser context
2973 * @error: the error code
2974 * @itemDes: the designation of the schema item
2975 * @item: the schema item
2976 * @itemElem: the node of the schema item
2977 * @message: the error message
2978 * @str1: an optional param for the error message
2979 * @str2: an optional param for the error message
2980 * @str3: an optional param for the error message
2982 * Reports an error during parsing.
2984 static void LIBXML_ATTR_FORMAT(5,0)
2985 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt
,
2986 xmlParserErrors error
,
2987 xmlSchemaBasicItemPtr item
,
2988 xmlNodePtr itemElem
,
2989 const char *message
,
2990 const xmlChar
*str1
,
2991 const xmlChar
*str2
,
2992 const xmlChar
*str3
)
2994 xmlChar
*des
= NULL
, *msg
= NULL
;
2996 xmlSchemaFormatItemForReport(&des
, NULL
, item
, itemElem
);
2997 msg
= xmlStrdup(BAD_CAST
"%s: ");
2998 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
2999 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
3000 if ((itemElem
== NULL
) && (item
!= NULL
))
3001 itemElem
= WXS_ITEM_NODE(item
);
3002 xmlSchemaPErrExt(ctxt
, itemElem
, error
, NULL
, NULL
, NULL
,
3003 (const char *) msg
, BAD_CAST des
, str1
, str2
, str3
, NULL
);
3009 * xmlSchemaPCustomErr:
3010 * @ctxt: the schema parser context
3011 * @error: the error code
3012 * @itemDes: the designation of the schema item
3013 * @item: the schema item
3014 * @itemElem: the node of the schema item
3015 * @message: the error message
3016 * @str1: the optional param for the error message
3018 * Reports an error during parsing.
3020 static void LIBXML_ATTR_FORMAT(5,0)
3021 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt
,
3022 xmlParserErrors error
,
3023 xmlSchemaBasicItemPtr item
,
3024 xmlNodePtr itemElem
,
3025 const char *message
,
3026 const xmlChar
*str1
)
3028 xmlSchemaPCustomErrExt(ctxt
, error
, item
, itemElem
, message
,
3033 * xmlSchemaPAttrUseErr:
3034 * @ctxt: the schema parser context
3035 * @error: the error code
3036 * @itemDes: the designation of the schema type
3037 * @item: the schema type
3038 * @itemElem: the node of the schema type
3039 * @attr: the invalid schema attribute
3040 * @message: the error message
3041 * @str1: the optional param for the error message
3043 * Reports an attribute use error during parsing.
3045 static void LIBXML_ATTR_FORMAT(6,0)
3046 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt
,
3047 xmlParserErrors error
,
3049 xmlSchemaBasicItemPtr ownerItem
,
3050 const xmlSchemaAttributeUsePtr attruse
,
3051 const char *message
,
3052 const xmlChar
*str1
, const xmlChar
*str2
,
3053 const xmlChar
*str3
,const xmlChar
*str4
)
3055 xmlChar
*str
= NULL
, *msg
= NULL
;
3057 xmlSchemaFormatItemForReport(&msg
, NULL
, ownerItem
, NULL
);
3058 msg
= xmlStrcat(msg
, BAD_CAST
", ");
3059 msg
= xmlStrcat(msg
,
3060 BAD_CAST
xmlSchemaFormatItemForReport(&str
, NULL
,
3061 WXS_BASIC_CAST attruse
, NULL
));
3063 msg
= xmlStrcat(msg
, BAD_CAST
": ");
3064 msg
= xmlStrcat(msg
, (const xmlChar
*) message
);
3065 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
3066 xmlSchemaErr4(ACTXT_CAST ctxt
, error
, node
,
3067 (const char *) msg
, str1
, str2
, str3
, str4
);
3072 * xmlSchemaPIllegalFacetAtomicErr:
3073 * @ctxt: the schema parser context
3074 * @error: the error code
3075 * @type: the schema type
3076 * @baseType: the base type of type
3077 * @facet: the illegal facet
3079 * Reports an illegal facet for atomic simple types.
3082 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt
,
3083 xmlParserErrors error
,
3084 xmlSchemaTypePtr type
,
3085 xmlSchemaTypePtr baseType
,
3086 xmlSchemaFacetPtr facet
)
3088 xmlChar
*des
= NULL
, *strT
= NULL
;
3090 xmlSchemaFormatItemForReport(&des
, NULL
, WXS_BASIC_CAST type
, type
->node
);
3091 xmlSchemaPErrExt(ctxt
, type
->node
, error
, NULL
, NULL
, NULL
,
3092 "%s: The facet '%s' is not allowed on types derived from the "
3094 BAD_CAST des
, xmlSchemaFacetTypeToString(facet
->type
),
3095 xmlSchemaFormatItemForReport(&strT
, NULL
, WXS_BASIC_CAST baseType
, NULL
),
3098 FREE_AND_NULL(strT
);
3102 * xmlSchemaPIllegalFacetListUnionErr:
3103 * @ctxt: the schema parser context
3104 * @error: the error code
3105 * @itemDes: the designation of the schema item involved
3106 * @item: the schema item involved
3107 * @facet: the illegal facet
3109 * Reports an illegal facet for <list> and <union>.
3112 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt
,
3113 xmlParserErrors error
,
3114 xmlSchemaTypePtr type
,
3115 xmlSchemaFacetPtr facet
)
3117 xmlChar
*des
= NULL
;
3119 xmlSchemaFormatItemForReport(&des
, NULL
, WXS_BASIC_CAST type
,
3121 xmlSchemaPErr(ctxt
, type
->node
, error
,
3122 "%s: The facet '%s' is not allowed.\n",
3123 BAD_CAST des
, xmlSchemaFacetTypeToString(facet
->type
));
3128 * xmlSchemaPMutualExclAttrErr:
3129 * @ctxt: the schema validation context
3130 * @error: the error code
3131 * @elemDes: the designation of the parent element node
3132 * @attr: the bad attribute node
3133 * @type: the corresponding type of the attribute node
3135 * Reports an illegal attribute.
3138 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt
,
3139 xmlParserErrors error
,
3140 xmlSchemaBasicItemPtr ownerItem
,
3145 xmlChar
*des
= NULL
;
3147 xmlSchemaFormatItemForReport(&des
, NULL
, WXS_BASIC_CAST ownerItem
, attr
->parent
);
3148 xmlSchemaPErrExt(ctxt
, (xmlNodePtr
) attr
, error
, NULL
, NULL
, NULL
,
3149 "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3150 BAD_CAST des
, BAD_CAST name1
, BAD_CAST name2
, NULL
, NULL
);
3155 * xmlSchemaPSimpleTypeErr:
3156 * @ctxt: the schema validation context
3157 * @error: the error code
3158 * @type: the type specifier
3159 * @ownerItem: the schema object if existent
3160 * @node: the validated node
3161 * @value: the validated value
3163 * Reports a simple type validation error.
3164 * TODO: Should this report the value of an element as well?
3166 static void LIBXML_ATTR_FORMAT(8,0)
3167 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt
,
3168 xmlParserErrors error
,
3169 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED
,
3171 xmlSchemaTypePtr type
,
3172 const char *expected
,
3173 const xmlChar
*value
,
3174 const char *message
,
3175 const xmlChar
*str1
,
3176 const xmlChar
*str2
)
3178 xmlChar
*msg
= NULL
;
3180 xmlSchemaFormatNodeForError(&msg
, ACTXT_CAST ctxt
, node
);
3181 if (message
== NULL
) {
3183 * Use default messages.
3186 if (node
->type
== XML_ATTRIBUTE_NODE
)
3187 msg
= xmlStrcat(msg
, BAD_CAST
"'%s' is not a valid value of ");
3189 msg
= xmlStrcat(msg
, BAD_CAST
"The character content is not a "
3191 if (! xmlSchemaIsGlobalItem(type
))
3192 msg
= xmlStrcat(msg
, BAD_CAST
"the local ");
3194 msg
= xmlStrcat(msg
, BAD_CAST
"the ");
3196 if (WXS_IS_ATOMIC(type
))
3197 msg
= xmlStrcat(msg
, BAD_CAST
"atomic type");
3198 else if (WXS_IS_LIST(type
))
3199 msg
= xmlStrcat(msg
, BAD_CAST
"list type");
3200 else if (WXS_IS_UNION(type
))
3201 msg
= xmlStrcat(msg
, BAD_CAST
"union type");
3203 if (xmlSchemaIsGlobalItem(type
)) {
3204 xmlChar
*str
= NULL
;
3205 msg
= xmlStrcat(msg
, BAD_CAST
" '");
3206 if (type
->builtInType
!= 0) {
3207 msg
= xmlStrcat(msg
, BAD_CAST
"xs:");
3208 str
= xmlStrdup(type
->name
);
3210 const xmlChar
*qName
= xmlSchemaFormatQName(&str
, type
->targetNamespace
, type
->name
);
3212 str
= xmlStrdup(qName
);
3214 msg
= xmlStrcat(msg
, xmlEscapeFormatString(&str
));
3215 msg
= xmlStrcat(msg
, BAD_CAST
"'.");
3219 if (node
->type
== XML_ATTRIBUTE_NODE
)
3220 msg
= xmlStrcat(msg
, BAD_CAST
"The value '%s' is not valid.");
3222 msg
= xmlStrcat(msg
, BAD_CAST
"The character content is not "
3226 xmlChar
*expectedEscaped
= xmlCharStrdup(expected
);
3227 msg
= xmlStrcat(msg
, BAD_CAST
" Expected is '");
3228 msg
= xmlStrcat(msg
, xmlEscapeFormatString(&expectedEscaped
));
3229 FREE_AND_NULL(expectedEscaped
);
3230 msg
= xmlStrcat(msg
, BAD_CAST
"'.\n");
3232 msg
= xmlStrcat(msg
, BAD_CAST
"\n");
3233 if (node
->type
== XML_ATTRIBUTE_NODE
)
3234 xmlSchemaPErr(ctxt
, node
, error
, (const char *) msg
, value
, NULL
);
3236 xmlSchemaPErr(ctxt
, node
, error
, (const char *) msg
, NULL
, NULL
);
3238 msg
= xmlStrcat(msg
, BAD_CAST message
);
3239 msg
= xmlStrcat(msg
, BAD_CAST
".\n");
3240 xmlSchemaPErrExt(ctxt
, node
, error
, NULL
, NULL
, NULL
,
3241 (const char*) msg
, str1
, str2
, NULL
, NULL
, NULL
);
3248 * xmlSchemaPContentErr:
3249 * @ctxt: the schema parser context
3250 * @error: the error code
3251 * @ownerItem: the owner item of the holder of the content
3252 * @ownerElem: the node of the holder of the content
3253 * @child: the invalid child node
3254 * @message: the optional error message
3255 * @content: the optional string describing the correct content
3257 * Reports an error concerning the content of a schema element.
3260 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt
,
3261 xmlParserErrors error
,
3262 xmlSchemaBasicItemPtr ownerItem
,
3263 xmlNodePtr ownerElem
,
3265 const char *message
,
3266 const char *content
)
3268 xmlChar
*des
= NULL
;
3270 xmlSchemaFormatItemForReport(&des
, NULL
, ownerItem
, ownerElem
);
3271 if (message
!= NULL
)
3272 xmlSchemaPErr2(ctxt
, ownerElem
, child
, error
,
3274 BAD_CAST des
, BAD_CAST message
);
3276 if (content
!= NULL
) {
3277 xmlSchemaPErr2(ctxt
, ownerElem
, child
, error
,
3278 "%s: The content is not valid. Expected is %s.\n",
3279 BAD_CAST des
, BAD_CAST content
);
3281 xmlSchemaPErr2(ctxt
, ownerElem
, child
, error
,
3282 "%s: The content is not valid.\n",
3283 BAD_CAST des
, NULL
);
3289 /************************************************************************
3291 * Streamable error functions *
3293 ************************************************************************/
3298 /************************************************************************
3300 * Validation helper functions *
3302 ************************************************************************/
3305 /************************************************************************
3307 * Allocation functions *
3309 ************************************************************************/
3312 * xmlSchemaNewSchemaForParserCtxt:
3313 * @ctxt: a schema validation context
3315 * Allocate a new Schema structure.
3317 * Returns the newly allocated structure or NULL in case or error
3320 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt
)
3324 ret
= (xmlSchemaPtr
) xmlMalloc(sizeof(xmlSchema
));
3326 xmlSchemaPErrMemory(ctxt
, "allocating schema", NULL
);
3329 memset(ret
, 0, sizeof(xmlSchema
));
3330 ret
->dict
= ctxt
->dict
;
3331 xmlDictReference(ret
->dict
);
3337 * xmlSchemaNewFacet:
3339 * Allocate a new Facet structure.
3341 * Returns the newly allocated structure or NULL in case or error
3344 xmlSchemaNewFacet(void)
3346 xmlSchemaFacetPtr ret
;
3348 ret
= (xmlSchemaFacetPtr
) xmlMalloc(sizeof(xmlSchemaFacet
));
3352 memset(ret
, 0, sizeof(xmlSchemaFacet
));
3358 * xmlSchemaNewAnnot:
3359 * @ctxt: a schema validation context
3362 * Allocate a new annotation structure.
3364 * Returns the newly allocated structure or NULL in case or error
3366 static xmlSchemaAnnotPtr
3367 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
)
3369 xmlSchemaAnnotPtr ret
;
3371 ret
= (xmlSchemaAnnotPtr
) xmlMalloc(sizeof(xmlSchemaAnnot
));
3373 xmlSchemaPErrMemory(ctxt
, "allocating annotation", node
);
3376 memset(ret
, 0, sizeof(xmlSchemaAnnot
));
3377 ret
->content
= node
;
3381 static xmlSchemaItemListPtr
3382 xmlSchemaItemListCreate(void)
3384 xmlSchemaItemListPtr ret
;
3386 ret
= xmlMalloc(sizeof(xmlSchemaItemList
));
3388 xmlSchemaPErrMemory(NULL
,
3389 "allocating an item list structure", NULL
);
3392 memset(ret
, 0, sizeof(xmlSchemaItemList
));
3397 xmlSchemaItemListClear(xmlSchemaItemListPtr list
)
3399 if (list
->items
!= NULL
) {
3400 xmlFree(list
->items
);
3404 list
->sizeItems
= 0;
3408 xmlSchemaItemListAdd(xmlSchemaItemListPtr list
, void *item
)
3410 if (list
->items
== NULL
) {
3411 list
->items
= (void **) xmlMalloc(
3412 20 * sizeof(void *));
3413 if (list
->items
== NULL
) {
3414 xmlSchemaPErrMemory(NULL
, "allocating new item list", NULL
);
3417 list
->sizeItems
= 20;
3418 } else if (list
->sizeItems
<= list
->nbItems
) {
3419 list
->sizeItems
*= 2;
3420 list
->items
= (void **) xmlRealloc(list
->items
,
3421 list
->sizeItems
* sizeof(void *));
3422 if (list
->items
== NULL
) {
3423 xmlSchemaPErrMemory(NULL
, "growing item list", NULL
);
3424 list
->sizeItems
= 0;
3428 list
->items
[list
->nbItems
++] = item
;
3433 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list
,
3437 if (list
->items
== NULL
) {
3438 if (initialSize
<= 0)
3440 list
->items
= (void **) xmlMalloc(
3441 initialSize
* sizeof(void *));
3442 if (list
->items
== NULL
) {
3443 xmlSchemaPErrMemory(NULL
, "allocating new item list", NULL
);
3446 list
->sizeItems
= initialSize
;
3447 } else if (list
->sizeItems
<= list
->nbItems
) {
3448 list
->sizeItems
*= 2;
3449 list
->items
= (void **) xmlRealloc(list
->items
,
3450 list
->sizeItems
* sizeof(void *));
3451 if (list
->items
== NULL
) {
3452 xmlSchemaPErrMemory(NULL
, "growing item list", NULL
);
3453 list
->sizeItems
= 0;
3457 list
->items
[list
->nbItems
++] = item
;
3462 xmlSchemaItemListInsert(xmlSchemaItemListPtr list
, void *item
, int idx
)
3464 if (list
->items
== NULL
) {
3465 list
->items
= (void **) xmlMalloc(
3466 20 * sizeof(void *));
3467 if (list
->items
== NULL
) {
3468 xmlSchemaPErrMemory(NULL
, "allocating new item list", NULL
);
3471 list
->sizeItems
= 20;
3472 } else if (list
->sizeItems
<= list
->nbItems
) {
3473 list
->sizeItems
*= 2;
3474 list
->items
= (void **) xmlRealloc(list
->items
,
3475 list
->sizeItems
* sizeof(void *));
3476 if (list
->items
== NULL
) {
3477 xmlSchemaPErrMemory(NULL
, "growing item list", NULL
);
3478 list
->sizeItems
= 0;
3483 * Just append if the index is greater/equal than the item count.
3485 if (idx
>= list
->nbItems
) {
3486 list
->items
[list
->nbItems
++] = item
;
3489 for (i
= list
->nbItems
; i
> idx
; i
--)
3490 list
->items
[i
] = list
->items
[i
-1];
3491 list
->items
[idx
] = item
;
3497 #if 0 /* enable if ever needed */
3499 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list
,
3504 if (list
->items
== NULL
) {
3505 if (initialSize
<= 0)
3507 list
->items
= (void **) xmlMalloc(
3508 initialSize
* sizeof(void *));
3509 if (list
->items
== NULL
) {
3510 xmlSchemaPErrMemory(NULL
, "allocating new item list", NULL
);
3513 list
->sizeItems
= initialSize
;
3514 } else if (list
->sizeItems
<= list
->nbItems
) {
3515 list
->sizeItems
*= 2;
3516 list
->items
= (void **) xmlRealloc(list
->items
,
3517 list
->sizeItems
* sizeof(void *));
3518 if (list
->items
== NULL
) {
3519 xmlSchemaPErrMemory(NULL
, "growing item list", NULL
);
3520 list
->sizeItems
= 0;
3525 * Just append if the index is greater/equal than the item count.
3527 if (idx
>= list
->nbItems
) {
3528 list
->items
[list
->nbItems
++] = item
;
3531 for (i
= list
->nbItems
; i
> idx
; i
--)
3532 list
->items
[i
] = list
->items
[i
-1];
3533 list
->items
[idx
] = item
;
3541 xmlSchemaItemListRemove(xmlSchemaItemListPtr list
, int idx
)
3544 if ((list
->items
== NULL
) || (idx
>= list
->nbItems
)) {
3545 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
3550 if (list
->nbItems
== 1) {
3551 /* TODO: Really free the list? */
3552 xmlFree(list
->items
);
3555 list
->sizeItems
= 0;
3556 } else if (list
->nbItems
-1 == idx
) {
3559 for (i
= idx
; i
< list
->nbItems
-1; i
++)
3560 list
->items
[i
] = list
->items
[i
+1];
3567 * xmlSchemaItemListFree:
3568 * @annot: a schema type structure
3570 * Deallocate a annotation structure
3573 xmlSchemaItemListFree(xmlSchemaItemListPtr list
)
3577 if (list
->items
!= NULL
)
3578 xmlFree(list
->items
);
3583 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket
)
3587 if (bucket
->globals
!= NULL
) {
3588 xmlSchemaComponentListFree(bucket
->globals
);
3589 xmlSchemaItemListFree(bucket
->globals
);
3591 if (bucket
->locals
!= NULL
) {
3592 xmlSchemaComponentListFree(bucket
->locals
);
3593 xmlSchemaItemListFree(bucket
->locals
);
3595 if (bucket
->relations
!= NULL
) {
3596 xmlSchemaSchemaRelationPtr prev
, cur
= bucket
->relations
;
3601 } while (cur
!= NULL
);
3603 if ((! bucket
->preserveDoc
) && (bucket
->doc
!= NULL
)) {
3604 xmlFreeDoc(bucket
->doc
);
3606 if (bucket
->type
== XML_SCHEMA_SCHEMA_IMPORT
) {
3607 if (WXS_IMPBUCKET(bucket
)->schema
!= NULL
)
3608 xmlSchemaFree(WXS_IMPBUCKET(bucket
)->schema
);
3614 xmlSchemaBucketFreeEntry(void *bucket
, const xmlChar
*name ATTRIBUTE_UNUSED
)
3616 xmlSchemaBucketFree((xmlSchemaBucketPtr
) bucket
);
3619 static xmlSchemaBucketPtr
3620 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt
,
3621 int type
, const xmlChar
*targetNamespace
)
3623 xmlSchemaBucketPtr ret
;
3625 xmlSchemaPtr mainSchema
;
3627 if (WXS_CONSTRUCTOR(pctxt
)->mainSchema
== NULL
) {
3628 PERROR_INT("xmlSchemaBucketCreate",
3629 "no main schema on constructor");
3632 mainSchema
= WXS_CONSTRUCTOR(pctxt
)->mainSchema
;
3633 /* Create the schema bucket. */
3634 if (WXS_IS_BUCKET_INCREDEF(type
))
3635 size
= sizeof(xmlSchemaInclude
);
3637 size
= sizeof(xmlSchemaImport
);
3638 ret
= (xmlSchemaBucketPtr
) xmlMalloc(size
);
3640 xmlSchemaPErrMemory(NULL
, "allocating schema bucket", NULL
);
3643 memset(ret
, 0, size
);
3644 ret
->targetNamespace
= targetNamespace
;
3646 ret
->globals
= xmlSchemaItemListCreate();
3647 if (ret
->globals
== NULL
) {
3651 ret
->locals
= xmlSchemaItemListCreate();
3652 if (ret
->locals
== NULL
) {
3657 * The following will assure that only the first bucket is marked as
3658 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3659 * For each following import buckets an xmlSchema will be created.
3660 * An xmlSchema will be created for every distinct targetNamespace.
3661 * We assign the targetNamespace to the schemata here.
3663 if (! WXS_HAS_BUCKETS(pctxt
)) {
3664 if (WXS_IS_BUCKET_INCREDEF(type
)) {
3665 PERROR_INT("xmlSchemaBucketCreate",
3666 "first bucket but it's an include or redefine");
3667 xmlSchemaBucketFree(ret
);
3670 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3671 ret
->type
= XML_SCHEMA_SCHEMA_MAIN
;
3672 /* Point to the *main* schema. */
3673 WXS_CONSTRUCTOR(pctxt
)->mainBucket
= ret
;
3674 WXS_IMPBUCKET(ret
)->schema
= mainSchema
;
3676 * Ensure that the main schema gets a targetNamespace.
3678 mainSchema
->targetNamespace
= targetNamespace
;
3680 if (type
== XML_SCHEMA_SCHEMA_MAIN
) {
3681 PERROR_INT("xmlSchemaBucketCreate",
3682 "main bucket but it's not the first one");
3683 xmlSchemaBucketFree(ret
);
3685 } else if (type
== XML_SCHEMA_SCHEMA_IMPORT
) {
3687 * Create a schema for imports and assign the
3690 WXS_IMPBUCKET(ret
)->schema
= xmlSchemaNewSchema(pctxt
);
3691 if (WXS_IMPBUCKET(ret
)->schema
== NULL
) {
3692 xmlSchemaBucketFree(ret
);
3695 WXS_IMPBUCKET(ret
)->schema
->targetNamespace
= targetNamespace
;
3698 if (WXS_IS_BUCKET_IMPMAIN(type
)) {
3701 * Imports go into the "schemasImports" slot of the main *schema*.
3702 * Note that we create an import entry for the main schema as well; i.e.,
3703 * even if there's only one schema, we'll get an import.
3705 if (mainSchema
->schemasImports
== NULL
) {
3706 mainSchema
->schemasImports
= xmlHashCreateDict(5,
3707 WXS_CONSTRUCTOR(pctxt
)->dict
);
3708 if (mainSchema
->schemasImports
== NULL
) {
3709 xmlSchemaBucketFree(ret
);
3713 if (targetNamespace
== NULL
)
3714 res
= xmlHashAddEntry(mainSchema
->schemasImports
,
3715 XML_SCHEMAS_NO_NAMESPACE
, ret
);
3717 res
= xmlHashAddEntry(mainSchema
->schemasImports
,
3718 targetNamespace
, ret
);
3720 PERROR_INT("xmlSchemaBucketCreate",
3721 "failed to add the schema bucket to the hash");
3722 xmlSchemaBucketFree(ret
);
3726 /* Set the @ownerImport of an include bucket. */
3727 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt
)->bucket
->type
))
3728 WXS_INCBUCKET(ret
)->ownerImport
=
3729 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt
)->bucket
);
3731 WXS_INCBUCKET(ret
)->ownerImport
=
3732 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt
)->bucket
)->ownerImport
;
3734 /* Includes got into the "includes" slot of the *main* schema. */
3735 if (mainSchema
->includes
== NULL
) {
3736 mainSchema
->includes
= xmlSchemaItemListCreate();
3737 if (mainSchema
->includes
== NULL
) {
3738 xmlSchemaBucketFree(ret
);
3742 xmlSchemaItemListAdd(mainSchema
->includes
, ret
);
3745 * Add to list of all buckets; this is used for lookup
3746 * during schema construction time only.
3748 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt
)->buckets
, ret
) == -1)
3754 xmlSchemaAddItemSize(xmlSchemaItemListPtr
*list
, int initialSize
, void *item
)
3756 if (*list
== NULL
) {
3757 *list
= xmlSchemaItemListCreate();
3761 xmlSchemaItemListAddSize(*list
, initialSize
, item
);
3766 * xmlSchemaFreeAnnot:
3767 * @annot: a schema type structure
3769 * Deallocate a annotation structure
3772 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot
)
3776 if (annot
->next
== NULL
) {
3779 xmlSchemaAnnotPtr prev
;
3783 annot
= annot
->next
;
3785 } while (annot
!= NULL
);
3790 * xmlSchemaFreeNotation:
3791 * @schema: a schema notation structure
3793 * Deallocate a Schema Notation structure.
3796 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota
)
3804 * xmlSchemaFreeAttribute:
3805 * @attr: an attribute declaration
3807 * Deallocates an attribute declaration structure.
3810 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr
)
3814 if (attr
->annot
!= NULL
)
3815 xmlSchemaFreeAnnot(attr
->annot
);
3816 if (attr
->defVal
!= NULL
)
3817 xmlSchemaFreeValue(attr
->defVal
);
3822 * xmlSchemaFreeAttributeUse:
3823 * @use: an attribute use
3825 * Deallocates an attribute use structure.
3828 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use
)
3832 if (use
->annot
!= NULL
)
3833 xmlSchemaFreeAnnot(use
->annot
);
3834 if (use
->defVal
!= NULL
)
3835 xmlSchemaFreeValue(use
->defVal
);
3840 * xmlSchemaFreeAttributeUseProhib:
3841 * @prohib: an attribute use prohibition
3843 * Deallocates an attribute use structure.
3846 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib
)
3854 * xmlSchemaFreeWildcardNsSet:
3855 * set: a schema wildcard namespace
3857 * Deallocates a list of wildcard constraint structures.
3860 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set
)
3862 xmlSchemaWildcardNsPtr next
;
3864 while (set
!= NULL
) {
3872 * xmlSchemaFreeWildcard:
3873 * @wildcard: a wildcard structure
3875 * Deallocates a wildcard structure.
3878 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard
)
3880 if (wildcard
== NULL
)
3882 if (wildcard
->annot
!= NULL
)
3883 xmlSchemaFreeAnnot(wildcard
->annot
);
3884 if (wildcard
->nsSet
!= NULL
)
3885 xmlSchemaFreeWildcardNsSet(wildcard
->nsSet
);
3886 if (wildcard
->negNsSet
!= NULL
)
3887 xmlFree(wildcard
->negNsSet
);
3892 * xmlSchemaFreeAttributeGroup:
3893 * @schema: a schema attribute group structure
3895 * Deallocate a Schema Attribute Group structure.
3898 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr
)
3902 if (attrGr
->annot
!= NULL
)
3903 xmlSchemaFreeAnnot(attrGr
->annot
);
3904 if (attrGr
->attrUses
!= NULL
)
3905 xmlSchemaItemListFree(WXS_LIST_CAST attrGr
->attrUses
);
3910 * xmlSchemaFreeQNameRef:
3911 * @item: a QName reference structure
3913 * Deallocatea a QName reference structure.
3916 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item
)
3922 * xmlSchemaFreeTypeLinkList:
3923 * @alink: a type link
3925 * Deallocate a list of types.
3928 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link
)
3930 xmlSchemaTypeLinkPtr next
;
3932 while (link
!= NULL
) {
3940 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto
)
3942 xmlSchemaIDCStateObjPtr next
;
3943 while (sto
!= NULL
) {
3945 if (sto
->history
!= NULL
)
3946 xmlFree(sto
->history
);
3947 if (sto
->xpathCtxt
!= NULL
)
3948 xmlFreeStreamCtxt((xmlStreamCtxtPtr
) sto
->xpathCtxt
);
3956 * @idc: a identity-constraint definition
3958 * Deallocates an identity-constraint definition.
3961 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef
)
3963 xmlSchemaIDCSelectPtr cur
, prev
;
3967 if (idcDef
->annot
!= NULL
)
3968 xmlSchemaFreeAnnot(idcDef
->annot
);
3970 if (idcDef
->selector
!= NULL
) {
3971 if (idcDef
->selector
->xpathComp
!= NULL
)
3972 xmlFreePattern((xmlPatternPtr
) idcDef
->selector
->xpathComp
);
3973 xmlFree(idcDef
->selector
);
3976 if (idcDef
->fields
!= NULL
) {
3977 cur
= idcDef
->fields
;
3981 if (prev
->xpathComp
!= NULL
)
3982 xmlFreePattern((xmlPatternPtr
) prev
->xpathComp
);
3984 } while (cur
!= NULL
);
3990 * xmlSchemaFreeElement:
3991 * @schema: a schema element structure
3993 * Deallocate a Schema Element structure.
3996 xmlSchemaFreeElement(xmlSchemaElementPtr elem
)
4000 if (elem
->annot
!= NULL
)
4001 xmlSchemaFreeAnnot(elem
->annot
);
4002 if (elem
->contModel
!= NULL
)
4003 xmlRegFreeRegexp(elem
->contModel
);
4004 if (elem
->defVal
!= NULL
)
4005 xmlSchemaFreeValue(elem
->defVal
);
4010 * xmlSchemaFreeFacet:
4011 * @facet: a schema facet structure
4013 * Deallocate a Schema Facet structure.
4016 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet
)
4020 if (facet
->val
!= NULL
)
4021 xmlSchemaFreeValue(facet
->val
);
4022 if (facet
->regexp
!= NULL
)
4023 xmlRegFreeRegexp(facet
->regexp
);
4024 if (facet
->annot
!= NULL
)
4025 xmlSchemaFreeAnnot(facet
->annot
);
4030 * xmlSchemaFreeType:
4031 * @type: a schema type structure
4033 * Deallocate a Schema Type structure.
4036 xmlSchemaFreeType(xmlSchemaTypePtr type
)
4040 if (type
->annot
!= NULL
)
4041 xmlSchemaFreeAnnot(type
->annot
);
4042 if (type
->facets
!= NULL
) {
4043 xmlSchemaFacetPtr facet
, next
;
4045 facet
= type
->facets
;
4046 while (facet
!= NULL
) {
4048 xmlSchemaFreeFacet(facet
);
4052 if (type
->attrUses
!= NULL
)
4053 xmlSchemaItemListFree((xmlSchemaItemListPtr
) type
->attrUses
);
4054 if (type
->memberTypes
!= NULL
)
4055 xmlSchemaFreeTypeLinkList(type
->memberTypes
);
4056 if (type
->facetSet
!= NULL
) {
4057 xmlSchemaFacetLinkPtr next
, link
;
4059 link
= type
->facetSet
;
4064 } while (link
!= NULL
);
4066 if (type
->contModel
!= NULL
)
4067 xmlRegFreeRegexp(type
->contModel
);
4072 * xmlSchemaFreeModelGroupDef:
4073 * @item: a schema model group definition
4075 * Deallocates a schema model group definition.
4078 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item
)
4080 if (item
->annot
!= NULL
)
4081 xmlSchemaFreeAnnot(item
->annot
);
4086 * xmlSchemaFreeModelGroup:
4087 * @item: a schema model group
4089 * Deallocates a schema model group structure.
4092 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item
)
4094 if (item
->annot
!= NULL
)
4095 xmlSchemaFreeAnnot(item
->annot
);
4100 xmlSchemaComponentListFree(xmlSchemaItemListPtr list
)
4102 if ((list
== NULL
) || (list
->nbItems
== 0))
4105 xmlSchemaTreeItemPtr item
;
4106 xmlSchemaTreeItemPtr
*items
= (xmlSchemaTreeItemPtr
*) list
->items
;
4109 for (i
= 0; i
< list
->nbItems
; i
++) {
4113 switch (item
->type
) {
4114 case XML_SCHEMA_TYPE_SIMPLE
:
4115 case XML_SCHEMA_TYPE_COMPLEX
:
4116 xmlSchemaFreeType((xmlSchemaTypePtr
) item
);
4118 case XML_SCHEMA_TYPE_ATTRIBUTE
:
4119 xmlSchemaFreeAttribute((xmlSchemaAttributePtr
) item
);
4121 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
4122 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr
) item
);
4124 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
:
4125 xmlSchemaFreeAttributeUseProhib(
4126 (xmlSchemaAttributeUseProhibPtr
) item
);
4128 case XML_SCHEMA_TYPE_ELEMENT
:
4129 xmlSchemaFreeElement((xmlSchemaElementPtr
) item
);
4131 case XML_SCHEMA_TYPE_PARTICLE
:
4132 if (item
->annot
!= NULL
)
4133 xmlSchemaFreeAnnot(item
->annot
);
4136 case XML_SCHEMA_TYPE_SEQUENCE
:
4137 case XML_SCHEMA_TYPE_CHOICE
:
4138 case XML_SCHEMA_TYPE_ALL
:
4139 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr
) item
);
4141 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
4142 xmlSchemaFreeAttributeGroup(
4143 (xmlSchemaAttributeGroupPtr
) item
);
4145 case XML_SCHEMA_TYPE_GROUP
:
4146 xmlSchemaFreeModelGroupDef(
4147 (xmlSchemaModelGroupDefPtr
) item
);
4149 case XML_SCHEMA_TYPE_ANY
:
4150 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE
:
4151 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr
) item
);
4153 case XML_SCHEMA_TYPE_IDC_KEY
:
4154 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
4155 case XML_SCHEMA_TYPE_IDC_KEYREF
:
4156 xmlSchemaFreeIDC((xmlSchemaIDCPtr
) item
);
4158 case XML_SCHEMA_TYPE_NOTATION
:
4159 xmlSchemaFreeNotation((xmlSchemaNotationPtr
) item
);
4161 case XML_SCHEMA_EXTRA_QNAMEREF
:
4162 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr
) item
);
4165 /* TODO: This should never be hit. */
4166 xmlSchemaPSimpleInternalErr(NULL
,
4167 "Internal error: xmlSchemaComponentListFree, "
4168 "unexpected component type '%s'\n",
4169 (const xmlChar
*) WXS_ITEM_TYPE_NAME(item
));
4180 * @schema: a schema structure
4182 * Deallocate a Schema structure.
4185 xmlSchemaFree(xmlSchemaPtr schema
)
4189 /* @volatiles is not used anymore :-/ */
4190 if (schema
->volatiles
!= NULL
)
4193 * Note that those slots are not responsible for freeing
4194 * schema components anymore; this will now be done by
4195 * the schema buckets.
4197 if (schema
->notaDecl
!= NULL
)
4198 xmlHashFree(schema
->notaDecl
, NULL
);
4199 if (schema
->attrDecl
!= NULL
)
4200 xmlHashFree(schema
->attrDecl
, NULL
);
4201 if (schema
->attrgrpDecl
!= NULL
)
4202 xmlHashFree(schema
->attrgrpDecl
, NULL
);
4203 if (schema
->elemDecl
!= NULL
)
4204 xmlHashFree(schema
->elemDecl
, NULL
);
4205 if (schema
->typeDecl
!= NULL
)
4206 xmlHashFree(schema
->typeDecl
, NULL
);
4207 if (schema
->groupDecl
!= NULL
)
4208 xmlHashFree(schema
->groupDecl
, NULL
);
4209 if (schema
->idcDef
!= NULL
)
4210 xmlHashFree(schema
->idcDef
, NULL
);
4212 if (schema
->schemasImports
!= NULL
)
4213 xmlHashFree(schema
->schemasImports
, xmlSchemaBucketFreeEntry
);
4214 if (schema
->includes
!= NULL
) {
4215 xmlSchemaItemListPtr list
= (xmlSchemaItemListPtr
) schema
->includes
;
4217 for (i
= 0; i
< list
->nbItems
; i
++) {
4218 xmlSchemaBucketFree((xmlSchemaBucketPtr
) list
->items
[i
]);
4220 xmlSchemaItemListFree(list
);
4222 if (schema
->annot
!= NULL
)
4223 xmlSchemaFreeAnnot(schema
->annot
);
4224 /* Never free the doc here, since this will be done by the buckets. */
4226 xmlDictFree(schema
->dict
);
4230 /************************************************************************
4234 ************************************************************************/
4236 #ifdef LIBXML_OUTPUT_ENABLED
4239 xmlSchemaTypeDump(xmlSchemaTypePtr type
, FILE * output
); /* forward */
4242 * xmlSchemaElementDump:
4244 * @output: the file output
4249 xmlSchemaElementDump(void *payload
, void *data
,
4250 const xmlChar
* name ATTRIBUTE_UNUSED
,
4251 const xmlChar
* namespace ATTRIBUTE_UNUSED
,
4252 const xmlChar
* context ATTRIBUTE_UNUSED
)
4254 xmlSchemaElementPtr elem
= (xmlSchemaElementPtr
) payload
;
4255 FILE *output
= (FILE *) data
;
4260 fprintf(output
, "Element");
4261 if (elem
->flags
& XML_SCHEMAS_ELEM_GLOBAL
)
4262 fprintf(output
, " (global)");
4263 fprintf(output
, ": '%s' ", elem
->name
);
4264 if (namespace != NULL
)
4265 fprintf(output
, "ns '%s'", namespace);
4266 fprintf(output
, "\n");
4268 if ((elem
->minOccurs
!= 1) || (elem
->maxOccurs
!= 1)) {
4269 fprintf(output
, " min %d ", elem
->minOccurs
);
4270 if (elem
->maxOccurs
>= UNBOUNDED
)
4271 fprintf(output
, "max: unbounded\n");
4272 else if (elem
->maxOccurs
!= 1)
4273 fprintf(output
, "max: %d\n", elem
->maxOccurs
);
4275 fprintf(output
, "\n");
4279 * Misc other properties.
4281 if ((elem
->flags
& XML_SCHEMAS_ELEM_NILLABLE
) ||
4282 (elem
->flags
& XML_SCHEMAS_ELEM_ABSTRACT
) ||
4283 (elem
->flags
& XML_SCHEMAS_ELEM_FIXED
) ||
4284 (elem
->flags
& XML_SCHEMAS_ELEM_DEFAULT
)) {
4285 fprintf(output
, " props: ");
4286 if (elem
->flags
& XML_SCHEMAS_ELEM_FIXED
)
4287 fprintf(output
, "[fixed] ");
4288 if (elem
->flags
& XML_SCHEMAS_ELEM_DEFAULT
)
4289 fprintf(output
, "[default] ");
4290 if (elem
->flags
& XML_SCHEMAS_ELEM_ABSTRACT
)
4291 fprintf(output
, "[abstract] ");
4292 if (elem
->flags
& XML_SCHEMAS_ELEM_NILLABLE
)
4293 fprintf(output
, "[nillable] ");
4294 fprintf(output
, "\n");
4297 * Default/fixed value.
4299 if (elem
->value
!= NULL
)
4300 fprintf(output
, " value: '%s'\n", elem
->value
);
4304 if (elem
->namedType
!= NULL
) {
4305 fprintf(output
, " type: '%s' ", elem
->namedType
);
4306 if (elem
->namedTypeNs
!= NULL
)
4307 fprintf(output
, "ns '%s'\n", elem
->namedTypeNs
);
4309 fprintf(output
, "\n");
4310 } else if (elem
->subtypes
!= NULL
) {
4314 xmlSchemaTypeDump(elem
->subtypes
, output
);
4317 * Substitution group.
4319 if (elem
->substGroup
!= NULL
) {
4320 fprintf(output
, " substitutionGroup: '%s' ", elem
->substGroup
);
4321 if (elem
->substGroupNs
!= NULL
)
4322 fprintf(output
, "ns '%s'\n", elem
->substGroupNs
);
4324 fprintf(output
, "\n");
4329 * xmlSchemaAnnotDump:
4330 * @output: the file output
4331 * @annot: a annotation
4333 * Dump the annotation
4336 xmlSchemaAnnotDump(FILE * output
, xmlSchemaAnnotPtr annot
)
4343 content
= xmlNodeGetContent(annot
->content
);
4344 if (content
!= NULL
) {
4345 fprintf(output
, " Annot: %s\n", content
);
4348 fprintf(output
, " Annot: empty\n");
4352 * xmlSchemaContentModelDump:
4353 * @particle: the schema particle
4354 * @output: the file output
4355 * @depth: the depth used for indentation
4357 * Dump a SchemaType structure
4360 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle
, FILE * output
, int depth
)
4362 xmlChar
*str
= NULL
;
4363 xmlSchemaTreeItemPtr term
;
4367 if (particle
== NULL
)
4369 for (i
= 0;((i
< depth
) && (i
< 25));i
++)
4370 shift
[2 * i
] = shift
[2 * i
+ 1] = ' ';
4371 shift
[2 * i
] = shift
[2 * i
+ 1] = 0;
4372 fprintf(output
, "%s", shift
);
4373 if (particle
->children
== NULL
) {
4374 fprintf(output
, "MISSING particle term\n");
4377 term
= particle
->children
;
4379 fprintf(output
, "(NULL)");
4381 switch (term
->type
) {
4382 case XML_SCHEMA_TYPE_ELEMENT
:
4383 fprintf(output
, "ELEM '%s'", xmlSchemaFormatQName(&str
,
4384 ((xmlSchemaElementPtr
)term
)->targetNamespace
,
4385 ((xmlSchemaElementPtr
)term
)->name
));
4388 case XML_SCHEMA_TYPE_SEQUENCE
:
4389 fprintf(output
, "SEQUENCE");
4391 case XML_SCHEMA_TYPE_CHOICE
:
4392 fprintf(output
, "CHOICE");
4394 case XML_SCHEMA_TYPE_ALL
:
4395 fprintf(output
, "ALL");
4397 case XML_SCHEMA_TYPE_ANY
:
4398 fprintf(output
, "ANY");
4401 fprintf(output
, "UNKNOWN\n");
4405 if (particle
->minOccurs
!= 1)
4406 fprintf(output
, " min: %d", particle
->minOccurs
);
4407 if (particle
->maxOccurs
>= UNBOUNDED
)
4408 fprintf(output
, " max: unbounded");
4409 else if (particle
->maxOccurs
!= 1)
4410 fprintf(output
, " max: %d", particle
->maxOccurs
);
4411 fprintf(output
, "\n");
4413 ((term
->type
== XML_SCHEMA_TYPE_SEQUENCE
) ||
4414 (term
->type
== XML_SCHEMA_TYPE_CHOICE
) ||
4415 (term
->type
== XML_SCHEMA_TYPE_ALL
)) &&
4416 (term
->children
!= NULL
)) {
4417 xmlSchemaContentModelDump((xmlSchemaParticlePtr
) term
->children
,
4420 if (particle
->next
!= NULL
)
4421 xmlSchemaContentModelDump((xmlSchemaParticlePtr
) particle
->next
,
4426 * xmlSchemaAttrUsesDump:
4427 * @uses: attribute uses list
4428 * @output: the file output
4430 * Dumps a list of attribute use components.
4433 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses
, FILE * output
)
4435 xmlSchemaAttributeUsePtr use
;
4436 xmlSchemaAttributeUseProhibPtr prohib
;
4437 xmlSchemaQNameRefPtr ref
;
4438 const xmlChar
*name
, *tns
;
4439 xmlChar
*str
= NULL
;
4442 if ((uses
== NULL
) || (uses
->nbItems
== 0))
4445 fprintf(output
, " attributes:\n");
4446 for (i
= 0; i
< uses
->nbItems
; i
++) {
4447 use
= uses
->items
[i
];
4448 if (use
->type
== XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
) {
4449 fprintf(output
, " [prohibition] ");
4450 prohib
= (xmlSchemaAttributeUseProhibPtr
) use
;
4451 name
= prohib
->name
;
4452 tns
= prohib
->targetNamespace
;
4453 } else if (use
->type
== XML_SCHEMA_EXTRA_QNAMEREF
) {
4454 fprintf(output
, " [reference] ");
4455 ref
= (xmlSchemaQNameRefPtr
) use
;
4457 tns
= ref
->targetNamespace
;
4459 fprintf(output
, " [use] ");
4460 name
= WXS_ATTRUSE_DECL_NAME(use
);
4461 tns
= WXS_ATTRUSE_DECL_TNS(use
);
4463 fprintf(output
, "'%s'\n",
4464 (const char *) xmlSchemaFormatQName(&str
, tns
, name
));
4470 * xmlSchemaTypeDump:
4471 * @output: the file output
4472 * @type: a type structure
4474 * Dump a SchemaType structure
4477 xmlSchemaTypeDump(xmlSchemaTypePtr type
, FILE * output
)
4480 fprintf(output
, "Type: NULL\n");
4483 fprintf(output
, "Type: ");
4484 if (type
->name
!= NULL
)
4485 fprintf(output
, "'%s' ", type
->name
);
4487 fprintf(output
, "(no name) ");
4488 if (type
->targetNamespace
!= NULL
)
4489 fprintf(output
, "ns '%s' ", type
->targetNamespace
);
4490 switch (type
->type
) {
4491 case XML_SCHEMA_TYPE_BASIC
:
4492 fprintf(output
, "[basic] ");
4494 case XML_SCHEMA_TYPE_SIMPLE
:
4495 fprintf(output
, "[simple] ");
4497 case XML_SCHEMA_TYPE_COMPLEX
:
4498 fprintf(output
, "[complex] ");
4500 case XML_SCHEMA_TYPE_SEQUENCE
:
4501 fprintf(output
, "[sequence] ");
4503 case XML_SCHEMA_TYPE_CHOICE
:
4504 fprintf(output
, "[choice] ");
4506 case XML_SCHEMA_TYPE_ALL
:
4507 fprintf(output
, "[all] ");
4509 case XML_SCHEMA_TYPE_UR
:
4510 fprintf(output
, "[ur] ");
4512 case XML_SCHEMA_TYPE_RESTRICTION
:
4513 fprintf(output
, "[restriction] ");
4515 case XML_SCHEMA_TYPE_EXTENSION
:
4516 fprintf(output
, "[extension] ");
4519 fprintf(output
, "[unknown type %d] ", type
->type
);
4522 fprintf(output
, "content: ");
4523 switch (type
->contentType
) {
4524 case XML_SCHEMA_CONTENT_UNKNOWN
:
4525 fprintf(output
, "[unknown] ");
4527 case XML_SCHEMA_CONTENT_EMPTY
:
4528 fprintf(output
, "[empty] ");
4530 case XML_SCHEMA_CONTENT_ELEMENTS
:
4531 fprintf(output
, "[element] ");
4533 case XML_SCHEMA_CONTENT_MIXED
:
4534 fprintf(output
, "[mixed] ");
4536 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS
:
4539 case XML_SCHEMA_CONTENT_BASIC
:
4540 fprintf(output
, "[basic] ");
4542 case XML_SCHEMA_CONTENT_SIMPLE
:
4543 fprintf(output
, "[simple] ");
4545 case XML_SCHEMA_CONTENT_ANY
:
4546 fprintf(output
, "[any] ");
4549 fprintf(output
, "\n");
4550 if (type
->base
!= NULL
) {
4551 fprintf(output
, " base type: '%s'", type
->base
);
4552 if (type
->baseNs
!= NULL
)
4553 fprintf(output
, " ns '%s'\n", type
->baseNs
);
4555 fprintf(output
, "\n");
4557 if (type
->attrUses
!= NULL
)
4558 xmlSchemaAttrUsesDump(type
->attrUses
, output
);
4559 if (type
->annot
!= NULL
)
4560 xmlSchemaAnnotDump(output
, type
->annot
);
4561 #ifdef DUMP_CONTENT_MODEL
4562 if ((type
->type
== XML_SCHEMA_TYPE_COMPLEX
) &&
4563 (type
->subtypes
!= NULL
)) {
4564 xmlSchemaContentModelDump((xmlSchemaParticlePtr
) type
->subtypes
,
4571 xmlSchemaTypeDumpEntry(void *type
, void *output
,
4572 const xmlChar
*name ATTRIBUTE_UNUSED
)
4574 xmlSchemaTypeDump((xmlSchemaTypePtr
) type
, (FILE *) output
);
4579 * @output: the file output
4580 * @schema: a schema structure
4582 * Dump a Schema structure.
4585 xmlSchemaDump(FILE * output
, xmlSchemaPtr schema
)
4589 if (schema
== NULL
) {
4590 fprintf(output
, "Schemas: NULL\n");
4593 fprintf(output
, "Schemas: ");
4594 if (schema
->name
!= NULL
)
4595 fprintf(output
, "%s, ", schema
->name
);
4597 fprintf(output
, "no name, ");
4598 if (schema
->targetNamespace
!= NULL
)
4599 fprintf(output
, "%s", (const char *) schema
->targetNamespace
);
4601 fprintf(output
, "no target namespace");
4602 fprintf(output
, "\n");
4603 if (schema
->annot
!= NULL
)
4604 xmlSchemaAnnotDump(output
, schema
->annot
);
4605 xmlHashScan(schema
->typeDecl
, xmlSchemaTypeDumpEntry
, output
);
4606 xmlHashScanFull(schema
->elemDecl
, xmlSchemaElementDump
, output
);
4609 #ifdef DEBUG_IDC_NODE_TABLE
4611 * xmlSchemaDebugDumpIDCTable:
4612 * @vctxt: the WXS validation context
4614 * Displays the current IDC table for debug purposes.
4617 xmlSchemaDebugDumpIDCTable(FILE * output
,
4618 const xmlChar
*namespaceName
,
4619 const xmlChar
*localName
,
4620 xmlSchemaPSVIIDCBindingPtr bind
)
4622 xmlChar
*str
= NULL
;
4623 const xmlChar
*value
;
4624 xmlSchemaPSVIIDCNodePtr tab
;
4625 xmlSchemaPSVIIDCKeyPtr key
;
4628 fprintf(output
, "IDC: TABLES on '%s'\n",
4629 xmlSchemaFormatQName(&str
, namespaceName
, localName
));
4635 fprintf(output
, "IDC: BINDING '%s' (%d)\n",
4636 xmlSchemaGetComponentQName(&str
,
4637 bind
->definition
), bind
->nbNodes
);
4639 for (i
= 0; i
< bind
->nbNodes
; i
++) {
4640 tab
= bind
->nodeTable
[i
];
4641 fprintf(output
, " ( ");
4642 for (j
= 0; j
< bind
->definition
->nbFields
; j
++) {
4644 if ((key
!= NULL
) && (key
->val
!= NULL
)) {
4645 res
= xmlSchemaGetCanonValue(key
->val
, &value
);
4647 fprintf(output
, "'%s' ", value
);
4649 fprintf(output
, "CANON-VALUE-FAILED ");
4651 FREE_AND_NULL(value
)
4652 } else if (key
!= NULL
)
4653 fprintf(output
, "(no val), ");
4655 fprintf(output
, "(key missing), ");
4657 fprintf(output
, ")\n");
4659 if (bind
->dupls
&& bind
->dupls
->nbItems
) {
4660 fprintf(output
, "IDC: dupls (%d):\n", bind
->dupls
->nbItems
);
4661 for (i
= 0; i
< bind
->dupls
->nbItems
; i
++) {
4662 tab
= bind
->dupls
->items
[i
];
4663 fprintf(output
, " ( ");
4664 for (j
= 0; j
< bind
->definition
->nbFields
; j
++) {
4666 if ((key
!= NULL
) && (key
->val
!= NULL
)) {
4667 res
= xmlSchemaGetCanonValue(key
->val
, &value
);
4669 fprintf(output
, "'%s' ", value
);
4671 fprintf(output
, "CANON-VALUE-FAILED ");
4673 FREE_AND_NULL(value
)
4674 } else if (key
!= NULL
)
4675 fprintf(output
, "(no val), ");
4677 fprintf(output
, "(key missing), ");
4679 fprintf(output
, ")\n");
4683 } while (bind
!= NULL
);
4685 #endif /* DEBUG_IDC */
4686 #endif /* LIBXML_OUTPUT_ENABLED */
4688 /************************************************************************
4692 ************************************************************************/
4695 * xmlSchemaGetPropNode:
4696 * @node: the element node
4697 * @name: the name of the attribute
4699 * Seeks an attribute with a name of @name in
4702 * Returns the attribute or NULL if not present.
4705 xmlSchemaGetPropNode(xmlNodePtr node
, const char *name
)
4709 if ((node
== NULL
) || (name
== NULL
))
4711 prop
= node
->properties
;
4712 while (prop
!= NULL
) {
4713 if ((prop
->ns
== NULL
) && xmlStrEqual(prop
->name
, BAD_CAST name
))
4721 * xmlSchemaGetPropNodeNs:
4722 * @node: the element node
4724 * @name: the name of the attribute
4726 * Seeks an attribute with a local name of @name and
4727 * a namespace URI of @uri.
4729 * Returns the attribute or NULL if not present.
4732 xmlSchemaGetPropNodeNs(xmlNodePtr node
, const char *uri
, const char *name
)
4736 if ((node
== NULL
) || (name
== NULL
))
4738 prop
= node
->properties
;
4739 while (prop
!= NULL
) {
4740 if ((prop
->ns
!= NULL
) &&
4741 xmlStrEqual(prop
->name
, BAD_CAST name
) &&
4742 xmlStrEqual(prop
->ns
->href
, BAD_CAST uri
))
4749 static const xmlChar
*
4750 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
)
4755 val
= xmlNodeGetContent(node
);
4757 val
= xmlStrdup((xmlChar
*)"");
4758 ret
= xmlDictLookup(ctxt
->dict
, val
, -1);
4763 static const xmlChar
*
4764 xmlSchemaGetNodeContentNoDict(xmlNodePtr node
)
4766 return((const xmlChar
*) xmlNodeGetContent(node
));
4771 * @ctxt: the parser context
4773 * @name: the property name
4775 * Read a attribute value and internalize the string
4777 * Returns the string or NULL if not present.
4779 static const xmlChar
*
4780 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
,
4786 val
= xmlGetNoNsProp(node
, BAD_CAST name
);
4789 ret
= xmlDictLookup(ctxt
->dict
, val
, -1);
4794 /************************************************************************
4796 * Parsing functions *
4798 ************************************************************************/
4800 #define WXS_FIND_GLOBAL_ITEM(slot) \
4801 if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4802 ret = xmlHashLookup(schema->slot, name); \
4803 if (ret != NULL) goto exit; \
4805 if (xmlHashSize(schema->schemasImports) > 1) { \
4806 xmlSchemaImportPtr import; \
4807 if (nsName == NULL) \
4808 import = xmlHashLookup(schema->schemasImports, \
4809 XML_SCHEMAS_NO_NAMESPACE); \
4811 import = xmlHashLookup(schema->schemasImports, nsName); \
4812 if (import == NULL) \
4814 ret = xmlHashLookup(import->schema->slot, name); \
4819 * @schema: the schema context
4820 * @name: the element name
4821 * @ns: the element namespace
4823 * Lookup a global element declaration in the schema.
4825 * Returns the element declaration or NULL if not found.
4827 static xmlSchemaElementPtr
4828 xmlSchemaGetElem(xmlSchemaPtr schema
, const xmlChar
* name
,
4829 const xmlChar
* nsName
)
4831 xmlSchemaElementPtr ret
= NULL
;
4833 if ((name
== NULL
) || (schema
== NULL
))
4835 if (schema
!= NULL
) {
4836 WXS_FIND_GLOBAL_ITEM(elemDecl
)
4842 fprintf(stderr
, "Unable to lookup element decl. %s", name
);
4844 fprintf(stderr
, "Unable to lookup element decl. %s:%s", name
,
4853 * @schema: the main schema
4854 * @name: the type's name
4855 * nsName: the type's namespace
4857 * Lookup a type in the schemas or the predefined types
4859 * Returns the group definition or NULL if not found.
4861 static xmlSchemaTypePtr
4862 xmlSchemaGetType(xmlSchemaPtr schema
, const xmlChar
* name
,
4863 const xmlChar
* nsName
)
4865 xmlSchemaTypePtr ret
= NULL
;
4869 /* First try the built-in types. */
4870 if ((nsName
!= NULL
) && xmlStrEqual(nsName
, xmlSchemaNs
)) {
4871 ret
= xmlSchemaGetPredefinedType(name
, nsName
);
4875 * Note that we try the parsed schemas as well here
4876 * since one might have parsed the S4S, which contain more
4877 * than the built-in types.
4878 * TODO: Can we optimize this?
4881 if (schema
!= NULL
) {
4882 WXS_FIND_GLOBAL_ITEM(typeDecl
)
4889 fprintf(stderr
, "Unable to lookup type %s", name
);
4891 fprintf(stderr
, "Unable to lookup type %s:%s", name
,
4899 * xmlSchemaGetAttributeDecl:
4900 * @schema: the context of the schema
4901 * @name: the name of the attribute
4902 * @ns: the target namespace of the attribute
4904 * Lookup a an attribute in the schema or imported schemas
4906 * Returns the attribute declaration or NULL if not found.
4908 static xmlSchemaAttributePtr
4909 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema
, const xmlChar
* name
,
4910 const xmlChar
* nsName
)
4912 xmlSchemaAttributePtr ret
= NULL
;
4914 if ((name
== NULL
) || (schema
== NULL
))
4916 if (schema
!= NULL
) {
4917 WXS_FIND_GLOBAL_ITEM(attrDecl
)
4923 fprintf(stderr
, "Unable to lookup attribute %s", name
);
4925 fprintf(stderr
, "Unable to lookup attribute %s:%s", name
,
4933 * xmlSchemaGetAttributeGroup:
4934 * @schema: the context of the schema
4935 * @name: the name of the attribute group
4936 * @ns: the target namespace of the attribute group
4938 * Lookup a an attribute group in the schema or imported schemas
4940 * Returns the attribute group definition or NULL if not found.
4942 static xmlSchemaAttributeGroupPtr
4943 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema
, const xmlChar
* name
,
4944 const xmlChar
* nsName
)
4946 xmlSchemaAttributeGroupPtr ret
= NULL
;
4948 if ((name
== NULL
) || (schema
== NULL
))
4950 if (schema
!= NULL
) {
4951 WXS_FIND_GLOBAL_ITEM(attrgrpDecl
)
4955 if ((ret != NULL) && (ret->redef != NULL)) {
4956 * Return the last redefinition. *
4963 fprintf(stderr
, "Unable to lookup attribute group %s", name
);
4965 fprintf(stderr
, "Unable to lookup attribute group %s:%s", name
,
4973 * xmlSchemaGetGroup:
4974 * @schema: the context of the schema
4975 * @name: the name of the group
4976 * @ns: the target namespace of the group
4978 * Lookup a group in the schema or imported schemas
4980 * Returns the group definition or NULL if not found.
4982 static xmlSchemaModelGroupDefPtr
4983 xmlSchemaGetGroup(xmlSchemaPtr schema
, const xmlChar
* name
,
4984 const xmlChar
* nsName
)
4986 xmlSchemaModelGroupDefPtr ret
= NULL
;
4988 if ((name
== NULL
) || (schema
== NULL
))
4990 if (schema
!= NULL
) {
4991 WXS_FIND_GLOBAL_ITEM(groupDecl
)
4998 fprintf(stderr
, "Unable to lookup group %s", name
);
5000 fprintf(stderr
, "Unable to lookup group %s:%s", name
,
5007 static xmlSchemaNotationPtr
5008 xmlSchemaGetNotation(xmlSchemaPtr schema
,
5009 const xmlChar
*name
,
5010 const xmlChar
*nsName
)
5012 xmlSchemaNotationPtr ret
= NULL
;
5014 if ((name
== NULL
) || (schema
== NULL
))
5016 if (schema
!= NULL
) {
5017 WXS_FIND_GLOBAL_ITEM(notaDecl
)
5023 static xmlSchemaIDCPtr
5024 xmlSchemaGetIDC(xmlSchemaPtr schema
,
5025 const xmlChar
*name
,
5026 const xmlChar
*nsName
)
5028 xmlSchemaIDCPtr ret
= NULL
;
5030 if ((name
== NULL
) || (schema
== NULL
))
5032 if (schema
!= NULL
) {
5033 WXS_FIND_GLOBAL_ITEM(idcDef
)
5040 * xmlSchemaGetNamedComponent:
5041 * @schema: the schema
5042 * @name: the name of the group
5043 * @ns: the target namespace of the group
5045 * Lookup a group in the schema or imported schemas
5047 * Returns the group definition or NULL if not found.
5049 static xmlSchemaBasicItemPtr
5050 xmlSchemaGetNamedComponent(xmlSchemaPtr schema
,
5051 xmlSchemaTypeType itemType
,
5052 const xmlChar
*name
,
5053 const xmlChar
*targetNs
)
5056 case XML_SCHEMA_TYPE_GROUP
:
5057 return ((xmlSchemaBasicItemPtr
) xmlSchemaGetGroup(schema
,
5059 case XML_SCHEMA_TYPE_ELEMENT
:
5060 return ((xmlSchemaBasicItemPtr
) xmlSchemaGetElem(schema
,
5068 /************************************************************************
5070 * Parsing functions *
5072 ************************************************************************/
5074 #define IS_BLANK_NODE(n) \
5075 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
5080 * @len: the length of the string or -1
5082 * Check if a string is ignorable
5084 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
5087 xmlSchemaIsBlank(xmlChar
* str
, int len
)
5093 if (!(IS_BLANK_CH(*str
)))
5097 } else while ((*str
!= 0) && (len
!= 0)) {
5098 if (!(IS_BLANK_CH(*str
)))
5107 #define WXS_COMP_NAME(c, t) ((t) (c))->name
5108 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
5110 * xmlSchemaFindRedefCompInGraph:
5111 * ATTENTION TODO: This uses pointer comp. for strings.
5113 static xmlSchemaBasicItemPtr
5114 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket
,
5115 xmlSchemaTypeType type
,
5116 const xmlChar
*name
,
5117 const xmlChar
*nsName
)
5119 xmlSchemaBasicItemPtr ret
;
5122 if ((bucket
== NULL
) || (name
== NULL
))
5124 if ((bucket
->globals
== NULL
) ||
5125 (bucket
->globals
->nbItems
== 0))
5128 * Search in global components.
5130 for (i
= 0; i
< bucket
->globals
->nbItems
; i
++) {
5131 ret
= bucket
->globals
->items
[i
];
5132 if (ret
->type
== type
) {
5134 case XML_SCHEMA_TYPE_COMPLEX
:
5135 case XML_SCHEMA_TYPE_SIMPLE
:
5136 if ((WXS_COMP_NAME(ret
, xmlSchemaTypePtr
) == name
) &&
5137 (WXS_COMP_TNS(ret
, xmlSchemaTypePtr
) ==
5143 case XML_SCHEMA_TYPE_GROUP
:
5144 if ((WXS_COMP_NAME(ret
,
5145 xmlSchemaModelGroupDefPtr
) == name
) &&
5147 xmlSchemaModelGroupDefPtr
) == nsName
))
5152 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
5153 if ((WXS_COMP_NAME(ret
,
5154 xmlSchemaAttributeGroupPtr
) == name
) &&
5156 xmlSchemaAttributeGroupPtr
) == nsName
))
5162 /* Should not be hit. */
5169 * Process imported/included schemas.
5171 if (bucket
->relations
!= NULL
) {
5172 xmlSchemaSchemaRelationPtr rel
= bucket
->relations
;
5175 * TODO: Marking the bucket will not avoid multiple searches
5176 * in the same schema, but avoids at least circularity.
5178 bucket
->flags
|= XML_SCHEMA_BUCKET_MARKED
;
5180 if ((rel
->bucket
!= NULL
) &&
5181 ((rel
->bucket
->flags
& XML_SCHEMA_BUCKET_MARKED
) == 0)) {
5182 ret
= xmlSchemaFindRedefCompInGraph(rel
->bucket
,
5183 type
, name
, nsName
);
5188 } while (rel
!= NULL
);
5189 bucket
->flags
^= XML_SCHEMA_BUCKET_MARKED
;
5195 * xmlSchemaAddNotation:
5196 * @ctxt: a schema parser context
5197 * @schema: the schema being built
5198 * @name: the item name
5200 * Add an XML schema annotation declaration
5201 * *WARNING* this interface is highly subject to change
5203 * Returns the new structure or NULL in case of error
5205 static xmlSchemaNotationPtr
5206 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
5207 const xmlChar
*name
, const xmlChar
*nsName
,
5208 xmlNodePtr node ATTRIBUTE_UNUSED
)
5210 xmlSchemaNotationPtr ret
= NULL
;
5212 if ((ctxt
== NULL
) || (schema
== NULL
) || (name
== NULL
))
5215 ret
= (xmlSchemaNotationPtr
) xmlMalloc(sizeof(xmlSchemaNotation
));
5217 xmlSchemaPErrMemory(ctxt
, "add annotation", NULL
);
5220 memset(ret
, 0, sizeof(xmlSchemaNotation
));
5221 ret
->type
= XML_SCHEMA_TYPE_NOTATION
;
5223 ret
->targetNamespace
= nsName
;
5224 /* TODO: do we need the node to be set?
5225 * ret->node = node;*/
5226 WXS_ADD_GLOBAL(ctxt
, ret
);
5231 * xmlSchemaAddAttribute:
5232 * @ctxt: a schema parser context
5233 * @schema: the schema being built
5234 * @name: the item name
5235 * @namespace: the namespace
5237 * Add an XML schema Attribute declaration
5238 * *WARNING* this interface is highly subject to change
5240 * Returns the new structure or NULL in case of error
5242 static xmlSchemaAttributePtr
5243 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
5244 const xmlChar
* name
, const xmlChar
* nsName
,
5245 xmlNodePtr node
, int topLevel
)
5247 xmlSchemaAttributePtr ret
= NULL
;
5249 if ((ctxt
== NULL
) || (schema
== NULL
))
5252 ret
= (xmlSchemaAttributePtr
) xmlMalloc(sizeof(xmlSchemaAttribute
));
5254 xmlSchemaPErrMemory(ctxt
, "allocating attribute", NULL
);
5257 memset(ret
, 0, sizeof(xmlSchemaAttribute
));
5258 ret
->type
= XML_SCHEMA_TYPE_ATTRIBUTE
;
5261 ret
->targetNamespace
= nsName
;
5264 WXS_ADD_GLOBAL(ctxt
, ret
);
5266 WXS_ADD_LOCAL(ctxt
, ret
);
5267 WXS_ADD_PENDING(ctxt
, ret
);
5272 * xmlSchemaAddAttributeUse:
5273 * @ctxt: a schema parser context
5274 * @schema: the schema being built
5275 * @name: the item name
5276 * @namespace: the namespace
5278 * Add an XML schema Attribute declaration
5279 * *WARNING* this interface is highly subject to change
5281 * Returns the new structure or NULL in case of error
5283 static xmlSchemaAttributeUsePtr
5284 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt
,
5287 xmlSchemaAttributeUsePtr ret
= NULL
;
5292 ret
= (xmlSchemaAttributeUsePtr
) xmlMalloc(sizeof(xmlSchemaAttributeUse
));
5294 xmlSchemaPErrMemory(pctxt
, "allocating attribute", NULL
);
5297 memset(ret
, 0, sizeof(xmlSchemaAttributeUse
));
5298 ret
->type
= XML_SCHEMA_TYPE_ATTRIBUTE_USE
;
5301 WXS_ADD_LOCAL(pctxt
, ret
);
5306 * xmlSchemaAddRedef:
5308 * Adds a redefinition information. This is used at a later stage to:
5309 * resolve references to the redefined components and to check constraints.
5311 static xmlSchemaRedefPtr
5312 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt
,
5313 xmlSchemaBucketPtr targetBucket
,
5315 const xmlChar
*refName
,
5316 const xmlChar
*refTargetNs
)
5318 xmlSchemaRedefPtr ret
;
5320 ret
= (xmlSchemaRedefPtr
)
5321 xmlMalloc(sizeof(xmlSchemaRedef
));
5323 xmlSchemaPErrMemory(pctxt
,
5324 "allocating redefinition info", NULL
);
5327 memset(ret
, 0, sizeof(xmlSchemaRedef
));
5329 ret
->targetBucket
= targetBucket
;
5330 ret
->refName
= refName
;
5331 ret
->refTargetNs
= refTargetNs
;
5332 if (WXS_CONSTRUCTOR(pctxt
)->redefs
== NULL
)
5333 WXS_CONSTRUCTOR(pctxt
)->redefs
= ret
;
5335 WXS_CONSTRUCTOR(pctxt
)->lastRedef
->next
= ret
;
5336 WXS_CONSTRUCTOR(pctxt
)->lastRedef
= ret
;
5342 * xmlSchemaAddAttributeGroupDefinition:
5343 * @ctxt: a schema parser context
5344 * @schema: the schema being built
5345 * @name: the item name
5346 * @nsName: the target namespace
5347 * @node: the corresponding node
5349 * Add an XML schema Attribute Group definition.
5351 * Returns the new structure or NULL in case of error
5353 static xmlSchemaAttributeGroupPtr
5354 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt
,
5355 xmlSchemaPtr schema ATTRIBUTE_UNUSED
,
5356 const xmlChar
*name
,
5357 const xmlChar
*nsName
,
5360 xmlSchemaAttributeGroupPtr ret
= NULL
;
5362 if ((pctxt
== NULL
) || (name
== NULL
))
5365 ret
= (xmlSchemaAttributeGroupPtr
)
5366 xmlMalloc(sizeof(xmlSchemaAttributeGroup
));
5368 xmlSchemaPErrMemory(pctxt
, "allocating attribute group", NULL
);
5371 memset(ret
, 0, sizeof(xmlSchemaAttributeGroup
));
5372 ret
->type
= XML_SCHEMA_TYPE_ATTRIBUTEGROUP
;
5374 ret
->targetNamespace
= nsName
;
5377 /* TODO: Remove the flag. */
5378 ret
->flags
|= XML_SCHEMAS_ATTRGROUP_GLOBAL
;
5379 if (pctxt
->isRedefine
) {
5380 pctxt
->redef
= xmlSchemaAddRedef(pctxt
, pctxt
->redefined
,
5382 if (pctxt
->redef
== NULL
) {
5386 pctxt
->redefCounter
= 0;
5388 WXS_ADD_GLOBAL(pctxt
, ret
);
5389 WXS_ADD_PENDING(pctxt
, ret
);
5394 * xmlSchemaAddElement:
5395 * @ctxt: a schema parser context
5396 * @schema: the schema being built
5397 * @name: the type name
5398 * @namespace: the type namespace
5400 * Add an XML schema Element declaration
5401 * *WARNING* this interface is highly subject to change
5403 * Returns the new structure or NULL in case of error
5405 static xmlSchemaElementPtr
5406 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt
,
5407 const xmlChar
* name
, const xmlChar
* nsName
,
5408 xmlNodePtr node
, int topLevel
)
5410 xmlSchemaElementPtr ret
= NULL
;
5412 if ((ctxt
== NULL
) || (name
== NULL
))
5415 ret
= (xmlSchemaElementPtr
) xmlMalloc(sizeof(xmlSchemaElement
));
5417 xmlSchemaPErrMemory(ctxt
, "allocating element", NULL
);
5420 memset(ret
, 0, sizeof(xmlSchemaElement
));
5421 ret
->type
= XML_SCHEMA_TYPE_ELEMENT
;
5423 ret
->targetNamespace
= nsName
;
5427 WXS_ADD_GLOBAL(ctxt
, ret
);
5429 WXS_ADD_LOCAL(ctxt
, ret
);
5430 WXS_ADD_PENDING(ctxt
, ret
);
5436 * @ctxt: a schema parser context
5437 * @schema: the schema being built
5438 * @name: the item name
5439 * @namespace: the namespace
5441 * Add an XML schema item
5442 * *WARNING* this interface is highly subject to change
5444 * Returns the new structure or NULL in case of error
5446 static xmlSchemaTypePtr
5447 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
5448 xmlSchemaTypeType type
,
5449 const xmlChar
* name
, const xmlChar
* nsName
,
5450 xmlNodePtr node
, int topLevel
)
5452 xmlSchemaTypePtr ret
= NULL
;
5454 if ((ctxt
== NULL
) || (schema
== NULL
))
5457 ret
= (xmlSchemaTypePtr
) xmlMalloc(sizeof(xmlSchemaType
));
5459 xmlSchemaPErrMemory(ctxt
, "allocating type", NULL
);
5462 memset(ret
, 0, sizeof(xmlSchemaType
));
5465 ret
->targetNamespace
= nsName
;
5468 if (ctxt
->isRedefine
) {
5469 ctxt
->redef
= xmlSchemaAddRedef(ctxt
, ctxt
->redefined
,
5471 if (ctxt
->redef
== NULL
) {
5475 ctxt
->redefCounter
= 0;
5477 WXS_ADD_GLOBAL(ctxt
, ret
);
5479 WXS_ADD_LOCAL(ctxt
, ret
);
5480 WXS_ADD_PENDING(ctxt
, ret
);
5484 static xmlSchemaQNameRefPtr
5485 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt
,
5486 xmlSchemaTypeType refType
,
5487 const xmlChar
*refName
,
5488 const xmlChar
*refNs
)
5490 xmlSchemaQNameRefPtr ret
;
5492 ret
= (xmlSchemaQNameRefPtr
)
5493 xmlMalloc(sizeof(xmlSchemaQNameRef
));
5495 xmlSchemaPErrMemory(pctxt
,
5496 "allocating QName reference item", NULL
);
5500 ret
->type
= XML_SCHEMA_EXTRA_QNAMEREF
;
5501 ret
->name
= refName
;
5502 ret
->targetNamespace
= refNs
;
5504 ret
->itemType
= refType
;
5506 * Store the reference item in the schema.
5508 WXS_ADD_LOCAL(pctxt
, ret
);
5512 static xmlSchemaAttributeUseProhibPtr
5513 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt
)
5515 xmlSchemaAttributeUseProhibPtr ret
;
5517 ret
= (xmlSchemaAttributeUseProhibPtr
)
5518 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib
));
5520 xmlSchemaPErrMemory(pctxt
,
5521 "allocating attribute use prohibition", NULL
);
5524 memset(ret
, 0, sizeof(xmlSchemaAttributeUseProhib
));
5525 ret
->type
= XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
;
5526 WXS_ADD_LOCAL(pctxt
, ret
);
5532 * xmlSchemaAddModelGroup:
5533 * @ctxt: a schema parser context
5534 * @schema: the schema being built
5535 * @type: the "compositor" type of the model group
5536 * @node: the node in the schema doc
5538 * Adds a schema model group
5539 * *WARNING* this interface is highly subject to change
5541 * Returns the new structure or NULL in case of error
5543 static xmlSchemaModelGroupPtr
5544 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt
,
5545 xmlSchemaPtr schema
,
5546 xmlSchemaTypeType type
,
5549 xmlSchemaModelGroupPtr ret
= NULL
;
5551 if ((ctxt
== NULL
) || (schema
== NULL
))
5554 ret
= (xmlSchemaModelGroupPtr
)
5555 xmlMalloc(sizeof(xmlSchemaModelGroup
));
5557 xmlSchemaPErrMemory(ctxt
, "allocating model group component",
5561 memset(ret
, 0, sizeof(xmlSchemaModelGroup
));
5564 WXS_ADD_LOCAL(ctxt
, ret
);
5565 if ((type
== XML_SCHEMA_TYPE_SEQUENCE
) ||
5566 (type
== XML_SCHEMA_TYPE_CHOICE
))
5567 WXS_ADD_PENDING(ctxt
, ret
);
5573 * xmlSchemaAddParticle:
5574 * @ctxt: a schema parser context
5575 * @schema: the schema being built
5576 * @node: the corresponding node in the schema doc
5577 * @min: the minOccurs
5578 * @max: the maxOccurs
5580 * Adds an XML schema particle component.
5581 * *WARNING* this interface is highly subject to change
5583 * Returns the new structure or NULL in case of error
5585 static xmlSchemaParticlePtr
5586 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt
,
5587 xmlNodePtr node
, int min
, int max
)
5589 xmlSchemaParticlePtr ret
= NULL
;
5594 fprintf(stderr
, "Adding particle component\n");
5596 ret
= (xmlSchemaParticlePtr
)
5597 xmlMalloc(sizeof(xmlSchemaParticle
));
5599 xmlSchemaPErrMemory(ctxt
, "allocating particle component",
5603 ret
->type
= XML_SCHEMA_TYPE_PARTICLE
;
5606 ret
->minOccurs
= min
;
5607 ret
->maxOccurs
= max
;
5609 ret
->children
= NULL
;
5611 WXS_ADD_LOCAL(ctxt
, ret
);
5613 * Note that addition to pending components will be done locally
5614 * to the specific parsing function, since the most particles
5615 * need not to be fixed up (i.e. the reference to be resolved).
5616 * REMOVED: WXS_ADD_PENDING(ctxt, ret);
5622 * xmlSchemaAddModelGroupDefinition:
5623 * @ctxt: a schema validation context
5624 * @schema: the schema being built
5625 * @name: the group name
5627 * Add an XML schema Group definition
5629 * Returns the new structure or NULL in case of error
5631 static xmlSchemaModelGroupDefPtr
5632 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt
,
5633 xmlSchemaPtr schema
,
5634 const xmlChar
*name
,
5635 const xmlChar
*nsName
,
5638 xmlSchemaModelGroupDefPtr ret
= NULL
;
5640 if ((ctxt
== NULL
) || (schema
== NULL
) || (name
== NULL
))
5643 ret
= (xmlSchemaModelGroupDefPtr
)
5644 xmlMalloc(sizeof(xmlSchemaModelGroupDef
));
5646 xmlSchemaPErrMemory(ctxt
, "adding group", NULL
);
5649 memset(ret
, 0, sizeof(xmlSchemaModelGroupDef
));
5651 ret
->type
= XML_SCHEMA_TYPE_GROUP
;
5653 ret
->targetNamespace
= nsName
;
5655 if (ctxt
->isRedefine
) {
5656 ctxt
->redef
= xmlSchemaAddRedef(ctxt
, ctxt
->redefined
,
5658 if (ctxt
->redef
== NULL
) {
5662 ctxt
->redefCounter
= 0;
5664 WXS_ADD_GLOBAL(ctxt
, ret
);
5665 WXS_ADD_PENDING(ctxt
, ret
);
5670 * xmlSchemaNewWildcardNs:
5671 * @ctxt: a schema validation context
5673 * Creates a new wildcard namespace constraint.
5675 * Returns the new structure or NULL in case of error
5677 static xmlSchemaWildcardNsPtr
5678 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt
)
5680 xmlSchemaWildcardNsPtr ret
;
5682 ret
= (xmlSchemaWildcardNsPtr
)
5683 xmlMalloc(sizeof(xmlSchemaWildcardNs
));
5685 xmlSchemaPErrMemory(ctxt
, "creating wildcard namespace constraint", NULL
);
5693 static xmlSchemaIDCPtr
5694 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
5695 const xmlChar
*name
, const xmlChar
*nsName
,
5696 int category
, xmlNodePtr node
)
5698 xmlSchemaIDCPtr ret
= NULL
;
5700 if ((ctxt
== NULL
) || (schema
== NULL
) || (name
== NULL
))
5703 ret
= (xmlSchemaIDCPtr
) xmlMalloc(sizeof(xmlSchemaIDC
));
5705 xmlSchemaPErrMemory(ctxt
,
5706 "allocating an identity-constraint definition", NULL
);
5709 memset(ret
, 0, sizeof(xmlSchemaIDC
));
5710 /* The target namespace of the parent element declaration. */
5711 ret
->targetNamespace
= nsName
;
5713 ret
->type
= category
;
5716 WXS_ADD_GLOBAL(ctxt
, ret
);
5718 * Only keyrefs need to be fixup up.
5720 if (category
== XML_SCHEMA_TYPE_IDC_KEYREF
)
5721 WXS_ADD_PENDING(ctxt
, ret
);
5726 * xmlSchemaAddWildcard:
5727 * @ctxt: a schema validation context
5731 * It corresponds to a xsd:anyAttribute and xsd:any.
5733 * Returns the new structure or NULL in case of error
5735 static xmlSchemaWildcardPtr
5736 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
5737 xmlSchemaTypeType type
, xmlNodePtr node
)
5739 xmlSchemaWildcardPtr ret
= NULL
;
5741 if ((ctxt
== NULL
) || (schema
== NULL
))
5744 ret
= (xmlSchemaWildcardPtr
) xmlMalloc(sizeof(xmlSchemaWildcard
));
5746 xmlSchemaPErrMemory(ctxt
, "adding wildcard", NULL
);
5749 memset(ret
, 0, sizeof(xmlSchemaWildcard
));
5752 WXS_ADD_LOCAL(ctxt
, ret
);
5757 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group
)
5761 if (group
->members
!= NULL
)
5762 xmlSchemaItemListFree(group
->members
);
5767 xmlSchemaSubstGroupFreeEntry(void *group
, const xmlChar
*name ATTRIBUTE_UNUSED
)
5769 xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr
) group
);
5772 static xmlSchemaSubstGroupPtr
5773 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt
,
5774 xmlSchemaElementPtr head
)
5776 xmlSchemaSubstGroupPtr ret
;
5778 /* Init subst group hash. */
5779 if (WXS_SUBST_GROUPS(pctxt
) == NULL
) {
5780 WXS_SUBST_GROUPS(pctxt
) = xmlHashCreateDict(10, pctxt
->dict
);
5781 if (WXS_SUBST_GROUPS(pctxt
) == NULL
)
5784 /* Create a new substitution group. */
5785 ret
= (xmlSchemaSubstGroupPtr
) xmlMalloc(sizeof(xmlSchemaSubstGroup
));
5787 xmlSchemaPErrMemory(NULL
,
5788 "allocating a substitution group container", NULL
);
5791 memset(ret
, 0, sizeof(xmlSchemaSubstGroup
));
5793 /* Create list of members. */
5794 ret
->members
= xmlSchemaItemListCreate();
5795 if (ret
->members
== NULL
) {
5796 xmlSchemaSubstGroupFree(ret
);
5799 /* Add subst group to hash. */
5800 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt
),
5801 head
->name
, head
->targetNamespace
, ret
) != 0) {
5802 PERROR_INT("xmlSchemaSubstGroupAdd",
5803 "failed to add a new substitution container");
5804 xmlSchemaSubstGroupFree(ret
);
5810 static xmlSchemaSubstGroupPtr
5811 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt
,
5812 xmlSchemaElementPtr head
)
5814 if (WXS_SUBST_GROUPS(pctxt
) == NULL
)
5816 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt
),
5817 head
->name
, head
->targetNamespace
));
5822 * xmlSchemaAddElementSubstitutionMember:
5823 * @pctxt: a schema parser context
5824 * @head: the head of the substitution group
5825 * @member: the new member of the substitution group
5827 * Allocate a new annotation structure.
5829 * Returns the newly allocated structure or NULL in case or error
5832 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt
,
5833 xmlSchemaElementPtr head
,
5834 xmlSchemaElementPtr member
)
5836 xmlSchemaSubstGroupPtr substGroup
= NULL
;
5838 if ((pctxt
== NULL
) || (head
== NULL
) || (member
== NULL
))
5841 substGroup
= xmlSchemaSubstGroupGet(pctxt
, head
);
5842 if (substGroup
== NULL
)
5843 substGroup
= xmlSchemaSubstGroupAdd(pctxt
, head
);
5844 if (substGroup
== NULL
)
5846 if (xmlSchemaItemListAdd(substGroup
->members
, member
) == -1)
5851 /************************************************************************
5853 * Utilities for parsing *
5855 ************************************************************************/
5858 * xmlSchemaPValAttrNodeQNameValue:
5859 * @ctxt: a schema parser context
5860 * @schema: the schema context
5861 * @ownerItem: the parent as a schema object
5862 * @value: the QName value
5863 * @uri: the resulting namespace URI if found
5864 * @local: the resulting local part if found, the attribute value otherwise
5866 * Extracts the local name and the URI of a QName value and validates it.
5867 * This one is intended to be used on attribute values that
5868 * should resolve to schema components.
5870 * Returns 0, in case the QName is valid, a positive error code
5871 * if not valid and -1 if an internal error occurs.
5874 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt
,
5875 xmlSchemaPtr schema
,
5876 xmlSchemaBasicItemPtr ownerItem
,
5878 const xmlChar
*value
,
5879 const xmlChar
**uri
,
5880 const xmlChar
**local
)
5882 const xmlChar
*pref
;
5888 ret
= xmlValidateQName(value
, 1);
5890 xmlSchemaPSimpleTypeErr(ctxt
,
5891 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
5892 ownerItem
, (xmlNodePtr
) attr
,
5893 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME
),
5894 NULL
, value
, NULL
, NULL
, NULL
);
5900 if (!strchr((char *) value
, ':')) {
5901 ns
= xmlSearchNs(attr
->doc
, attr
->parent
, NULL
);
5902 if (ns
&& ns
->href
&& ns
->href
[0])
5903 *uri
= xmlDictLookup(ctxt
->dict
, ns
->href
, -1);
5904 else if (schema
->flags
& XML_SCHEMAS_INCLUDING_CONVERT_NS
) {
5905 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
5906 * parser context. */
5908 * This one takes care of included schemas with no
5911 *uri
= ctxt
->targetNamespace
;
5913 *local
= xmlDictLookup(ctxt
->dict
, value
, -1);
5917 * At this point xmlSplitQName3 has to return a local name.
5919 *local
= xmlSplitQName3(value
, &len
);
5920 *local
= xmlDictLookup(ctxt
->dict
, *local
, -1);
5921 pref
= xmlDictLookup(ctxt
->dict
, value
, len
);
5922 ns
= xmlSearchNs(attr
->doc
, attr
->parent
, pref
);
5924 xmlSchemaPSimpleTypeErr(ctxt
,
5925 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
5926 ownerItem
, (xmlNodePtr
) attr
,
5927 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME
), NULL
, value
,
5928 "The value '%s' of simple type 'xs:QName' has no "
5929 "corresponding namespace declaration in scope", value
, NULL
);
5932 *uri
= xmlDictLookup(ctxt
->dict
, ns
->href
, -1);
5938 * xmlSchemaPValAttrNodeQName:
5939 * @ctxt: a schema parser context
5940 * @schema: the schema context
5941 * @ownerItem: the owner as a schema object
5942 * @attr: the attribute node
5943 * @uri: the resulting namespace URI if found
5944 * @local: the resulting local part if found, the attribute value otherwise
5946 * Extracts and validates the QName of an attribute value.
5947 * This one is intended to be used on attribute values that
5948 * should resolve to schema components.
5950 * Returns 0, in case the QName is valid, a positive error code
5951 * if not valid and -1 if an internal error occurs.
5954 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt
,
5955 xmlSchemaPtr schema
,
5956 xmlSchemaBasicItemPtr ownerItem
,
5958 const xmlChar
**uri
,
5959 const xmlChar
**local
)
5961 const xmlChar
*value
;
5963 value
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
5964 return (xmlSchemaPValAttrNodeQNameValue(ctxt
, schema
,
5965 ownerItem
, attr
, value
, uri
, local
));
5969 * xmlSchemaPValAttrQName:
5970 * @ctxt: a schema parser context
5971 * @schema: the schema context
5972 * @ownerItem: the owner as a schema object
5973 * @ownerElem: the parent node of the attribute
5974 * @name: the name of the attribute
5975 * @uri: the resulting namespace URI if found
5976 * @local: the resulting local part if found, the attribute value otherwise
5978 * Extracts and validates the QName of an attribute value.
5980 * Returns 0, in case the QName is valid, a positive error code
5981 * if not valid and -1 if an internal error occurs.
5984 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt
,
5985 xmlSchemaPtr schema
,
5986 xmlSchemaBasicItemPtr ownerItem
,
5987 xmlNodePtr ownerElem
,
5989 const xmlChar
**uri
,
5990 const xmlChar
**local
)
5994 attr
= xmlSchemaGetPropNode(ownerElem
, name
);
6000 return (xmlSchemaPValAttrNodeQName(ctxt
, schema
,
6001 ownerItem
, attr
, uri
, local
));
6005 * xmlSchemaPValAttrID:
6006 * @ctxt: a schema parser context
6008 * Extracts and validates the ID of an attribute value.
6010 * Returns 0, in case the ID is valid, a positive error code
6011 * if not valid and -1 if an internal error occurs.
6014 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt
, xmlAttrPtr attr
)
6017 const xmlChar
*value
;
6021 value
= xmlSchemaGetNodeContentNoDict((xmlNodePtr
) attr
);
6022 ret
= xmlValidateNCName(value
, 1);
6025 * NOTE: the IDness might have already be declared in the DTD
6027 if (attr
->atype
!= XML_ATTRIBUTE_ID
) {
6032 * TODO: Use xmlSchemaStrip here; it's not exported at this
6035 strip
= xmlSchemaCollapseString(value
);
6036 if (strip
!= NULL
) {
6037 xmlFree((xmlChar
*) value
);
6040 res
= xmlAddID(NULL
, attr
->doc
, value
, attr
);
6042 ret
= XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
;
6043 xmlSchemaPSimpleTypeErr(ctxt
,
6044 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6045 NULL
, (xmlNodePtr
) attr
,
6046 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID
),
6047 NULL
, NULL
, "Duplicate value '%s' of simple "
6048 "type 'xs:ID'", value
, NULL
);
6050 attr
->atype
= XML_ATTRIBUTE_ID
;
6052 } else if (ret
> 0) {
6053 ret
= XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
;
6054 xmlSchemaPSimpleTypeErr(ctxt
,
6055 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6056 NULL
, (xmlNodePtr
) attr
,
6057 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID
),
6058 NULL
, NULL
, "The value '%s' of simple type 'xs:ID' is "
6059 "not a valid 'xs:NCName'",
6063 xmlFree((xmlChar
*)value
);
6069 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt
,
6070 xmlNodePtr ownerElem
,
6071 const xmlChar
*name
)
6075 attr
= xmlSchemaGetPropNode(ownerElem
, (const char *) name
);
6078 return(xmlSchemaPValAttrNodeID(ctxt
, attr
));
6084 * @ctxt: a schema validation context
6085 * @node: a subtree containing XML Schema information
6087 * Get the maxOccurs property
6089 * Returns the default if not found, or the value
6092 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
,
6093 int min
, int max
, int def
, const char *expected
)
6095 const xmlChar
*val
, *cur
;
6099 attr
= xmlSchemaGetPropNode(node
, "maxOccurs");
6102 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
6104 if (xmlStrEqual(val
, (const xmlChar
*) "unbounded")) {
6105 if (max
!= UNBOUNDED
) {
6106 xmlSchemaPSimpleTypeErr(ctxt
,
6107 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6108 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6109 NULL
, (xmlNodePtr
) attr
, NULL
, expected
,
6110 val
, NULL
, NULL
, NULL
);
6113 return (UNBOUNDED
); /* encoding it with -1 might be another option */
6117 while (IS_BLANK_CH(*cur
))
6120 xmlSchemaPSimpleTypeErr(ctxt
,
6121 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6122 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6123 NULL
, (xmlNodePtr
) attr
, NULL
, expected
,
6124 val
, NULL
, NULL
, NULL
);
6127 while ((*cur
>= '0') && (*cur
<= '9')) {
6128 if (ret
> INT_MAX
/ 10) {
6131 int digit
= *cur
- '0';
6133 if (ret
> INT_MAX
- digit
)
6140 while (IS_BLANK_CH(*cur
))
6143 * TODO: Restrict the maximal value to Integer.
6145 if ((*cur
!= 0) || (ret
< min
) || ((max
!= -1) && (ret
> max
))) {
6146 xmlSchemaPSimpleTypeErr(ctxt
,
6147 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6148 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6149 NULL
, (xmlNodePtr
) attr
, NULL
, expected
,
6150 val
, NULL
, NULL
, NULL
);
6158 * @ctxt: a schema validation context
6159 * @node: a subtree containing XML Schema information
6161 * Get the minOccurs property
6163 * Returns the default if not found, or the value
6166 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
,
6167 int min
, int max
, int def
, const char *expected
)
6169 const xmlChar
*val
, *cur
;
6173 attr
= xmlSchemaGetPropNode(node
, "minOccurs");
6176 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
6178 while (IS_BLANK_CH(*cur
))
6181 xmlSchemaPSimpleTypeErr(ctxt
,
6182 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6183 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6184 NULL
, (xmlNodePtr
) attr
, NULL
, expected
,
6185 val
, NULL
, NULL
, NULL
);
6188 while ((*cur
>= '0') && (*cur
<= '9')) {
6189 if (ret
> INT_MAX
/ 10) {
6192 int digit
= *cur
- '0';
6194 if (ret
> INT_MAX
- digit
)
6201 while (IS_BLANK_CH(*cur
))
6204 * TODO: Restrict the maximal value to Integer.
6206 if ((*cur
!= 0) || (ret
< min
) || ((max
!= -1) && (ret
> max
))) {
6207 xmlSchemaPSimpleTypeErr(ctxt
,
6208 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6209 /* XML_SCHEMAP_INVALID_MINOCCURS, */
6210 NULL
, (xmlNodePtr
) attr
, NULL
, expected
,
6211 val
, NULL
, NULL
, NULL
);
6218 * xmlSchemaPGetBoolNodeValue:
6219 * @ctxt: a schema validation context
6220 * @ownerItem: the owner as a schema item
6221 * @node: the node holding the value
6223 * Converts a boolean string value into 1 or 0.
6228 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt
,
6229 xmlSchemaBasicItemPtr ownerItem
,
6232 xmlChar
*value
= NULL
;
6235 value
= xmlNodeGetContent(node
);
6237 * 3.2.2.1 Lexical representation
6238 * An instance of a datatype that is defined as `boolean`
6239 * can have the following legal literals {true, false, 1, 0}.
6241 if (xmlStrEqual(BAD_CAST value
, BAD_CAST
"true"))
6243 else if (xmlStrEqual(BAD_CAST value
, BAD_CAST
"false"))
6245 else if (xmlStrEqual(BAD_CAST value
, BAD_CAST
"1"))
6247 else if (xmlStrEqual(BAD_CAST value
, BAD_CAST
"0"))
6250 xmlSchemaPSimpleTypeErr(ctxt
,
6251 XML_SCHEMAP_INVALID_BOOLEAN
,
6253 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN
),
6254 NULL
, BAD_CAST value
,
6263 * xmlGetBooleanProp:
6264 * @ctxt: a schema validation context
6265 * @node: a subtree containing XML Schema information
6266 * @name: the attribute name
6267 * @def: the default value
6269 * Evaluate if a boolean property is set
6271 * Returns the default if not found, 0 if found to be false,
6272 * 1 if found to be true
6275 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt
,
6277 const char *name
, int def
)
6281 val
= xmlSchemaGetProp(ctxt
, node
, name
);
6285 * 3.2.2.1 Lexical representation
6286 * An instance of a datatype that is defined as `boolean`
6287 * can have the following legal literals {true, false, 1, 0}.
6289 if (xmlStrEqual(val
, BAD_CAST
"true"))
6291 else if (xmlStrEqual(val
, BAD_CAST
"false"))
6293 else if (xmlStrEqual(val
, BAD_CAST
"1"))
6295 else if (xmlStrEqual(val
, BAD_CAST
"0"))
6298 xmlSchemaPSimpleTypeErr(ctxt
,
6299 XML_SCHEMAP_INVALID_BOOLEAN
,
6301 (xmlNodePtr
) xmlSchemaGetPropNode(node
, name
),
6302 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN
),
6303 NULL
, val
, NULL
, NULL
, NULL
);
6308 /************************************************************************
6310 * Schema extraction from an Infoset *
6312 ************************************************************************/
6313 static xmlSchemaTypePtr
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
6314 ctxt
, xmlSchemaPtr schema
,
6317 static xmlSchemaTypePtr
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
6319 xmlSchemaPtr schema
,
6322 static xmlSchemaTypePtr
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
6324 xmlSchemaPtr schema
,
6326 xmlSchemaTypeType parentType
);
6327 static xmlSchemaBasicItemPtr
6328 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt
,
6329 xmlSchemaPtr schema
,
6331 xmlSchemaItemListPtr uses
,
6333 static xmlSchemaTypePtr
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt
,
6334 xmlSchemaPtr schema
,
6336 static xmlSchemaWildcardPtr
6337 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt
,
6338 xmlSchemaPtr schema
, xmlNodePtr node
);
6341 * xmlSchemaPValAttrNodeValue:
6343 * @pctxt: a schema parser context
6344 * @ownerItem: the schema object owner if existent
6345 * @attr: the schema attribute node being validated
6347 * @type: the built-in type to be validated against
6349 * Validates a value against the given built-in type.
6350 * This one is intended to be used internally for validation
6351 * of schema attribute values during parsing of the schema.
6353 * Returns 0 if the value is valid, a positive error code
6354 * number otherwise and -1 in case of an internal or API error.
6357 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt
,
6358 xmlSchemaBasicItemPtr ownerItem
,
6360 const xmlChar
*value
,
6361 xmlSchemaTypePtr type
)
6367 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
6368 * one is really meant to be used internally, so better not.
6370 if ((pctxt
== NULL
) || (type
== NULL
) || (attr
== NULL
))
6372 if (type
->type
!= XML_SCHEMA_TYPE_BASIC
) {
6373 PERROR_INT("xmlSchemaPValAttrNodeValue",
6374 "the given type is not a built-in type");
6377 switch (type
->builtInType
) {
6378 case XML_SCHEMAS_NCNAME
:
6379 case XML_SCHEMAS_QNAME
:
6380 case XML_SCHEMAS_ANYURI
:
6381 case XML_SCHEMAS_TOKEN
:
6382 case XML_SCHEMAS_LANGUAGE
:
6383 ret
= xmlSchemaValPredefTypeNode(type
, value
, NULL
,
6387 PERROR_INT("xmlSchemaPValAttrNodeValue",
6388 "validation using the given type is not supported while "
6389 "parsing a schema");
6394 * TODO: Should we use the S4S error codes instead?
6397 PERROR_INT("xmlSchemaPValAttrNodeValue",
6398 "failed to validate a schema attribute value");
6400 } else if (ret
> 0) {
6401 if (WXS_IS_LIST(type
))
6402 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2
;
6404 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
;
6405 xmlSchemaPSimpleTypeErr(pctxt
,
6406 ret
, ownerItem
, (xmlNodePtr
) attr
,
6407 type
, NULL
, value
, NULL
, NULL
, NULL
);
6413 * xmlSchemaPValAttrNode:
6415 * @ctxt: a schema parser context
6416 * @ownerItem: the schema object owner if existent
6417 * @attr: the schema attribute node being validated
6418 * @type: the built-in type to be validated against
6419 * @value: the resulting value if any
6421 * Extracts and validates a value against the given built-in type.
6422 * This one is intended to be used internally for validation
6423 * of schema attribute values during parsing of the schema.
6425 * Returns 0 if the value is valid, a positive error code
6426 * number otherwise and -1 in case of an internal or API error.
6429 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt
,
6430 xmlSchemaBasicItemPtr ownerItem
,
6432 xmlSchemaTypePtr type
,
6433 const xmlChar
**value
)
6437 if ((ctxt
== NULL
) || (type
== NULL
) || (attr
== NULL
))
6440 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
6444 return (xmlSchemaPValAttrNodeValue(ctxt
, ownerItem
, attr
,
6449 * xmlSchemaPValAttr:
6451 * @ctxt: a schema parser context
6452 * @node: the element node of the attribute
6453 * @ownerItem: the schema object owner if existent
6454 * @ownerElem: the owner element node
6455 * @name: the name of the schema attribute node
6456 * @type: the built-in type to be validated against
6457 * @value: the resulting value if any
6459 * Extracts and validates a value against the given built-in type.
6460 * This one is intended to be used internally for validation
6461 * of schema attribute values during parsing of the schema.
6463 * Returns 0 if the value is valid, a positive error code
6464 * number otherwise and -1 in case of an internal or API error.
6467 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt
,
6468 xmlSchemaBasicItemPtr ownerItem
,
6469 xmlNodePtr ownerElem
,
6471 xmlSchemaTypePtr type
,
6472 const xmlChar
**value
)
6476 if ((ctxt
== NULL
) || (type
== NULL
)) {
6481 if (type
->type
!= XML_SCHEMA_TYPE_BASIC
) {
6484 xmlSchemaPErr(ctxt
, ownerElem
,
6485 XML_SCHEMAP_INTERNAL
,
6486 "Internal error: xmlSchemaPValAttr, the given "
6487 "type '%s' is not a built-in type.\n",
6491 attr
= xmlSchemaGetPropNode(ownerElem
, name
);
6497 return (xmlSchemaPValAttrNode(ctxt
, ownerItem
, attr
,
6502 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt
,
6503 xmlSchemaPtr schema ATTRIBUTE_UNUSED
,
6506 const xmlChar
*namespaceName
)
6508 /* TODO: Pointer comparison instead? */
6509 if (xmlStrEqual(pctxt
->targetNamespace
, namespaceName
))
6511 if (xmlStrEqual(xmlSchemaNs
, namespaceName
))
6514 * Check if the referenced namespace was <import>ed.
6516 if (WXS_BUCKET(pctxt
)->relations
!= NULL
) {
6517 xmlSchemaSchemaRelationPtr rel
;
6519 rel
= WXS_BUCKET(pctxt
)->relations
;
6521 if (WXS_IS_BUCKET_IMPMAIN(rel
->type
) &&
6522 xmlStrEqual(namespaceName
, rel
->importNamespace
))
6525 } while (rel
!= NULL
);
6528 * No matching <import>ed namespace found.
6531 xmlNodePtr n
= (attr
!= NULL
) ? (xmlNodePtr
) attr
: node
;
6533 if (namespaceName
== NULL
)
6534 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
6535 XML_SCHEMAP_SRC_RESOLVE
, n
, NULL
,
6536 "References from this schema to components in no "
6537 "namespace are not allowed, since not indicated by an "
6538 "import statement", NULL
, NULL
);
6540 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
6541 XML_SCHEMAP_SRC_RESOLVE
, n
, NULL
,
6542 "References from this schema to components in the "
6543 "namespace '%s' are not allowed, since not indicated by an "
6544 "import statement", namespaceName
, NULL
);
6546 return (XML_SCHEMAP_SRC_RESOLVE
);
6550 * xmlSchemaParseLocalAttributes:
6551 * @ctxt: a schema validation context
6552 * @schema: the schema being built
6553 * @node: a subtree containing XML Schema information
6554 * @type: the hosting type where the attributes will be anchored
6556 * Parses attribute uses and attribute declarations and
6557 * attribute group references.
6560 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
6561 xmlNodePtr
*child
, xmlSchemaItemListPtr
*list
,
6562 int parentType
, int *hasRefs
)
6566 while ((IS_SCHEMA((*child
), "attribute")) ||
6567 (IS_SCHEMA((*child
), "attributeGroup"))) {
6568 if (IS_SCHEMA((*child
), "attribute")) {
6569 item
= xmlSchemaParseLocalAttribute(ctxt
, schema
, *child
,
6572 item
= xmlSchemaParseAttributeGroupRef(ctxt
, schema
, *child
);
6573 if ((item
!= NULL
) && (hasRefs
!= NULL
))
6577 if (*list
== NULL
) {
6578 /* TODO: Customize grow factor. */
6579 *list
= xmlSchemaItemListCreate();
6583 if (xmlSchemaItemListAddSize(*list
, 2, item
) == -1)
6586 *child
= (*child
)->next
;
6592 * xmlSchemaParseAnnotation:
6593 * @ctxt: a schema validation context
6594 * @schema: the schema being built
6595 * @node: a subtree containing XML Schema information
6597 * parse a XML schema Attribute declaration
6598 * *WARNING* this interface is highly subject to change
6600 * Returns -1 in case of error, 0 if the declaration is improper and
6601 * 1 in case of success.
6603 static xmlSchemaAnnotPtr
6604 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr node
, int needed
)
6606 xmlSchemaAnnotPtr ret
;
6607 xmlNodePtr child
= NULL
;
6612 * INFO: S4S completed.
6616 * {any attributes with non-schema namespace . . .}>
6617 * Content: (appinfo | documentation)*
6619 if ((ctxt
== NULL
) || (node
== NULL
))
6622 ret
= xmlSchemaNewAnnot(ctxt
, node
);
6625 attr
= node
->properties
;
6626 while (attr
!= NULL
) {
6627 if (((attr
->ns
== NULL
) &&
6628 (!xmlStrEqual(attr
->name
, BAD_CAST
"id"))) ||
6629 ((attr
->ns
!= NULL
) &&
6630 xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
))) {
6632 xmlSchemaPIllegalAttrErr(ctxt
,
6633 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
6637 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
6639 * And now for the children...
6641 child
= node
->children
;
6642 while (child
!= NULL
) {
6643 if (IS_SCHEMA(child
, "appinfo")) {
6644 /* TODO: make available the content of "appinfo". */
6647 * {any attributes with non-schema namespace . . .}>
6650 attr
= child
->properties
;
6651 while (attr
!= NULL
) {
6652 if (((attr
->ns
== NULL
) &&
6653 (!xmlStrEqual(attr
->name
, BAD_CAST
"source"))) ||
6654 ((attr
->ns
!= NULL
) &&
6655 xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
))) {
6657 xmlSchemaPIllegalAttrErr(ctxt
,
6658 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
6662 xmlSchemaPValAttr(ctxt
, NULL
, child
, "source",
6663 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
), NULL
);
6664 child
= child
->next
;
6665 } else if (IS_SCHEMA(child
, "documentation")) {
6666 /* TODO: make available the content of "documentation". */
6669 * {any attributes with non-schema namespace . . .}>
6672 attr
= child
->properties
;
6673 while (attr
!= NULL
) {
6674 if (attr
->ns
== NULL
) {
6675 if (!xmlStrEqual(attr
->name
, BAD_CAST
"source")) {
6676 xmlSchemaPIllegalAttrErr(ctxt
,
6677 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
6680 if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
) ||
6681 (xmlStrEqual(attr
->name
, BAD_CAST
"lang") &&
6682 (!xmlStrEqual(attr
->ns
->href
, XML_XML_NAMESPACE
)))) {
6684 xmlSchemaPIllegalAttrErr(ctxt
,
6685 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
6691 * Attribute "xml:lang".
6693 attr
= xmlSchemaGetPropNodeNs(child
, (const char *) XML_XML_NAMESPACE
, "lang");
6695 xmlSchemaPValAttrNode(ctxt
, NULL
, attr
,
6696 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE
), NULL
);
6697 child
= child
->next
;
6700 xmlSchemaPContentErr(ctxt
,
6701 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
6702 NULL
, node
, child
, NULL
, "(appinfo | documentation)*");
6704 child
= child
->next
;
6712 * xmlSchemaParseFacet:
6713 * @ctxt: a schema validation context
6714 * @schema: the schema being built
6715 * @node: a subtree containing XML Schema information
6717 * parse a XML schema Facet declaration
6718 * *WARNING* this interface is highly subject to change
6720 * Returns the new type structure or NULL in case of error
6722 static xmlSchemaFacetPtr
6723 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
6726 xmlSchemaFacetPtr facet
;
6727 xmlNodePtr child
= NULL
;
6728 const xmlChar
*value
;
6730 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
6733 facet
= xmlSchemaNewFacet();
6734 if (facet
== NULL
) {
6735 xmlSchemaPErrMemory(ctxt
, "allocating facet", node
);
6739 value
= xmlSchemaGetProp(ctxt
, node
, "value");
6740 if (value
== NULL
) {
6741 xmlSchemaPErr2(ctxt
, node
, child
, XML_SCHEMAP_FACET_NO_VALUE
,
6742 "Facet %s has no value\n", node
->name
, NULL
);
6743 xmlSchemaFreeFacet(facet
);
6746 if (IS_SCHEMA(node
, "minInclusive")) {
6747 facet
->type
= XML_SCHEMA_FACET_MININCLUSIVE
;
6748 } else if (IS_SCHEMA(node
, "minExclusive")) {
6749 facet
->type
= XML_SCHEMA_FACET_MINEXCLUSIVE
;
6750 } else if (IS_SCHEMA(node
, "maxInclusive")) {
6751 facet
->type
= XML_SCHEMA_FACET_MAXINCLUSIVE
;
6752 } else if (IS_SCHEMA(node
, "maxExclusive")) {
6753 facet
->type
= XML_SCHEMA_FACET_MAXEXCLUSIVE
;
6754 } else if (IS_SCHEMA(node
, "totalDigits")) {
6755 facet
->type
= XML_SCHEMA_FACET_TOTALDIGITS
;
6756 } else if (IS_SCHEMA(node
, "fractionDigits")) {
6757 facet
->type
= XML_SCHEMA_FACET_FRACTIONDIGITS
;
6758 } else if (IS_SCHEMA(node
, "pattern")) {
6759 facet
->type
= XML_SCHEMA_FACET_PATTERN
;
6760 } else if (IS_SCHEMA(node
, "enumeration")) {
6761 facet
->type
= XML_SCHEMA_FACET_ENUMERATION
;
6762 } else if (IS_SCHEMA(node
, "whiteSpace")) {
6763 facet
->type
= XML_SCHEMA_FACET_WHITESPACE
;
6764 } else if (IS_SCHEMA(node
, "length")) {
6765 facet
->type
= XML_SCHEMA_FACET_LENGTH
;
6766 } else if (IS_SCHEMA(node
, "maxLength")) {
6767 facet
->type
= XML_SCHEMA_FACET_MAXLENGTH
;
6768 } else if (IS_SCHEMA(node
, "minLength")) {
6769 facet
->type
= XML_SCHEMA_FACET_MINLENGTH
;
6771 xmlSchemaPErr2(ctxt
, node
, child
, XML_SCHEMAP_UNKNOWN_FACET_TYPE
,
6772 "Unknown facet type %s\n", node
->name
, NULL
);
6773 xmlSchemaFreeFacet(facet
);
6776 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
6777 facet
->value
= value
;
6778 if ((facet
->type
!= XML_SCHEMA_FACET_PATTERN
) &&
6779 (facet
->type
!= XML_SCHEMA_FACET_ENUMERATION
)) {
6780 const xmlChar
*fixed
;
6782 fixed
= xmlSchemaGetProp(ctxt
, node
, "fixed");
6783 if (fixed
!= NULL
) {
6784 if (xmlStrEqual(fixed
, BAD_CAST
"true"))
6788 child
= node
->children
;
6790 if (IS_SCHEMA(child
, "annotation")) {
6791 facet
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
6792 child
= child
->next
;
6794 if (child
!= NULL
) {
6795 xmlSchemaPErr2(ctxt
, node
, child
, XML_SCHEMAP_UNKNOWN_FACET_CHILD
,
6796 "Facet %s has unexpected child content\n",
6803 * xmlSchemaParseWildcardNs:
6804 * @ctxt: a schema parser context
6805 * @wildc: the wildcard, already created
6806 * @node: a subtree containing XML Schema information
6808 * Parses the attribute "processContents" and "namespace"
6809 * of a xsd:anyAttribute and xsd:any.
6810 * *WARNING* this interface is highly subject to change
6812 * Returns 0 if everything goes fine, a positive error code
6813 * if something is not valid and -1 if an internal error occurs.
6816 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt
,
6817 xmlSchemaPtr schema ATTRIBUTE_UNUSED
,
6818 xmlSchemaWildcardPtr wildc
,
6821 const xmlChar
*pc
, *ns
, *dictnsItem
;
6824 xmlSchemaWildcardNsPtr tmp
, lastNs
= NULL
;
6827 pc
= xmlSchemaGetProp(ctxt
, node
, "processContents");
6829 || (xmlStrEqual(pc
, (const xmlChar
*) "strict"))) {
6830 wildc
->processContents
= XML_SCHEMAS_ANY_STRICT
;
6831 } else if (xmlStrEqual(pc
, (const xmlChar
*) "skip")) {
6832 wildc
->processContents
= XML_SCHEMAS_ANY_SKIP
;
6833 } else if (xmlStrEqual(pc
, (const xmlChar
*) "lax")) {
6834 wildc
->processContents
= XML_SCHEMAS_ANY_LAX
;
6836 xmlSchemaPSimpleTypeErr(ctxt
,
6837 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
6839 NULL
, "(strict | skip | lax)", pc
,
6841 wildc
->processContents
= XML_SCHEMAS_ANY_STRICT
;
6842 ret
= XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
;
6845 * Build the namespace constraints.
6847 attr
= xmlSchemaGetPropNode(node
, "namespace");
6848 ns
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
6849 if ((attr
== NULL
) || (xmlStrEqual(ns
, BAD_CAST
"##any")))
6851 else if (xmlStrEqual(ns
, BAD_CAST
"##other")) {
6852 wildc
->negNsSet
= xmlSchemaNewWildcardNsConstraint(ctxt
);
6853 if (wildc
->negNsSet
== NULL
) {
6856 wildc
->negNsSet
->value
= ctxt
->targetNamespace
;
6858 const xmlChar
*end
, *cur
;
6862 while (IS_BLANK_CH(*cur
))
6865 while ((*end
!= 0) && (!(IS_BLANK_CH(*end
))))
6869 nsItem
= xmlStrndup(cur
, end
- cur
);
6870 if ((xmlStrEqual(nsItem
, BAD_CAST
"##other")) ||
6871 (xmlStrEqual(nsItem
, BAD_CAST
"##any"))) {
6872 xmlSchemaPSimpleTypeErr(ctxt
,
6873 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER
,
6874 NULL
, (xmlNodePtr
) attr
,
6876 "((##any | ##other) | List of (xs:anyURI | "
6877 "(##targetNamespace | ##local)))",
6878 nsItem
, NULL
, NULL
, NULL
);
6879 ret
= XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER
;
6881 if (xmlStrEqual(nsItem
, BAD_CAST
"##targetNamespace")) {
6882 dictnsItem
= ctxt
->targetNamespace
;
6883 } else if (xmlStrEqual(nsItem
, BAD_CAST
"##local")) {
6887 * Validate the item (anyURI).
6889 xmlSchemaPValAttrNodeValue(ctxt
, NULL
, attr
,
6890 nsItem
, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
));
6891 dictnsItem
= xmlDictLookup(ctxt
->dict
, nsItem
, -1);
6894 * Avoid duplicate namespaces.
6897 while (tmp
!= NULL
) {
6898 if (dictnsItem
== tmp
->value
)
6903 tmp
= xmlSchemaNewWildcardNsConstraint(ctxt
);
6908 tmp
->value
= dictnsItem
;
6910 if (wildc
->nsSet
== NULL
)
6912 else if (lastNs
!= NULL
)
6920 } while (*cur
!= 0);
6926 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt
,
6927 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED
,
6932 if ((maxOccurs
== 0) && ( minOccurs
== 0))
6934 if (maxOccurs
!= UNBOUNDED
) {
6936 * TODO: Maybe we should better not create the particle,
6937 * if min/max is invalid, since it could confuse the build of the
6941 * 3.9.6 Schema Component Constraint: Particle Correct
6944 if (maxOccurs
< 1) {
6946 * 2.2 {max occurs} must be greater than or equal to 1.
6948 xmlSchemaPCustomAttrErr(ctxt
,
6949 XML_SCHEMAP_P_PROPS_CORRECT_2_2
,
6951 xmlSchemaGetPropNode(node
, "maxOccurs"),
6952 "The value must be greater than or equal to 1");
6953 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2
);
6954 } else if (minOccurs
> maxOccurs
) {
6956 * 2.1 {min occurs} must not be greater than {max occurs}.
6958 xmlSchemaPCustomAttrErr(ctxt
,
6959 XML_SCHEMAP_P_PROPS_CORRECT_2_1
,
6961 xmlSchemaGetPropNode(node
, "minOccurs"),
6962 "The value must not be greater than the value of 'maxOccurs'");
6963 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1
);
6970 * xmlSchemaParseAny:
6971 * @ctxt: a schema validation context
6972 * @schema: the schema being built
6973 * @node: a subtree containing XML Schema information
6975 * Parsea a XML schema <any> element. A particle and wildcard
6976 * will be created (except if minOccurs==maxOccurs==0, in this case
6977 * nothing will be created).
6978 * *WARNING* this interface is highly subject to change
6980 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
6982 static xmlSchemaParticlePtr
6983 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
6986 xmlSchemaParticlePtr particle
;
6987 xmlNodePtr child
= NULL
;
6988 xmlSchemaWildcardPtr wild
;
6991 xmlSchemaAnnotPtr annot
= NULL
;
6993 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
6996 * Check for illegal attributes.
6998 attr
= node
->properties
;
6999 while (attr
!= NULL
) {
7000 if (attr
->ns
== NULL
) {
7001 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
7002 (!xmlStrEqual(attr
->name
, BAD_CAST
"minOccurs")) &&
7003 (!xmlStrEqual(attr
->name
, BAD_CAST
"maxOccurs")) &&
7004 (!xmlStrEqual(attr
->name
, BAD_CAST
"namespace")) &&
7005 (!xmlStrEqual(attr
->name
, BAD_CAST
"processContents"))) {
7006 xmlSchemaPIllegalAttrErr(ctxt
,
7007 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7009 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
7010 xmlSchemaPIllegalAttrErr(ctxt
,
7011 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7015 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
7017 * minOccurs/maxOccurs.
7019 max
= xmlGetMaxOccurs(ctxt
, node
, 0, UNBOUNDED
, 1,
7020 "(xs:nonNegativeInteger | unbounded)");
7021 min
= xmlGetMinOccurs(ctxt
, node
, 0, -1, 1,
7022 "xs:nonNegativeInteger");
7023 xmlSchemaPCheckParticleCorrect_2(ctxt
, NULL
, node
, min
, max
);
7025 * Create & parse the wildcard.
7027 wild
= xmlSchemaAddWildcard(ctxt
, schema
, XML_SCHEMA_TYPE_ANY
, node
);
7030 xmlSchemaParseWildcardNs(ctxt
, schema
, wild
, node
);
7032 * And now for the children...
7034 child
= node
->children
;
7035 if (IS_SCHEMA(child
, "annotation")) {
7036 annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
7037 child
= child
->next
;
7039 if (child
!= NULL
) {
7040 xmlSchemaPContentErr(ctxt
,
7041 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7043 NULL
, "(annotation?)");
7046 * No component if minOccurs==maxOccurs==0.
7048 if ((min
== 0) && (max
== 0)) {
7049 /* Don't free the wildcard, since it's already on the list. */
7053 * Create the particle.
7055 particle
= xmlSchemaAddParticle(ctxt
, node
, min
, max
);
7056 if (particle
== NULL
)
7058 particle
->annot
= annot
;
7059 particle
->children
= (xmlSchemaTreeItemPtr
) wild
;
7065 * xmlSchemaParseNotation:
7066 * @ctxt: a schema validation context
7067 * @schema: the schema being built
7068 * @node: a subtree containing XML Schema information
7070 * parse a XML schema Notation declaration
7072 * Returns the new structure or NULL in case of error
7074 static xmlSchemaNotationPtr
7075 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
7078 const xmlChar
*name
;
7079 xmlSchemaNotationPtr ret
;
7080 xmlNodePtr child
= NULL
;
7082 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
7084 name
= xmlSchemaGetProp(ctxt
, node
, "name");
7086 xmlSchemaPErr2(ctxt
, node
, child
, XML_SCHEMAP_NOTATION_NO_NAME
,
7087 "Notation has no name\n", NULL
, NULL
);
7090 ret
= xmlSchemaAddNotation(ctxt
, schema
, name
,
7091 ctxt
->targetNamespace
, node
);
7094 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
7096 child
= node
->children
;
7097 if (IS_SCHEMA(child
, "annotation")) {
7098 ret
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
7099 child
= child
->next
;
7101 if (child
!= NULL
) {
7102 xmlSchemaPContentErr(ctxt
,
7103 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7105 NULL
, "(annotation?)");
7112 * xmlSchemaParseAnyAttribute:
7113 * @ctxt: a schema validation context
7114 * @schema: the schema being built
7115 * @node: a subtree containing XML Schema information
7117 * parse a XML schema AnyAttribute declaration
7118 * *WARNING* this interface is highly subject to change
7120 * Returns a wildcard or NULL.
7122 static xmlSchemaWildcardPtr
7123 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt
,
7124 xmlSchemaPtr schema
, xmlNodePtr node
)
7126 xmlSchemaWildcardPtr ret
;
7127 xmlNodePtr child
= NULL
;
7130 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
7133 ret
= xmlSchemaAddWildcard(ctxt
, schema
, XML_SCHEMA_TYPE_ANY_ATTRIBUTE
,
7139 * Check for illegal attributes.
7141 attr
= node
->properties
;
7142 while (attr
!= NULL
) {
7143 if (attr
->ns
== NULL
) {
7144 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
7145 (!xmlStrEqual(attr
->name
, BAD_CAST
"namespace")) &&
7146 (!xmlStrEqual(attr
->name
, BAD_CAST
"processContents"))) {
7147 xmlSchemaPIllegalAttrErr(ctxt
,
7148 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7150 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
7151 xmlSchemaPIllegalAttrErr(ctxt
,
7152 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7156 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
7158 * Parse the namespace list.
7160 if (xmlSchemaParseWildcardNs(ctxt
, schema
, ret
, node
) != 0)
7163 * And now for the children...
7165 child
= node
->children
;
7166 if (IS_SCHEMA(child
, "annotation")) {
7167 ret
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
7168 child
= child
->next
;
7170 if (child
!= NULL
) {
7171 xmlSchemaPContentErr(ctxt
,
7172 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7174 NULL
, "(annotation?)");
7182 * xmlSchemaParseAttribute:
7183 * @ctxt: a schema validation context
7184 * @schema: the schema being built
7185 * @node: a subtree containing XML Schema information
7187 * parse a XML schema Attribute declaration
7188 * *WARNING* this interface is highly subject to change
7190 * Returns the attribute declaration.
7192 static xmlSchemaBasicItemPtr
7193 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt
,
7194 xmlSchemaPtr schema
,
7196 xmlSchemaItemListPtr uses
,
7199 const xmlChar
*attrValue
, *name
= NULL
, *ns
= NULL
;
7200 xmlSchemaAttributeUsePtr use
= NULL
;
7201 xmlNodePtr child
= NULL
;
7203 const xmlChar
*tmpNs
= NULL
, *tmpName
= NULL
, *defValue
= NULL
;
7204 int isRef
= 0, occurs
= XML_SCHEMAS_ATTR_USE_OPTIONAL
;
7205 int nberrors
, hasForm
= 0, defValueType
= 0;
7207 #define WXS_ATTR_DEF_VAL_DEFAULT 1
7208 #define WXS_ATTR_DEF_VAL_FIXED 2
7211 * 3.2.3 Constraints on XML Representations of Attribute Declarations
7214 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
7216 attr
= xmlSchemaGetPropNode(node
, "ref");
7218 if (xmlSchemaPValAttrNodeQName(pctxt
, schema
,
7219 NULL
, attr
, &tmpNs
, &tmpName
) != 0) {
7222 if (xmlSchemaCheckReference(pctxt
, schema
, node
, attr
, tmpNs
) != 0)
7226 nberrors
= pctxt
->nberrors
;
7228 * Check for illegal attributes.
7230 attr
= node
->properties
;
7231 while (attr
!= NULL
) {
7232 if (attr
->ns
== NULL
) {
7234 if (xmlStrEqual(attr
->name
, BAD_CAST
"id")) {
7235 xmlSchemaPValAttrNodeID(pctxt
, attr
);
7237 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"ref")) {
7241 if (xmlStrEqual(attr
->name
, BAD_CAST
"name")) {
7243 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"id")) {
7244 xmlSchemaPValAttrNodeID(pctxt
, attr
);
7246 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"type")) {
7247 xmlSchemaPValAttrNodeQName(pctxt
, schema
, NULL
,
7248 attr
, &tmpNs
, &tmpName
);
7250 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"form")) {
7252 * Evaluate the target namespace
7255 attrValue
= xmlSchemaGetNodeContent(pctxt
,
7257 if (xmlStrEqual(attrValue
, BAD_CAST
"qualified")) {
7258 ns
= pctxt
->targetNamespace
;
7259 } else if (!xmlStrEqual(attrValue
, BAD_CAST
"unqualified"))
7261 xmlSchemaPSimpleTypeErr(pctxt
,
7262 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
7263 NULL
, (xmlNodePtr
) attr
,
7264 NULL
, "(qualified | unqualified)",
7265 attrValue
, NULL
, NULL
, NULL
);
7270 if (xmlStrEqual(attr
->name
, BAD_CAST
"use")) {
7272 attrValue
= xmlSchemaGetNodeContent(pctxt
, (xmlNodePtr
) attr
);
7273 /* TODO: Maybe we need to normalize the value beforehand. */
7274 if (xmlStrEqual(attrValue
, BAD_CAST
"optional"))
7275 occurs
= XML_SCHEMAS_ATTR_USE_OPTIONAL
;
7276 else if (xmlStrEqual(attrValue
, BAD_CAST
"prohibited"))
7277 occurs
= XML_SCHEMAS_ATTR_USE_PROHIBITED
;
7278 else if (xmlStrEqual(attrValue
, BAD_CAST
"required"))
7279 occurs
= XML_SCHEMAS_ATTR_USE_REQUIRED
;
7281 xmlSchemaPSimpleTypeErr(pctxt
,
7282 XML_SCHEMAP_INVALID_ATTR_USE
,
7283 NULL
, (xmlNodePtr
) attr
,
7284 NULL
, "(optional | prohibited | required)",
7285 attrValue
, NULL
, NULL
, NULL
);
7288 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"default")) {
7291 * default and fixed must not both be present.
7294 xmlSchemaPMutualExclAttrErr(pctxt
,
7295 XML_SCHEMAP_SRC_ATTRIBUTE_1
,
7296 NULL
, attr
, "default", "fixed");
7298 defValue
= xmlSchemaGetNodeContent(pctxt
, (xmlNodePtr
) attr
);
7299 defValueType
= WXS_ATTR_DEF_VAL_DEFAULT
;
7302 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"fixed")) {
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_FIXED
;
7317 } else if (! xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
))
7320 xmlSchemaPIllegalAttrErr(pctxt
,
7321 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7328 * If default and use are both present, use must have
7329 * the actual value optional.
7331 if ((defValueType
== WXS_ATTR_DEF_VAL_DEFAULT
) &&
7332 (occurs
!= XML_SCHEMAS_ATTR_USE_OPTIONAL
)) {
7333 xmlSchemaPSimpleTypeErr(pctxt
,
7334 XML_SCHEMAP_SRC_ATTRIBUTE_2
,
7336 "(optional | prohibited | required)", NULL
,
7337 "The value of the attribute 'use' must be 'optional' "
7338 "if the attribute 'default' is present",
7342 * We want correct attributes.
7344 if (nberrors
!= pctxt
->nberrors
)
7347 xmlSchemaAttributePtr attrDecl
;
7349 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
7350 if ((! hasForm
) && (schema
->flags
& XML_SCHEMAS_QUALIF_ATTR
))
7351 ns
= pctxt
->targetNamespace
;
7353 * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7354 * TODO: Move this to the component layer.
7356 if (xmlStrEqual(ns
, xmlSchemaInstanceNs
)) {
7357 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
7360 "The target namespace must not match '%s'",
7361 xmlSchemaInstanceNs
, NULL
);
7363 attr
= xmlSchemaGetPropNode(node
, "name");
7365 xmlSchemaPMissingAttrErr(pctxt
, XML_SCHEMAP_S4S_ATTR_MISSING
,
7366 NULL
, node
, "name", NULL
);
7369 if (xmlSchemaPValAttrNode(pctxt
, NULL
, attr
,
7370 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &name
) != 0) {
7374 * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7375 * TODO: Move this to the component layer.
7377 if (xmlStrEqual(name
, BAD_CAST
"xmlns")) {
7378 xmlSchemaPSimpleTypeErr(pctxt
,
7379 XML_SCHEMAP_NO_XMLNS
,
7380 NULL
, (xmlNodePtr
) attr
,
7381 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), NULL
, NULL
,
7382 "The value of the attribute must not match 'xmlns'",
7386 if (occurs
== XML_SCHEMAS_ATTR_USE_PROHIBITED
)
7387 goto check_children
;
7389 * Create the attribute use component.
7391 use
= xmlSchemaAddAttributeUse(pctxt
, node
);
7394 use
->occurs
= occurs
;
7396 * Create the attribute declaration.
7398 attrDecl
= xmlSchemaAddAttribute(pctxt
, schema
, name
, ns
, node
, 0);
7399 if (attrDecl
== NULL
)
7401 if (tmpName
!= NULL
) {
7402 attrDecl
->typeName
= tmpName
;
7403 attrDecl
->typeNs
= tmpNs
;
7405 use
->attrDecl
= attrDecl
;
7409 if (defValue
!= NULL
) {
7410 attrDecl
->defValue
= defValue
;
7411 if (defValueType
== WXS_ATTR_DEF_VAL_FIXED
)
7412 attrDecl
->flags
|= XML_SCHEMAS_ATTR_FIXED
;
7414 } else if (occurs
!= XML_SCHEMAS_ATTR_USE_PROHIBITED
) {
7415 xmlSchemaQNameRefPtr ref
;
7418 * Create the attribute use component.
7420 use
= xmlSchemaAddAttributeUse(pctxt
, node
);
7424 * We need to resolve the reference at later stage.
7426 WXS_ADD_PENDING(pctxt
, use
);
7427 use
->occurs
= occurs
;
7429 * Create a QName reference to the attribute declaration.
7431 ref
= xmlSchemaNewQNameRef(pctxt
, XML_SCHEMA_TYPE_ATTRIBUTE
,
7436 * Assign the reference. This will be substituted for the
7437 * referenced attribute declaration when the QName is resolved.
7439 use
->attrDecl
= WXS_ATTR_CAST ref
;
7443 if (defValue
!= NULL
)
7444 use
->defValue
= defValue
;
7445 if (defValueType
== WXS_ATTR_DEF_VAL_FIXED
)
7446 use
->flags
|= XML_SCHEMA_ATTR_USE_FIXED
;
7451 * And now for the children...
7453 child
= node
->children
;
7454 if (occurs
== XML_SCHEMAS_ATTR_USE_PROHIBITED
) {
7455 xmlSchemaAttributeUseProhibPtr prohib
;
7457 if (IS_SCHEMA(child
, "annotation")) {
7458 xmlSchemaParseAnnotation(pctxt
, child
, 0);
7459 child
= child
->next
;
7461 if (child
!= NULL
) {
7462 xmlSchemaPContentErr(pctxt
,
7463 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7464 NULL
, node
, child
, NULL
,
7468 * Check for pointlessness of attribute prohibitions.
7470 if (parentType
== XML_SCHEMA_TYPE_ATTRIBUTEGROUP
) {
7471 xmlSchemaCustomWarning(ACTXT_CAST pctxt
,
7472 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH
,
7474 "Skipping attribute use prohibition, since it is "
7475 "pointless inside an <attributeGroup>",
7478 } else if (parentType
== XML_SCHEMA_TYPE_EXTENSION
) {
7479 xmlSchemaCustomWarning(ACTXT_CAST pctxt
,
7480 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH
,
7482 "Skipping attribute use prohibition, since it is "
7483 "pointless when extending a type",
7492 * Check for duplicate attribute prohibitions.
7497 for (i
= 0; i
< uses
->nbItems
; i
++) {
7498 use
= uses
->items
[i
];
7499 if ((use
->type
== XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
) &&
7500 (tmpName
== (WXS_ATTR_PROHIB_CAST use
)->name
) &&
7501 (tmpNs
== (WXS_ATTR_PROHIB_CAST use
)->targetNamespace
))
7503 xmlChar
*str
= NULL
;
7505 xmlSchemaCustomWarning(ACTXT_CAST pctxt
,
7506 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH
,
7508 "Skipping duplicate attribute use prohibition '%s'",
7509 xmlSchemaFormatQName(&str
, tmpNs
, tmpName
),
7517 * Create the attribute prohibition helper component.
7519 prohib
= xmlSchemaAddAttributeUseProhib(pctxt
);
7522 prohib
->node
= node
;
7523 prohib
->name
= tmpName
;
7524 prohib
->targetNamespace
= tmpNs
;
7527 * We need at least to resolve to the attribute declaration.
7529 WXS_ADD_PENDING(pctxt
, prohib
);
7531 return(WXS_BASIC_CAST prohib
);
7533 if (IS_SCHEMA(child
, "annotation")) {
7535 * TODO: Should this go into the attr decl?
7537 use
->annot
= xmlSchemaParseAnnotation(pctxt
, child
, 1);
7538 child
= child
->next
;
7541 if (child
!= NULL
) {
7542 if (IS_SCHEMA(child
, "simpleType"))
7545 * If ref is present, then all of <simpleType>,
7546 * form and type must be absent.
7548 xmlSchemaPContentErr(pctxt
,
7549 XML_SCHEMAP_SRC_ATTRIBUTE_3_2
,
7550 NULL
, node
, child
, NULL
,
7553 xmlSchemaPContentErr(pctxt
,
7554 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7555 NULL
, node
, child
, NULL
,
7559 if (IS_SCHEMA(child
, "simpleType")) {
7560 if (WXS_ATTRUSE_DECL(use
)->typeName
!= NULL
) {
7563 * type and <simpleType> must not both be present.
7565 xmlSchemaPContentErr(pctxt
, XML_SCHEMAP_SRC_ATTRIBUTE_4
,
7567 "The attribute 'type' and the <simpleType> child "
7568 "are mutually exclusive", NULL
);
7570 WXS_ATTRUSE_TYPEDEF(use
) =
7571 xmlSchemaParseSimpleType(pctxt
, schema
, child
, 0);
7572 child
= child
->next
;
7575 xmlSchemaPContentErr(pctxt
, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7576 NULL
, node
, child
, NULL
,
7577 "(annotation?, simpleType?)");
7580 return (WXS_BASIC_CAST use
);
7584 static xmlSchemaAttributePtr
7585 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt
,
7586 xmlSchemaPtr schema
,
7589 const xmlChar
*attrValue
;
7590 xmlSchemaAttributePtr ret
;
7591 xmlNodePtr child
= NULL
;
7595 * Note that the w3c spec assumes the schema to be validated with schema
7596 * for schemas beforehand.
7598 * 3.2.3 Constraints on XML Representations of Attribute Declarations
7600 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
7604 * One of ref or name must be present, but not both
7606 attr
= xmlSchemaGetPropNode(node
, "name");
7608 xmlSchemaPMissingAttrErr(pctxt
, XML_SCHEMAP_S4S_ATTR_MISSING
,
7609 NULL
, node
, "name", NULL
);
7612 if (xmlSchemaPValAttrNode(pctxt
, NULL
, attr
,
7613 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &attrValue
) != 0) {
7617 * 3.2.6 Schema Component Constraint: xmlns Not Allowed
7618 * TODO: Move this to the component layer.
7620 if (xmlStrEqual(attrValue
, BAD_CAST
"xmlns")) {
7621 xmlSchemaPSimpleTypeErr(pctxt
,
7622 XML_SCHEMAP_NO_XMLNS
,
7623 NULL
, (xmlNodePtr
) attr
,
7624 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), NULL
, NULL
,
7625 "The value of the attribute must not match 'xmlns'",
7630 * 3.2.6 Schema Component Constraint: xsi: Not Allowed
7631 * TODO: Move this to the component layer.
7632 * Or better leave it here and add it to the component layer
7633 * if we have a schema construction API.
7635 if (xmlStrEqual(pctxt
->targetNamespace
, xmlSchemaInstanceNs
)) {
7636 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
7637 XML_SCHEMAP_NO_XSI
, node
, NULL
,
7638 "The target namespace must not match '%s'",
7639 xmlSchemaInstanceNs
, NULL
);
7642 ret
= xmlSchemaAddAttribute(pctxt
, schema
, attrValue
,
7643 pctxt
->targetNamespace
, node
, 1);
7646 ret
->flags
|= XML_SCHEMAS_ATTR_GLOBAL
;
7649 * Check for illegal attributes.
7651 attr
= node
->properties
;
7652 while (attr
!= NULL
) {
7653 if (attr
->ns
== NULL
) {
7654 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
7655 (!xmlStrEqual(attr
->name
, BAD_CAST
"default")) &&
7656 (!xmlStrEqual(attr
->name
, BAD_CAST
"fixed")) &&
7657 (!xmlStrEqual(attr
->name
, BAD_CAST
"name")) &&
7658 (!xmlStrEqual(attr
->name
, BAD_CAST
"type")))
7660 xmlSchemaPIllegalAttrErr(pctxt
,
7661 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7663 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
7664 xmlSchemaPIllegalAttrErr(pctxt
,
7665 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7669 xmlSchemaPValAttrQName(pctxt
, schema
, NULL
,
7670 node
, "type", &ret
->typeNs
, &ret
->typeName
);
7672 xmlSchemaPValAttrID(pctxt
, node
, BAD_CAST
"id");
7674 * Attribute "fixed".
7676 ret
->defValue
= xmlSchemaGetProp(pctxt
, node
, "fixed");
7677 if (ret
->defValue
!= NULL
)
7678 ret
->flags
|= XML_SCHEMAS_ATTR_FIXED
;
7680 * Attribute "default".
7682 attr
= xmlSchemaGetPropNode(node
, "default");
7686 * default and fixed must not both be present.
7688 if (ret
->flags
& XML_SCHEMAS_ATTR_FIXED
) {
7689 xmlSchemaPMutualExclAttrErr(pctxt
, XML_SCHEMAP_SRC_ATTRIBUTE_1
,
7690 WXS_BASIC_CAST ret
, attr
, "default", "fixed");
7692 ret
->defValue
= xmlSchemaGetNodeContent(pctxt
, (xmlNodePtr
) attr
);
7695 * And now for the children...
7697 child
= node
->children
;
7698 if (IS_SCHEMA(child
, "annotation")) {
7699 ret
->annot
= xmlSchemaParseAnnotation(pctxt
, child
, 1);
7700 child
= child
->next
;
7702 if (IS_SCHEMA(child
, "simpleType")) {
7703 if (ret
->typeName
!= NULL
) {
7706 * type and <simpleType> must not both be present.
7708 xmlSchemaPContentErr(pctxt
, XML_SCHEMAP_SRC_ATTRIBUTE_4
,
7710 "The attribute 'type' and the <simpleType> child "
7711 "are mutually exclusive", NULL
);
7713 ret
->subtypes
= xmlSchemaParseSimpleType(pctxt
, schema
, child
, 0);
7714 child
= child
->next
;
7717 xmlSchemaPContentErr(pctxt
, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7718 NULL
, node
, child
, NULL
,
7719 "(annotation?, simpleType?)");
7725 * xmlSchemaParseAttributeGroupRef:
7726 * @ctxt: a schema validation context
7727 * @schema: the schema being built
7728 * @node: a subtree containing XML Schema information
7730 * Parse an attribute group definition reference.
7731 * Note that a reference to an attribute group does not
7732 * correspond to any component at all.
7733 * *WARNING* this interface is highly subject to change
7735 * Returns the attribute group or NULL in case of error.
7737 static xmlSchemaQNameRefPtr
7738 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt
,
7739 xmlSchemaPtr schema
,
7742 xmlSchemaQNameRefPtr ret
;
7743 xmlNodePtr child
= NULL
;
7745 const xmlChar
*refNs
= NULL
, *ref
= NULL
;
7747 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
7750 attr
= xmlSchemaGetPropNode(node
, "ref");
7752 xmlSchemaPMissingAttrErr(pctxt
,
7753 XML_SCHEMAP_S4S_ATTR_MISSING
,
7754 NULL
, node
, "ref", NULL
);
7757 xmlSchemaPValAttrNodeQName(pctxt
, schema
,
7758 NULL
, attr
, &refNs
, &ref
);
7759 if (xmlSchemaCheckReference(pctxt
, schema
, node
, attr
, refNs
) != 0)
7763 * Check for illegal attributes.
7765 attr
= node
->properties
;
7766 while (attr
!= NULL
) {
7767 if (attr
->ns
== NULL
) {
7768 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"ref")) &&
7769 (!xmlStrEqual(attr
->name
, BAD_CAST
"id")))
7771 xmlSchemaPIllegalAttrErr(pctxt
,
7772 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7774 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
7775 xmlSchemaPIllegalAttrErr(pctxt
,
7776 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7781 xmlSchemaPValAttrID(pctxt
, node
, BAD_CAST
"id");
7784 * And now for the children...
7786 child
= node
->children
;
7787 if (IS_SCHEMA(child
, "annotation")) {
7789 * TODO: We do not have a place to store the annotation, do we?
7791 xmlSchemaParseAnnotation(pctxt
, child
, 0);
7792 child
= child
->next
;
7794 if (child
!= NULL
) {
7795 xmlSchemaPContentErr(pctxt
,
7796 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7797 NULL
, node
, child
, NULL
,
7802 * Handle attribute group redefinitions.
7804 if (pctxt
->isRedefine
&& pctxt
->redef
&&
7805 (pctxt
->redef
->item
->type
==
7806 XML_SCHEMA_TYPE_ATTRIBUTEGROUP
) &&
7807 (ref
== pctxt
->redef
->refName
) &&
7808 (refNs
== pctxt
->redef
->refTargetNs
))
7811 * SPEC src-redefine:
7812 * (7.1) "If it has an <attributeGroup> among its contents
7813 * the `actual value` of whose ref [attribute] is the same
7814 * as the `actual value` of its own name attribute plus
7815 * target namespace, then it must have exactly one such group."
7817 if (pctxt
->redefCounter
!= 0) {
7818 xmlChar
*str
= NULL
;
7820 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
7821 XML_SCHEMAP_SRC_REDEFINE
, node
, NULL
,
7822 "The redefining attribute group definition "
7823 "'%s' must not contain more than one "
7824 "reference to the redefined definition",
7825 xmlSchemaFormatQName(&str
, refNs
, ref
), NULL
);
7829 pctxt
->redefCounter
++;
7831 * URGENT TODO: How to ensure that the reference will not be
7832 * handled by the normal component resolution mechanism?
7834 ret
= xmlSchemaNewQNameRef(pctxt
,
7835 XML_SCHEMA_TYPE_ATTRIBUTEGROUP
, ref
, refNs
);
7839 pctxt
->redef
->reference
= WXS_BASIC_CAST ret
;
7842 * Create a QName-reference helper component. We will substitute this
7843 * component for the attribute uses of the referenced attribute group
7846 ret
= xmlSchemaNewQNameRef(pctxt
,
7847 XML_SCHEMA_TYPE_ATTRIBUTEGROUP
, ref
, refNs
);
7851 /* Add to pending items, to be able to resolve the reference. */
7852 WXS_ADD_PENDING(pctxt
, ret
);
7858 * xmlSchemaParseAttributeGroupDefinition:
7859 * @pctxt: a schema validation context
7860 * @schema: the schema being built
7861 * @node: a subtree containing XML Schema information
7863 * parse a XML schema Attribute Group declaration
7864 * *WARNING* this interface is highly subject to change
7866 * Returns the attribute group definition or NULL in case of error.
7868 static xmlSchemaAttributeGroupPtr
7869 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt
,
7870 xmlSchemaPtr schema
,
7873 const xmlChar
*name
;
7874 xmlSchemaAttributeGroupPtr ret
;
7875 xmlNodePtr child
= NULL
;
7879 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
7882 attr
= xmlSchemaGetPropNode(node
, "name");
7884 xmlSchemaPMissingAttrErr(pctxt
,
7885 XML_SCHEMAP_S4S_ATTR_MISSING
,
7886 NULL
, node
, "name", NULL
);
7890 * The name is crucial, exit if invalid.
7892 if (xmlSchemaPValAttrNode(pctxt
,
7894 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &name
) != 0) {
7897 ret
= xmlSchemaAddAttributeGroupDefinition(pctxt
, schema
,
7898 name
, pctxt
->targetNamespace
, node
);
7902 * Check for illegal attributes.
7904 attr
= node
->properties
;
7905 while (attr
!= NULL
) {
7906 if (attr
->ns
== NULL
) {
7907 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"name")) &&
7908 (!xmlStrEqual(attr
->name
, BAD_CAST
"id")))
7910 xmlSchemaPIllegalAttrErr(pctxt
,
7911 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7913 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
7914 xmlSchemaPIllegalAttrErr(pctxt
,
7915 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
7920 xmlSchemaPValAttrID(pctxt
, node
, BAD_CAST
"id");
7922 * And now for the children...
7924 child
= node
->children
;
7925 if (IS_SCHEMA(child
, "annotation")) {
7926 ret
->annot
= xmlSchemaParseAnnotation(pctxt
, child
, 1);
7927 child
= child
->next
;
7930 * Parse contained attribute decls/refs.
7932 if (xmlSchemaParseLocalAttributes(pctxt
, schema
, &child
,
7933 (xmlSchemaItemListPtr
*) &(ret
->attrUses
),
7934 XML_SCHEMA_TYPE_ATTRIBUTEGROUP
, &hasRefs
) == -1)
7937 ret
->flags
|= XML_SCHEMAS_ATTRGROUP_HAS_REFS
;
7939 * Parse the attribute wildcard.
7941 if (IS_SCHEMA(child
, "anyAttribute")) {
7942 ret
->attributeWildcard
= xmlSchemaParseAnyAttribute(pctxt
,
7944 child
= child
->next
;
7946 if (child
!= NULL
) {
7947 xmlSchemaPContentErr(pctxt
,
7948 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
7949 NULL
, node
, child
, NULL
,
7950 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
7956 * xmlSchemaPValAttrFormDefault:
7958 * @flags: the flags to be modified
7959 * @flagQualified: the specific flag for "qualified"
7961 * Returns 0 if the value is valid, 1 otherwise.
7964 xmlSchemaPValAttrFormDefault(const xmlChar
*value
,
7968 if (xmlStrEqual(value
, BAD_CAST
"qualified")) {
7969 if ((*flags
& flagQualified
) == 0)
7970 *flags
|= flagQualified
;
7971 } else if (!xmlStrEqual(value
, BAD_CAST
"unqualified"))
7978 * xmlSchemaPValAttrBlockFinal:
7980 * @flags: the flags to be modified
7981 * @flagAll: the specific flag for "#all"
7982 * @flagExtension: the specific flag for "extension"
7983 * @flagRestriction: the specific flag for "restriction"
7984 * @flagSubstitution: the specific flag for "substitution"
7985 * @flagList: the specific flag for "list"
7986 * @flagUnion: the specific flag for "union"
7988 * Validates the value of the attribute "final" and "block". The value
7989 * is converted into the specified flag values and returned in @flags.
7991 * Returns 0 if the value is valid, 1 otherwise.
7995 xmlSchemaPValAttrBlockFinal(const xmlChar
*value
,
7999 int flagRestriction
,
8000 int flagSubstitution
,
8007 * TODO: This does not check for duplicate entries.
8009 if ((flags
== NULL
) || (value
== NULL
))
8013 if (xmlStrEqual(value
, BAD_CAST
"#all")) {
8017 if (flagExtension
!= -1)
8018 *flags
|= flagExtension
;
8019 if (flagRestriction
!= -1)
8020 *flags
|= flagRestriction
;
8021 if (flagSubstitution
!= -1)
8022 *flags
|= flagSubstitution
;
8025 if (flagUnion
!= -1)
8026 *flags
|= flagUnion
;
8029 const xmlChar
*end
, *cur
= value
;
8033 while (IS_BLANK_CH(*cur
))
8036 while ((*end
!= 0) && (!(IS_BLANK_CH(*end
))))
8040 item
= xmlStrndup(cur
, end
- cur
);
8041 if (xmlStrEqual(item
, BAD_CAST
"extension")) {
8042 if (flagExtension
!= -1) {
8043 if ((*flags
& flagExtension
) == 0)
8044 *flags
|= flagExtension
;
8047 } else if (xmlStrEqual(item
, BAD_CAST
"restriction")) {
8048 if (flagRestriction
!= -1) {
8049 if ((*flags
& flagRestriction
) == 0)
8050 *flags
|= flagRestriction
;
8053 } else if (xmlStrEqual(item
, BAD_CAST
"substitution")) {
8054 if (flagSubstitution
!= -1) {
8055 if ((*flags
& flagSubstitution
) == 0)
8056 *flags
|= flagSubstitution
;
8059 } else if (xmlStrEqual(item
, BAD_CAST
"list")) {
8060 if (flagList
!= -1) {
8061 if ((*flags
& flagList
) == 0)
8065 } else if (xmlStrEqual(item
, BAD_CAST
"union")) {
8066 if (flagUnion
!= -1) {
8067 if ((*flags
& flagUnion
) == 0)
8068 *flags
|= flagUnion
;
8076 } while ((ret
== 0) && (*cur
!= 0));
8083 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt
,
8084 xmlSchemaIDCPtr idc
,
8085 xmlSchemaIDCSelectPtr selector
,
8093 * Schema Component Constraint: Selector Value OK
8095 * TODO: 1 The {selector} must be a valid XPath expression, as defined
8098 if (selector
== NULL
) {
8099 xmlSchemaPErr(ctxt
, idc
->node
,
8100 XML_SCHEMAP_INTERNAL
,
8101 "Internal error: xmlSchemaCheckCSelectorXPath, "
8102 "the selector is not specified.\n", NULL
, NULL
);
8108 node
= (xmlNodePtr
) attr
;
8109 if (selector
->xpath
== NULL
) {
8110 xmlSchemaPCustomErr(ctxt
,
8111 /* TODO: Adjust error code. */
8112 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
8114 "The XPath expression of the selector is not valid", NULL
);
8115 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
);
8117 const xmlChar
**nsArray
= NULL
;
8118 xmlNsPtr
*nsList
= NULL
;
8120 * Compile the XPath expression.
8123 * TODO: We need the array of in-scope namespaces for compilation.
8124 * TODO: Call xmlPatterncompile with different options for selector/
8130 nsList
= xmlGetNsList(attr
->doc
, attr
->parent
);
8132 * Build an array of prefixes and namespaces.
8134 if (nsList
!= NULL
) {
8137 for (i
= 0; nsList
[i
] != NULL
; i
++)
8140 nsArray
= (const xmlChar
**) xmlMalloc(
8141 (count
* 2 + 1) * sizeof(const xmlChar
*));
8142 if (nsArray
== NULL
) {
8143 xmlSchemaPErrMemory(ctxt
, "allocating a namespace array",
8148 for (i
= 0; i
< count
; i
++) {
8149 nsArray
[2 * i
] = nsList
[i
]->href
;
8150 nsArray
[2 * i
+ 1] = nsList
[i
]->prefix
;
8152 nsArray
[count
* 2] = NULL
;
8156 * TODO: Differentiate between "selector" and "field".
8159 selector
->xpathComp
= (void *) xmlPatterncompile(selector
->xpath
,
8160 NULL
, XML_PATTERN_XSFIELD
, nsArray
);
8162 selector
->xpathComp
= (void *) xmlPatterncompile(selector
->xpath
,
8163 NULL
, XML_PATTERN_XSSEL
, nsArray
);
8164 if (nsArray
!= NULL
)
8165 xmlFree((xmlChar
**) nsArray
);
8167 if (selector
->xpathComp
== NULL
) {
8168 xmlSchemaPCustomErr(ctxt
,
8169 /* TODO: Adjust error code? */
8170 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
8172 "The XPath expression '%s' could not be "
8173 "compiled", selector
->xpath
);
8174 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
);
8180 #define ADD_ANNOTATION(annot) \
8181 xmlSchemaAnnotPtr cur = item->annot; \
8182 if (item->annot == NULL) { \
8183 item->annot = annot; \
8186 cur = item->annot; \
8187 if (cur->next != NULL) { \
8193 * xmlSchemaAssignAnnotation:
8194 * @item: the schema component
8195 * @annot: the annotation
8197 * Adds the annotation to the given schema component.
8199 * Returns the given annotation.
8201 static xmlSchemaAnnotPtr
8202 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem
,
8203 xmlSchemaAnnotPtr annot
)
8205 if ((annItem
== NULL
) || (annot
== NULL
))
8207 switch (annItem
->type
) {
8208 case XML_SCHEMA_TYPE_ELEMENT
: {
8209 xmlSchemaElementPtr item
= (xmlSchemaElementPtr
) annItem
;
8210 ADD_ANNOTATION(annot
)
8213 case XML_SCHEMA_TYPE_ATTRIBUTE
: {
8214 xmlSchemaAttributePtr item
= (xmlSchemaAttributePtr
) annItem
;
8215 ADD_ANNOTATION(annot
)
8218 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE
:
8219 case XML_SCHEMA_TYPE_ANY
: {
8220 xmlSchemaWildcardPtr item
= (xmlSchemaWildcardPtr
) annItem
;
8221 ADD_ANNOTATION(annot
)
8224 case XML_SCHEMA_TYPE_PARTICLE
:
8225 case XML_SCHEMA_TYPE_IDC_KEY
:
8226 case XML_SCHEMA_TYPE_IDC_KEYREF
:
8227 case XML_SCHEMA_TYPE_IDC_UNIQUE
: {
8228 xmlSchemaAnnotItemPtr item
= (xmlSchemaAnnotItemPtr
) annItem
;
8229 ADD_ANNOTATION(annot
)
8232 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
: {
8233 xmlSchemaAttributeGroupPtr item
=
8234 (xmlSchemaAttributeGroupPtr
) annItem
;
8235 ADD_ANNOTATION(annot
)
8238 case XML_SCHEMA_TYPE_NOTATION
: {
8239 xmlSchemaNotationPtr item
= (xmlSchemaNotationPtr
) annItem
;
8240 ADD_ANNOTATION(annot
)
8243 case XML_SCHEMA_FACET_MININCLUSIVE
:
8244 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
8245 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
8246 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
8247 case XML_SCHEMA_FACET_TOTALDIGITS
:
8248 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
8249 case XML_SCHEMA_FACET_PATTERN
:
8250 case XML_SCHEMA_FACET_ENUMERATION
:
8251 case XML_SCHEMA_FACET_WHITESPACE
:
8252 case XML_SCHEMA_FACET_LENGTH
:
8253 case XML_SCHEMA_FACET_MAXLENGTH
:
8254 case XML_SCHEMA_FACET_MINLENGTH
: {
8255 xmlSchemaFacetPtr item
= (xmlSchemaFacetPtr
) annItem
;
8256 ADD_ANNOTATION(annot
)
8259 case XML_SCHEMA_TYPE_SIMPLE
:
8260 case XML_SCHEMA_TYPE_COMPLEX
: {
8261 xmlSchemaTypePtr item
= (xmlSchemaTypePtr
) annItem
;
8262 ADD_ANNOTATION(annot
)
8265 case XML_SCHEMA_TYPE_GROUP
: {
8266 xmlSchemaModelGroupDefPtr item
= (xmlSchemaModelGroupDefPtr
) annItem
;
8267 ADD_ANNOTATION(annot
)
8270 case XML_SCHEMA_TYPE_SEQUENCE
:
8271 case XML_SCHEMA_TYPE_CHOICE
:
8272 case XML_SCHEMA_TYPE_ALL
: {
8273 xmlSchemaModelGroupPtr item
= (xmlSchemaModelGroupPtr
) annItem
;
8274 ADD_ANNOTATION(annot
)
8278 xmlSchemaPCustomErr(NULL
,
8279 XML_SCHEMAP_INTERNAL
,
8281 "Internal error: xmlSchemaAddAnnotation, "
8282 "The item is not a annotated schema component", NULL
);
8289 * xmlSchemaParseIDCSelectorAndField:
8290 * @ctxt: a schema validation context
8291 * @schema: the schema being built
8292 * @node: a subtree containing XML Schema information
8294 * Parses a XML Schema identity-constraint definition's
8295 * <selector> and <field> elements.
8297 * Returns the parsed identity-constraint definition.
8299 static xmlSchemaIDCSelectPtr
8300 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt
,
8301 xmlSchemaIDCPtr idc
,
8305 xmlSchemaIDCSelectPtr item
;
8306 xmlNodePtr child
= NULL
;
8310 * Check for illegal attributes.
8312 attr
= node
->properties
;
8313 while (attr
!= NULL
) {
8314 if (attr
->ns
== NULL
) {
8315 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
8316 (!xmlStrEqual(attr
->name
, BAD_CAST
"xpath"))) {
8317 xmlSchemaPIllegalAttrErr(ctxt
,
8318 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8320 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
8321 xmlSchemaPIllegalAttrErr(ctxt
,
8322 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8329 item
= (xmlSchemaIDCSelectPtr
) xmlMalloc(sizeof(xmlSchemaIDCSelect
));
8331 xmlSchemaPErrMemory(ctxt
,
8332 "allocating a 'selector' of an identity-constraint definition",
8336 memset(item
, 0, sizeof(xmlSchemaIDCSelect
));
8338 * Attribute "xpath" (mandatory).
8340 attr
= xmlSchemaGetPropNode(node
, "xpath");
8342 xmlSchemaPMissingAttrErr(ctxt
,
8343 XML_SCHEMAP_S4S_ATTR_MISSING
,
8347 item
->xpath
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
8349 * URGENT TODO: "field"s have an other syntax than "selector"s.
8352 if (xmlSchemaCheckCSelectorXPath(ctxt
, idc
, item
, attr
,
8356 XML_SCHEMAP_INTERNAL
,
8357 "Internal error: xmlSchemaParseIDCSelectorAndField, "
8358 "validating the XPath expression of a IDC selector.\n",
8363 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
8365 * And now for the children...
8367 child
= node
->children
;
8368 if (IS_SCHEMA(child
, "annotation")) {
8370 * Add the annotation to the parent IDC.
8372 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) idc
,
8373 xmlSchemaParseAnnotation(ctxt
, child
, 1));
8374 child
= child
->next
;
8376 if (child
!= NULL
) {
8377 xmlSchemaPContentErr(ctxt
,
8378 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
8380 NULL
, "(annotation?)");
8387 * xmlSchemaParseIDC:
8388 * @ctxt: a schema validation context
8389 * @schema: the schema being built
8390 * @node: a subtree containing XML Schema information
8392 * Parses a XML Schema identity-constraint definition.
8394 * Returns the parsed identity-constraint definition.
8396 static xmlSchemaIDCPtr
8397 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt
,
8398 xmlSchemaPtr schema
,
8400 xmlSchemaTypeType idcCategory
,
8401 const xmlChar
*targetNamespace
)
8403 xmlSchemaIDCPtr item
= NULL
;
8404 xmlNodePtr child
= NULL
;
8406 const xmlChar
*name
= NULL
;
8407 xmlSchemaIDCSelectPtr field
= NULL
, lastField
= NULL
;
8410 * Check for illegal attributes.
8412 attr
= node
->properties
;
8413 while (attr
!= NULL
) {
8414 if (attr
->ns
== NULL
) {
8415 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
8416 (!xmlStrEqual(attr
->name
, BAD_CAST
"name")) &&
8417 ((idcCategory
!= XML_SCHEMA_TYPE_IDC_KEYREF
) ||
8418 (!xmlStrEqual(attr
->name
, BAD_CAST
"refer")))) {
8419 xmlSchemaPIllegalAttrErr(ctxt
,
8420 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8422 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
8423 xmlSchemaPIllegalAttrErr(ctxt
,
8424 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8429 * Attribute "name" (mandatory).
8431 attr
= xmlSchemaGetPropNode(node
, "name");
8433 xmlSchemaPMissingAttrErr(ctxt
,
8434 XML_SCHEMAP_S4S_ATTR_MISSING
,
8438 } else if (xmlSchemaPValAttrNode(ctxt
,
8440 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &name
) != 0) {
8443 /* Create the component. */
8444 item
= xmlSchemaAddIDC(ctxt
, schema
, name
, targetNamespace
,
8449 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
8450 if (idcCategory
== XML_SCHEMA_TYPE_IDC_KEYREF
) {
8452 * Attribute "refer" (mandatory).
8454 attr
= xmlSchemaGetPropNode(node
, "refer");
8456 xmlSchemaPMissingAttrErr(ctxt
,
8457 XML_SCHEMAP_S4S_ATTR_MISSING
,
8462 * Create a reference item.
8464 item
->ref
= xmlSchemaNewQNameRef(ctxt
, XML_SCHEMA_TYPE_IDC_KEY
,
8466 if (item
->ref
== NULL
)
8468 xmlSchemaPValAttrNodeQName(ctxt
, schema
,
8470 &(item
->ref
->targetNamespace
),
8471 &(item
->ref
->name
));
8472 xmlSchemaCheckReference(ctxt
, schema
, node
, attr
,
8473 item
->ref
->targetNamespace
);
8477 * And now for the children...
8479 child
= node
->children
;
8480 if (IS_SCHEMA(child
, "annotation")) {
8481 item
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
8482 child
= child
->next
;
8484 if (child
== NULL
) {
8485 xmlSchemaPContentErr(ctxt
,
8486 XML_SCHEMAP_S4S_ELEM_MISSING
,
8488 "A child element is missing",
8489 "(annotation?, (selector, field+))");
8492 * Child element <selector>.
8494 if (IS_SCHEMA(child
, "selector")) {
8495 item
->selector
= xmlSchemaParseIDCSelectorAndField(ctxt
,
8497 child
= child
->next
;
8499 * Child elements <field>.
8501 if (IS_SCHEMA(child
, "field")) {
8503 field
= xmlSchemaParseIDCSelectorAndField(ctxt
,
8505 if (field
!= NULL
) {
8506 field
->index
= item
->nbFields
;
8508 if (lastField
!= NULL
)
8509 lastField
->next
= field
;
8511 item
->fields
= field
;
8514 child
= child
->next
;
8515 } while (IS_SCHEMA(child
, "field"));
8517 xmlSchemaPContentErr(ctxt
,
8518 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
8520 NULL
, "(annotation?, (selector, field+))");
8523 if (child
!= NULL
) {
8524 xmlSchemaPContentErr(ctxt
,
8525 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
8527 NULL
, "(annotation?, (selector, field+))");
8534 * xmlSchemaParseElement:
8535 * @ctxt: a schema validation context
8536 * @schema: the schema being built
8537 * @node: a subtree containing XML Schema information
8538 * @topLevel: indicates if this is global declaration
8540 * Parses a XML schema element declaration.
8541 * *WARNING* this interface is highly subject to change
8543 * Returns the element declaration or a particle; NULL in case
8544 * of an error or if the particle has minOccurs==maxOccurs==0.
8546 static xmlSchemaBasicItemPtr
8547 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
8548 xmlNodePtr node
, int *isElemRef
, int topLevel
)
8550 xmlSchemaElementPtr decl
= NULL
;
8551 xmlSchemaParticlePtr particle
= NULL
;
8552 xmlSchemaAnnotPtr annot
= NULL
;
8553 xmlNodePtr child
= NULL
;
8554 xmlAttrPtr attr
, nameAttr
;
8555 int min
, max
, isRef
= 0;
8556 xmlChar
*des
= NULL
;
8558 /* 3.3.3 Constraints on XML Representations of Element Declarations */
8559 /* TODO: Complete implementation of 3.3.6 */
8561 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
8564 if (isElemRef
!= NULL
)
8567 * If we get a "ref" attribute on a local <element> we will assume it's
8568 * a reference - even if there's a "name" attribute; this seems to be more
8571 nameAttr
= xmlSchemaGetPropNode(node
, "name");
8572 attr
= xmlSchemaGetPropNode(node
, "ref");
8573 if ((topLevel
) || (attr
== NULL
)) {
8574 if (nameAttr
== NULL
) {
8575 xmlSchemaPMissingAttrErr(ctxt
,
8576 XML_SCHEMAP_S4S_ATTR_MISSING
,
8577 NULL
, node
, "name", NULL
);
8583 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
8584 child
= node
->children
;
8585 if (IS_SCHEMA(child
, "annotation")) {
8586 annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
8587 child
= child
->next
;
8590 * Skip particle part if a global declaration.
8593 goto declaration_part
;
8595 * The particle part ==================================================
8597 min
= xmlGetMinOccurs(ctxt
, node
, 0, -1, 1, "xs:nonNegativeInteger");
8598 max
= xmlGetMaxOccurs(ctxt
, node
, 0, UNBOUNDED
, 1, "(xs:nonNegativeInteger | unbounded)");
8599 xmlSchemaPCheckParticleCorrect_2(ctxt
, NULL
, node
, min
, max
);
8600 particle
= xmlSchemaAddParticle(ctxt
, node
, min
, max
);
8601 if (particle
== NULL
)
8604 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
8607 const xmlChar
*refNs
= NULL
, *ref
= NULL
;
8608 xmlSchemaQNameRefPtr refer
= NULL
;
8610 * The reference part =============================================
8612 if (isElemRef
!= NULL
)
8615 xmlSchemaPValAttrNodeQName(ctxt
, schema
,
8616 NULL
, attr
, &refNs
, &ref
);
8617 xmlSchemaCheckReference(ctxt
, schema
, node
, attr
, refNs
);
8619 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
8621 if (nameAttr
!= NULL
) {
8622 xmlSchemaPMutualExclAttrErr(ctxt
,
8623 XML_SCHEMAP_SRC_ELEMENT_2_1
, NULL
, nameAttr
, "ref", "name");
8626 * Check for illegal attributes.
8628 attr
= node
->properties
;
8629 while (attr
!= NULL
) {
8630 if (attr
->ns
== NULL
) {
8631 if (xmlStrEqual(attr
->name
, BAD_CAST
"ref") ||
8632 xmlStrEqual(attr
->name
, BAD_CAST
"name") ||
8633 xmlStrEqual(attr
->name
, BAD_CAST
"id") ||
8634 xmlStrEqual(attr
->name
, BAD_CAST
"maxOccurs") ||
8635 xmlStrEqual(attr
->name
, BAD_CAST
"minOccurs"))
8640 /* SPEC (3.3.3 : 2.2) */
8641 xmlSchemaPCustomAttrErr(ctxt
,
8642 XML_SCHEMAP_SRC_ELEMENT_2_2
,
8644 "Only the attributes 'minOccurs', 'maxOccurs' and "
8645 "'id' are allowed in addition to 'ref'");
8648 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
8649 xmlSchemaPIllegalAttrErr(ctxt
,
8650 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8655 * No children except <annotation> expected.
8657 if (child
!= NULL
) {
8658 xmlSchemaPContentErr(ctxt
, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
8659 NULL
, node
, child
, NULL
, "(annotation?)");
8661 if ((min
== 0) && (max
== 0))
8664 * Create the reference item and attach it to the particle.
8666 refer
= xmlSchemaNewQNameRef(ctxt
, XML_SCHEMA_TYPE_ELEMENT
,
8670 particle
->children
= (xmlSchemaTreeItemPtr
) refer
;
8671 particle
->annot
= annot
;
8673 * Add the particle to pending components, since the reference
8674 * need to be resolved.
8676 WXS_ADD_PENDING(ctxt
, particle
);
8677 return ((xmlSchemaBasicItemPtr
) particle
);
8680 * The declaration part ===============================================
8684 const xmlChar
*ns
= NULL
, *fixed
, *name
, *attrValue
;
8685 xmlSchemaIDCPtr curIDC
= NULL
, lastIDC
= NULL
;
8687 if (xmlSchemaPValAttrNode(ctxt
, NULL
, nameAttr
,
8688 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &name
) != 0)
8691 * Evaluate the target namespace.
8694 ns
= ctxt
->targetNamespace
;
8696 attr
= xmlSchemaGetPropNode(node
, "form");
8698 attrValue
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
8699 if (xmlStrEqual(attrValue
, BAD_CAST
"qualified")) {
8700 ns
= ctxt
->targetNamespace
;
8701 } else if (!xmlStrEqual(attrValue
, BAD_CAST
"unqualified")) {
8702 xmlSchemaPSimpleTypeErr(ctxt
,
8703 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
8704 NULL
, (xmlNodePtr
) attr
,
8705 NULL
, "(qualified | unqualified)",
8706 attrValue
, NULL
, NULL
, NULL
);
8708 } else if (schema
->flags
& XML_SCHEMAS_QUALIF_ELEM
)
8709 ns
= ctxt
->targetNamespace
;
8711 decl
= xmlSchemaAddElement(ctxt
, name
, ns
, node
, topLevel
);
8716 * Check for illegal attributes.
8718 attr
= node
->properties
;
8719 while (attr
!= NULL
) {
8720 if (attr
->ns
== NULL
) {
8721 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"name")) &&
8722 (!xmlStrEqual(attr
->name
, BAD_CAST
"type")) &&
8723 (!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
8724 (!xmlStrEqual(attr
->name
, BAD_CAST
"default")) &&
8725 (!xmlStrEqual(attr
->name
, BAD_CAST
"fixed")) &&
8726 (!xmlStrEqual(attr
->name
, BAD_CAST
"block")) &&
8727 (!xmlStrEqual(attr
->name
, BAD_CAST
"nillable")))
8729 if (topLevel
== 0) {
8730 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"maxOccurs")) &&
8731 (!xmlStrEqual(attr
->name
, BAD_CAST
"minOccurs")) &&
8732 (!xmlStrEqual(attr
->name
, BAD_CAST
"form")))
8734 xmlSchemaPIllegalAttrErr(ctxt
,
8735 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8737 } else if ((!xmlStrEqual(attr
->name
, BAD_CAST
"final")) &&
8738 (!xmlStrEqual(attr
->name
, BAD_CAST
"abstract")) &&
8739 (!xmlStrEqual(attr
->name
, BAD_CAST
"substitutionGroup"))) {
8741 xmlSchemaPIllegalAttrErr(ctxt
,
8742 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8745 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
8747 xmlSchemaPIllegalAttrErr(ctxt
,
8748 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8753 * Extract/validate attributes.
8757 * Process top attributes of global element declarations here.
8759 decl
->flags
|= XML_SCHEMAS_ELEM_GLOBAL
;
8760 decl
->flags
|= XML_SCHEMAS_ELEM_TOPLEVEL
;
8761 xmlSchemaPValAttrQName(ctxt
, schema
,
8762 NULL
, node
, "substitutionGroup",
8763 &(decl
->substGroupNs
), &(decl
->substGroup
));
8764 if (xmlGetBooleanProp(ctxt
, node
, "abstract", 0))
8765 decl
->flags
|= XML_SCHEMAS_ELEM_ABSTRACT
;
8767 * Attribute "final".
8769 attr
= xmlSchemaGetPropNode(node
, "final");
8771 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_EXTENSION
)
8772 decl
->flags
|= XML_SCHEMAS_ELEM_FINAL_EXTENSION
;
8773 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION
)
8774 decl
->flags
|= XML_SCHEMAS_ELEM_FINAL_RESTRICTION
;
8776 attrValue
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
8777 if (xmlSchemaPValAttrBlockFinal(attrValue
, &(decl
->flags
),
8779 XML_SCHEMAS_ELEM_FINAL_EXTENSION
,
8780 XML_SCHEMAS_ELEM_FINAL_RESTRICTION
, -1, -1, -1) != 0) {
8781 xmlSchemaPSimpleTypeErr(ctxt
,
8782 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
8783 NULL
, (xmlNodePtr
) attr
,
8784 NULL
, "(#all | List of (extension | restriction))",
8785 attrValue
, NULL
, NULL
, NULL
);
8790 * Attribute "block".
8792 attr
= xmlSchemaGetPropNode(node
, "block");
8795 * Apply default "block" values.
8797 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION
)
8798 decl
->flags
|= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION
;
8799 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION
)
8800 decl
->flags
|= XML_SCHEMAS_ELEM_BLOCK_EXTENSION
;
8801 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION
)
8802 decl
->flags
|= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION
;
8804 attrValue
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
8805 if (xmlSchemaPValAttrBlockFinal(attrValue
, &(decl
->flags
),
8807 XML_SCHEMAS_ELEM_BLOCK_EXTENSION
,
8808 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION
,
8809 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION
, -1, -1) != 0) {
8810 xmlSchemaPSimpleTypeErr(ctxt
,
8811 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
8812 NULL
, (xmlNodePtr
) attr
,
8813 NULL
, "(#all | List of (extension | "
8814 "restriction | substitution))", attrValue
,
8818 if (xmlGetBooleanProp(ctxt
, node
, "nillable", 0))
8819 decl
->flags
|= XML_SCHEMAS_ELEM_NILLABLE
;
8821 attr
= xmlSchemaGetPropNode(node
, "type");
8823 xmlSchemaPValAttrNodeQName(ctxt
, schema
,
8825 &(decl
->namedTypeNs
), &(decl
->namedType
));
8826 xmlSchemaCheckReference(ctxt
, schema
, node
,
8827 attr
, decl
->namedTypeNs
);
8829 decl
->value
= xmlSchemaGetProp(ctxt
, node
, "default");
8830 attr
= xmlSchemaGetPropNode(node
, "fixed");
8832 fixed
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
8833 if (decl
->value
!= NULL
) {
8836 * default and fixed must not both be present.
8838 xmlSchemaPMutualExclAttrErr(ctxt
,
8839 XML_SCHEMAP_SRC_ELEMENT_1
,
8840 NULL
, attr
, "default", "fixed");
8842 decl
->flags
|= XML_SCHEMAS_ELEM_FIXED
;
8843 decl
->value
= fixed
;
8847 * And now for the children...
8849 if (IS_SCHEMA(child
, "complexType")) {
8852 * "type" and either <simpleType> or <complexType> are mutually
8855 if (decl
->namedType
!= NULL
) {
8856 xmlSchemaPContentErr(ctxt
,
8857 XML_SCHEMAP_SRC_ELEMENT_3
,
8859 "The attribute 'type' and the <complexType> child are "
8860 "mutually exclusive", NULL
);
8862 WXS_ELEM_TYPEDEF(decl
) = xmlSchemaParseComplexType(ctxt
, schema
, child
, 0);
8863 child
= child
->next
;
8864 } else if (IS_SCHEMA(child
, "simpleType")) {
8867 * "type" and either <simpleType> or <complexType> are
8868 * mutually exclusive
8870 if (decl
->namedType
!= NULL
) {
8871 xmlSchemaPContentErr(ctxt
,
8872 XML_SCHEMAP_SRC_ELEMENT_3
,
8874 "The attribute 'type' and the <simpleType> child are "
8875 "mutually exclusive", NULL
);
8877 WXS_ELEM_TYPEDEF(decl
) = xmlSchemaParseSimpleType(ctxt
, schema
, child
, 0);
8878 child
= child
->next
;
8880 while ((IS_SCHEMA(child
, "unique")) ||
8881 (IS_SCHEMA(child
, "key")) || (IS_SCHEMA(child
, "keyref"))) {
8882 if (IS_SCHEMA(child
, "unique")) {
8883 curIDC
= xmlSchemaParseIDC(ctxt
, schema
, child
,
8884 XML_SCHEMA_TYPE_IDC_UNIQUE
, decl
->targetNamespace
);
8885 } else if (IS_SCHEMA(child
, "key")) {
8886 curIDC
= xmlSchemaParseIDC(ctxt
, schema
, child
,
8887 XML_SCHEMA_TYPE_IDC_KEY
, decl
->targetNamespace
);
8888 } else if (IS_SCHEMA(child
, "keyref")) {
8889 curIDC
= xmlSchemaParseIDC(ctxt
, schema
, child
,
8890 XML_SCHEMA_TYPE_IDC_KEYREF
, decl
->targetNamespace
);
8892 if (lastIDC
!= NULL
)
8893 lastIDC
->next
= curIDC
;
8895 decl
->idcs
= (void *) curIDC
;
8897 child
= child
->next
;
8899 if (child
!= NULL
) {
8900 xmlSchemaPContentErr(ctxt
,
8901 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
8903 NULL
, "(annotation?, ((simpleType | complexType)?, "
8904 "(unique | key | keyref)*))");
8906 decl
->annot
= annot
;
8909 * NOTE: Element Declaration Representation OK 4. will be checked at a
8914 return ((xmlSchemaBasicItemPtr
) decl
);
8916 particle
->children
= (xmlSchemaTreeItemPtr
) decl
;
8917 return ((xmlSchemaBasicItemPtr
) particle
);
8922 if (annot
!= NULL
) {
8923 if (particle
!= NULL
)
8924 particle
->annot
= NULL
;
8927 xmlSchemaFreeAnnot(annot
);
8933 * xmlSchemaParseUnion:
8934 * @ctxt: a schema validation context
8935 * @schema: the schema being built
8936 * @node: a subtree containing XML Schema information
8938 * parse a XML schema Union definition
8939 * *WARNING* this interface is highly subject to change
8941 * Returns -1 in case of internal error, 0 in case of success and a positive
8942 * error code otherwise.
8945 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
8948 xmlSchemaTypePtr type
;
8949 xmlNodePtr child
= NULL
;
8951 const xmlChar
*cur
= NULL
;
8953 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
8955 /* Not a component, don't create it. */
8956 type
= ctxt
->ctxtType
;
8958 * Mark the simple type as being of variety "union".
8960 type
->flags
|= XML_SCHEMAS_TYPE_VARIETY_UNION
;
8962 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8963 * then the `simple ur-type definition`."
8965 type
->baseType
= xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE
);
8967 * Check for illegal attributes.
8969 attr
= node
->properties
;
8970 while (attr
!= NULL
) {
8971 if (attr
->ns
== NULL
) {
8972 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
8973 (!xmlStrEqual(attr
->name
, BAD_CAST
"memberTypes"))) {
8974 xmlSchemaPIllegalAttrErr(ctxt
,
8975 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8977 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
8978 xmlSchemaPIllegalAttrErr(ctxt
,
8979 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
8983 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
8985 * Attribute "memberTypes". This is a list of QNames.
8986 * TODO: Check the value to contain anything.
8988 attr
= xmlSchemaGetPropNode(node
, "memberTypes");
8992 const xmlChar
*localName
, *nsName
;
8993 xmlSchemaTypeLinkPtr link
, lastLink
= NULL
;
8994 xmlSchemaQNameRefPtr ref
;
8996 cur
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
8999 while (IS_BLANK_CH(*cur
))
9002 while ((*end
!= 0) && (!(IS_BLANK_CH(*end
))))
9006 tmp
= xmlStrndup(cur
, end
- cur
);
9007 if (xmlSchemaPValAttrNodeQNameValue(ctxt
, schema
,
9008 NULL
, attr
, BAD_CAST tmp
, &nsName
, &localName
) == 0) {
9010 * Create the member type link.
9012 link
= (xmlSchemaTypeLinkPtr
)
9013 xmlMalloc(sizeof(xmlSchemaTypeLink
));
9015 xmlSchemaPErrMemory(ctxt
, "xmlSchemaParseUnion, "
9016 "allocating a type link", NULL
);
9021 if (lastLink
== NULL
)
9022 type
->memberTypes
= link
;
9024 lastLink
->next
= link
;
9027 * Create a reference item.
9029 ref
= xmlSchemaNewQNameRef(ctxt
, XML_SCHEMA_TYPE_SIMPLE
,
9036 * Assign the reference to the link, it will be resolved
9037 * later during fixup of the union simple type.
9039 link
->type
= (xmlSchemaTypePtr
) ref
;
9043 } while (*cur
!= 0);
9047 * And now for the children...
9049 child
= node
->children
;
9050 if (IS_SCHEMA(child
, "annotation")) {
9052 * Add the annotation to the simple type ancestor.
9054 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) type
,
9055 xmlSchemaParseAnnotation(ctxt
, child
, 1));
9056 child
= child
->next
;
9058 if (IS_SCHEMA(child
, "simpleType")) {
9059 xmlSchemaTypePtr subtype
, last
= NULL
;
9062 * Anchor the member types in the "subtypes" field of the
9065 while (IS_SCHEMA(child
, "simpleType")) {
9066 subtype
= (xmlSchemaTypePtr
)
9067 xmlSchemaParseSimpleType(ctxt
, schema
, child
, 0);
9068 if (subtype
!= NULL
) {
9070 type
->subtypes
= subtype
;
9073 last
->next
= subtype
;
9078 child
= child
->next
;
9081 if (child
!= NULL
) {
9082 xmlSchemaPContentErr(ctxt
,
9083 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
9084 NULL
, node
, child
, NULL
, "(annotation?, simpleType*)");
9086 if ((attr
== NULL
) && (type
->subtypes
== NULL
)) {
9088 * src-union-memberTypes-or-simpleTypes
9089 * Either the memberTypes [attribute] of the <union> element must
9090 * be non-empty or there must be at least one simpleType [child].
9092 xmlSchemaPCustomErr(ctxt
,
9093 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES
,
9095 "Either the attribute 'memberTypes' or "
9096 "at least one <simpleType> child must be present", NULL
);
9102 * xmlSchemaParseList:
9103 * @ctxt: a schema validation context
9104 * @schema: the schema being built
9105 * @node: a subtree containing XML Schema information
9107 * parse a XML schema List definition
9108 * *WARNING* this interface is highly subject to change
9110 * Returns -1 in case of error, 0 if the declaration is improper and
9111 * 1 in case of success.
9113 static xmlSchemaTypePtr
9114 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
9117 xmlSchemaTypePtr type
;
9118 xmlNodePtr child
= NULL
;
9121 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
9123 /* Not a component, don't create it. */
9124 type
= ctxt
->ctxtType
;
9126 * Mark the type as being of variety "list".
9128 type
->flags
|= XML_SCHEMAS_TYPE_VARIETY_LIST
;
9130 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
9131 * then the `simple ur-type definition`."
9133 type
->baseType
= xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE
);
9135 * Check for illegal attributes.
9137 attr
= node
->properties
;
9138 while (attr
!= NULL
) {
9139 if (attr
->ns
== NULL
) {
9140 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
9141 (!xmlStrEqual(attr
->name
, BAD_CAST
"itemType"))) {
9142 xmlSchemaPIllegalAttrErr(ctxt
,
9143 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9145 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
9146 xmlSchemaPIllegalAttrErr(ctxt
,
9147 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9152 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
9155 * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
9156 * fields for holding the reference to the itemType.
9158 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
9161 xmlSchemaPValAttrQName(ctxt
, schema
, NULL
,
9162 node
, "itemType", &(type
->baseNs
), &(type
->base
));
9164 * And now for the children...
9166 child
= node
->children
;
9167 if (IS_SCHEMA(child
, "annotation")) {
9168 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) type
,
9169 xmlSchemaParseAnnotation(ctxt
, child
, 1));
9170 child
= child
->next
;
9172 if (IS_SCHEMA(child
, "simpleType")) {
9174 * src-list-itemType-or-simpleType
9175 * Either the itemType [attribute] or the <simpleType> [child] of
9176 * the <list> element must be present, but not both.
9178 if (type
->base
!= NULL
) {
9179 xmlSchemaPCustomErr(ctxt
,
9180 XML_SCHEMAP_SRC_SIMPLE_TYPE_1
,
9182 "The attribute 'itemType' and the <simpleType> child "
9183 "are mutually exclusive", NULL
);
9185 type
->subtypes
= xmlSchemaParseSimpleType(ctxt
, schema
, child
, 0);
9187 child
= child
->next
;
9188 } else if (type
->base
== NULL
) {
9189 xmlSchemaPCustomErr(ctxt
,
9190 XML_SCHEMAP_SRC_SIMPLE_TYPE_1
,
9192 "Either the attribute 'itemType' or the <simpleType> child "
9193 "must be present", NULL
);
9195 if (child
!= NULL
) {
9196 xmlSchemaPContentErr(ctxt
,
9197 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
9198 NULL
, node
, child
, NULL
, "(annotation?, simpleType?)");
9200 if ((type
->base
== NULL
) &&
9201 (type
->subtypes
== NULL
) &&
9202 (xmlSchemaGetPropNode(node
, "itemType") == NULL
)) {
9203 xmlSchemaPCustomErr(ctxt
,
9204 XML_SCHEMAP_SRC_SIMPLE_TYPE_1
,
9206 "Either the attribute 'itemType' or the <simpleType> child "
9207 "must be present", NULL
);
9213 * xmlSchemaParseSimpleType:
9214 * @ctxt: a schema validation context
9215 * @schema: the schema being built
9216 * @node: a subtree containing XML Schema information
9218 * parse a XML schema Simple Type definition
9219 * *WARNING* this interface is highly subject to change
9221 * Returns -1 in case of error, 0 if the declaration is improper and
9222 * 1 in case of success.
9224 static xmlSchemaTypePtr
9225 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
9226 xmlNodePtr node
, int topLevel
)
9228 xmlSchemaTypePtr type
, oldCtxtType
;
9229 xmlNodePtr child
= NULL
;
9230 const xmlChar
*attrValue
= NULL
;
9232 int hasRestriction
= 0;
9234 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
9238 attr
= xmlSchemaGetPropNode(node
, "name");
9240 xmlSchemaPMissingAttrErr(ctxt
,
9241 XML_SCHEMAP_S4S_ATTR_MISSING
,
9246 if (xmlSchemaPValAttrNode(ctxt
,
9248 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &attrValue
) != 0)
9251 * Skip built-in types.
9254 xmlSchemaTypePtr biType
;
9256 if (ctxt
->isRedefine
) {
9258 * REDEFINE: Disallow redefinition of built-in-types.
9259 * TODO: It seems that the spec does not say anything
9262 xmlSchemaPCustomErr(ctxt
, XML_SCHEMAP_SRC_REDEFINE
,
9264 "Redefinition of built-in simple types is not "
9268 biType
= xmlSchemaGetPredefinedType(attrValue
, xmlSchemaNs
);
9276 * SPEC "The `actual value` of the targetNamespace [attribute]
9277 * of the <schema> ancestor element information item if present,
9278 * otherwise `absent`.
9280 if (topLevel
== 0) {
9281 #ifdef ENABLE_NAMED_LOCALS
9285 * Parse as local simple type definition.
9287 #ifdef ENABLE_NAMED_LOCALS
9288 snprintf(buf
, 39, "#ST%d", ctxt
->counter
++ + 1);
9289 type
= xmlSchemaAddType(ctxt
, schema
,
9290 XML_SCHEMA_TYPE_SIMPLE
,
9291 xmlDictLookup(ctxt
->dict
, (const xmlChar
*)buf
, -1),
9292 ctxt
->targetNamespace
, node
, 0);
9294 type
= xmlSchemaAddType(ctxt
, schema
,
9295 XML_SCHEMA_TYPE_SIMPLE
,
9296 NULL
, ctxt
->targetNamespace
, node
, 0);
9300 type
->type
= XML_SCHEMA_TYPE_SIMPLE
;
9301 type
->contentType
= XML_SCHEMA_CONTENT_SIMPLE
;
9303 * Check for illegal attributes.
9305 attr
= node
->properties
;
9306 while (attr
!= NULL
) {
9307 if (attr
->ns
== NULL
) {
9308 if (!xmlStrEqual(attr
->name
, BAD_CAST
"id")) {
9309 xmlSchemaPIllegalAttrErr(ctxt
,
9310 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9312 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
9313 xmlSchemaPIllegalAttrErr(ctxt
,
9314 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9320 * Parse as global simple type definition.
9322 * Note that attrValue is the value of the attribute "name" here.
9324 type
= xmlSchemaAddType(ctxt
, schema
, XML_SCHEMA_TYPE_SIMPLE
,
9325 attrValue
, ctxt
->targetNamespace
, node
, 1);
9328 type
->type
= XML_SCHEMA_TYPE_SIMPLE
;
9329 type
->contentType
= XML_SCHEMA_CONTENT_SIMPLE
;
9330 type
->flags
|= XML_SCHEMAS_TYPE_GLOBAL
;
9332 * Check for illegal attributes.
9334 attr
= node
->properties
;
9335 while (attr
!= NULL
) {
9336 if (attr
->ns
== NULL
) {
9337 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
9338 (!xmlStrEqual(attr
->name
, BAD_CAST
"name")) &&
9339 (!xmlStrEqual(attr
->name
, BAD_CAST
"final"))) {
9340 xmlSchemaPIllegalAttrErr(ctxt
,
9341 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9343 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
9344 xmlSchemaPIllegalAttrErr(ctxt
,
9345 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9350 * Attribute "final".
9352 attr
= xmlSchemaGetPropNode(node
, "final");
9354 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION
)
9355 type
->flags
|= XML_SCHEMAS_TYPE_FINAL_RESTRICTION
;
9356 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_LIST
)
9357 type
->flags
|= XML_SCHEMAS_TYPE_FINAL_LIST
;
9358 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_UNION
)
9359 type
->flags
|= XML_SCHEMAS_TYPE_FINAL_UNION
;
9361 attrValue
= xmlSchemaGetProp(ctxt
, node
, "final");
9362 if (xmlSchemaPValAttrBlockFinal(attrValue
, &(type
->flags
),
9363 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION
, -1,
9364 XML_SCHEMAS_TYPE_FINAL_LIST
,
9365 XML_SCHEMAS_TYPE_FINAL_UNION
) != 0) {
9367 xmlSchemaPSimpleTypeErr(ctxt
,
9368 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
9369 WXS_BASIC_CAST type
, (xmlNodePtr
) attr
,
9370 NULL
, "(#all | List of (list | union | restriction)",
9371 attrValue
, NULL
, NULL
, NULL
);
9375 type
->targetNamespace
= ctxt
->targetNamespace
;
9376 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
9378 * And now for the children...
9380 oldCtxtType
= ctxt
->ctxtType
;
9382 ctxt
->ctxtType
= type
;
9384 child
= node
->children
;
9385 if (IS_SCHEMA(child
, "annotation")) {
9386 type
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
9387 child
= child
->next
;
9389 if (child
== NULL
) {
9390 xmlSchemaPContentErr(ctxt
, XML_SCHEMAP_S4S_ELEM_MISSING
,
9391 NULL
, node
, child
, NULL
,
9392 "(annotation?, (restriction | list | union))");
9393 } else if (IS_SCHEMA(child
, "restriction")) {
9394 xmlSchemaParseRestriction(ctxt
, schema
, child
,
9395 XML_SCHEMA_TYPE_SIMPLE
);
9397 child
= child
->next
;
9398 } else if (IS_SCHEMA(child
, "list")) {
9399 xmlSchemaParseList(ctxt
, schema
, child
);
9400 child
= child
->next
;
9401 } else if (IS_SCHEMA(child
, "union")) {
9402 xmlSchemaParseUnion(ctxt
, schema
, child
);
9403 child
= child
->next
;
9405 if (child
!= NULL
) {
9406 xmlSchemaPContentErr(ctxt
, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
9407 NULL
, node
, child
, NULL
,
9408 "(annotation?, (restriction | list | union))");
9411 * REDEFINE: SPEC src-redefine (5)
9412 * "Within the [children], each <simpleType> must have a
9413 * <restriction> among its [children] ... the `actual value` of whose
9414 * base [attribute] must be the same as the `actual value` of its own
9415 * name attribute plus target namespace;"
9417 if (topLevel
&& ctxt
->isRedefine
&& (! hasRestriction
)) {
9418 xmlSchemaPCustomErr(ctxt
, XML_SCHEMAP_SRC_REDEFINE
,
9419 NULL
, node
, "This is a redefinition, thus the "
9420 "<simpleType> must have a <restriction> child", NULL
);
9423 ctxt
->ctxtType
= oldCtxtType
;
9428 * xmlSchemaParseModelGroupDefRef:
9429 * @ctxt: the parser context
9430 * @schema: the schema being built
9433 * Parses a reference to a model group definition.
9435 * We will return a particle component with a qname-component or
9436 * NULL in case of an error.
9438 static xmlSchemaTreeItemPtr
9439 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt
,
9440 xmlSchemaPtr schema
,
9443 xmlSchemaParticlePtr item
;
9444 xmlNodePtr child
= NULL
;
9446 const xmlChar
*ref
= NULL
, *refNs
= NULL
;
9449 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
9452 attr
= xmlSchemaGetPropNode(node
, "ref");
9454 xmlSchemaPMissingAttrErr(ctxt
,
9455 XML_SCHEMAP_S4S_ATTR_MISSING
,
9456 NULL
, node
, "ref", NULL
);
9458 } else if (xmlSchemaPValAttrNodeQName(ctxt
, schema
, NULL
,
9459 attr
, &refNs
, &ref
) != 0) {
9462 xmlSchemaCheckReference(ctxt
, schema
, node
, attr
, refNs
);
9463 min
= xmlGetMinOccurs(ctxt
, node
, 0, -1, 1, "xs:nonNegativeInteger");
9464 max
= xmlGetMaxOccurs(ctxt
, node
, 0, UNBOUNDED
, 1,
9465 "(xs:nonNegativeInteger | unbounded)");
9467 * Check for illegal attributes.
9469 attr
= node
->properties
;
9470 while (attr
!= NULL
) {
9471 if (attr
->ns
== NULL
) {
9472 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"ref")) &&
9473 (!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
9474 (!xmlStrEqual(attr
->name
, BAD_CAST
"minOccurs")) &&
9475 (!xmlStrEqual(attr
->name
, BAD_CAST
"maxOccurs"))) {
9476 xmlSchemaPIllegalAttrErr(ctxt
,
9477 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9479 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
9480 xmlSchemaPIllegalAttrErr(ctxt
,
9481 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9485 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
9486 item
= xmlSchemaAddParticle(ctxt
, node
, min
, max
);
9490 * Create a qname-reference and set as the term; it will be substituted
9491 * for the model group after the reference has been resolved.
9493 item
->children
= (xmlSchemaTreeItemPtr
)
9494 xmlSchemaNewQNameRef(ctxt
, XML_SCHEMA_TYPE_GROUP
, ref
, refNs
);
9495 xmlSchemaPCheckParticleCorrect_2(ctxt
, item
, node
, min
, max
);
9497 * And now for the children...
9499 child
= node
->children
;
9500 /* TODO: Is annotation even allowed for a model group reference? */
9501 if (IS_SCHEMA(child
, "annotation")) {
9503 * TODO: What to do exactly with the annotation?
9505 item
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
9506 child
= child
->next
;
9508 if (child
!= NULL
) {
9509 xmlSchemaPContentErr(ctxt
,
9510 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
9511 NULL
, node
, child
, NULL
,
9515 * Corresponds to no component at all if minOccurs==maxOccurs==0.
9517 if ((min
== 0) && (max
== 0))
9520 return ((xmlSchemaTreeItemPtr
) item
);
9524 * xmlSchemaParseModelGroupDefinition:
9525 * @ctxt: a schema validation context
9526 * @schema: the schema being built
9527 * @node: a subtree containing XML Schema information
9529 * Parses a XML schema model group definition.
9531 * Note that the constraint src-redefine (6.2) can't be applied until
9532 * references have been resolved. So we will do this at the
9533 * component fixup level.
9535 * *WARNING* this interface is highly subject to change
9537 * Returns -1 in case of error, 0 if the declaration is improper and
9538 * 1 in case of success.
9540 static xmlSchemaModelGroupDefPtr
9541 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt
,
9542 xmlSchemaPtr schema
,
9545 xmlSchemaModelGroupDefPtr item
;
9546 xmlNodePtr child
= NULL
;
9548 const xmlChar
*name
;
9550 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
9553 attr
= xmlSchemaGetPropNode(node
, "name");
9555 xmlSchemaPMissingAttrErr(ctxt
,
9556 XML_SCHEMAP_S4S_ATTR_MISSING
,
9560 } else if (xmlSchemaPValAttrNode(ctxt
, NULL
, attr
,
9561 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &name
) != 0) {
9564 item
= xmlSchemaAddModelGroupDefinition(ctxt
, schema
, name
,
9565 ctxt
->targetNamespace
, node
);
9569 * Check for illegal attributes.
9571 attr
= node
->properties
;
9572 while (attr
!= NULL
) {
9573 if (attr
->ns
== NULL
) {
9574 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"name")) &&
9575 (!xmlStrEqual(attr
->name
, BAD_CAST
"id"))) {
9576 xmlSchemaPIllegalAttrErr(ctxt
,
9577 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9579 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
9580 xmlSchemaPIllegalAttrErr(ctxt
,
9581 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
9585 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
9587 * And now for the children...
9589 child
= node
->children
;
9590 if (IS_SCHEMA(child
, "annotation")) {
9591 item
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
9592 child
= child
->next
;
9594 if (IS_SCHEMA(child
, "all")) {
9595 item
->children
= xmlSchemaParseModelGroup(ctxt
, schema
, child
,
9596 XML_SCHEMA_TYPE_ALL
, 0);
9597 child
= child
->next
;
9598 } else if (IS_SCHEMA(child
, "choice")) {
9599 item
->children
= xmlSchemaParseModelGroup(ctxt
, schema
, child
,
9600 XML_SCHEMA_TYPE_CHOICE
, 0);
9601 child
= child
->next
;
9602 } else if (IS_SCHEMA(child
, "sequence")) {
9603 item
->children
= xmlSchemaParseModelGroup(ctxt
, schema
, child
,
9604 XML_SCHEMA_TYPE_SEQUENCE
, 0);
9605 child
= child
->next
;
9610 if (child
!= NULL
) {
9611 xmlSchemaPContentErr(ctxt
,
9612 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
9613 NULL
, node
, child
, NULL
,
9614 "(annotation?, (all | choice | sequence)?)");
9620 * xmlSchemaCleanupDoc:
9621 * @ctxt: a schema validation context
9622 * @node: the root of the document.
9624 * removes unwanted nodes in a schemas document tree
9627 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt
, xmlNodePtr root
)
9629 xmlNodePtr
delete, cur
;
9631 if ((ctxt
== NULL
) || (root
== NULL
)) return;
9634 * Remove all the blank text nodes
9638 while (cur
!= NULL
) {
9639 if (delete != NULL
) {
9640 xmlUnlinkNode(delete);
9641 xmlFreeNode(delete);
9644 if (cur
->type
== XML_TEXT_NODE
) {
9645 if (IS_BLANK_NODE(cur
)) {
9646 if (xmlNodeGetSpacePreserve(cur
) != 1) {
9650 } else if ((cur
->type
!= XML_ELEMENT_NODE
) &&
9651 (cur
->type
!= XML_CDATA_SECTION_NODE
)) {
9659 if (cur
->children
!= NULL
) {
9660 if ((cur
->children
->type
!= XML_ENTITY_DECL
) &&
9661 (cur
->children
->type
!= XML_ENTITY_REF_NODE
) &&
9662 (cur
->children
->type
!= XML_ENTITY_NODE
)) {
9663 cur
= cur
->children
;
9668 if (cur
->next
!= NULL
) {
9681 if (cur
->next
!= NULL
) {
9685 } while (cur
!= NULL
);
9687 if (delete != NULL
) {
9688 xmlUnlinkNode(delete);
9689 xmlFreeNode(delete);
9696 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema
)
9698 if (schema
->flags
& XML_SCHEMAS_QUALIF_ELEM
)
9699 schema
->flags
^= XML_SCHEMAS_QUALIF_ELEM
;
9701 if (schema
->flags
& XML_SCHEMAS_QUALIF_ATTR
)
9702 schema
->flags
^= XML_SCHEMAS_QUALIF_ATTR
;
9704 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_EXTENSION
)
9705 schema
->flags
^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION
;
9706 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION
)
9707 schema
->flags
^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION
;
9708 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_LIST
)
9709 schema
->flags
^= XML_SCHEMAS_FINAL_DEFAULT_LIST
;
9710 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_UNION
)
9711 schema
->flags
^= XML_SCHEMAS_FINAL_DEFAULT_UNION
;
9713 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION
)
9714 schema
->flags
^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION
;
9715 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION
)
9716 schema
->flags
^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION
;
9717 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION
)
9718 schema
->flags
^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION
;
9722 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt
,
9723 xmlSchemaPtr schema
,
9728 int res
= 0, oldErrs
= ctxt
->nberrors
;
9731 * Those flags should be moved to the parser context flags,
9732 * since they are not visible at the component level. I.e.
9733 * they are used if processing schema *documents* only.
9735 res
= xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
9739 * Since the version is of type xs:token, we won't bother to
9743 attr = xmlSchemaGetPropNode(node, "version");
9745 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
9746 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
9750 attr
= xmlSchemaGetPropNode(node
, "targetNamespace");
9752 res
= xmlSchemaPValAttrNode(ctxt
, NULL
, attr
,
9753 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
), NULL
);
9756 ctxt
->stop
= XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
;
9760 attr
= xmlSchemaGetPropNode(node
, "elementFormDefault");
9762 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
9763 res
= xmlSchemaPValAttrFormDefault(val
, &schema
->flags
,
9764 XML_SCHEMAS_QUALIF_ELEM
);
9767 xmlSchemaPSimpleTypeErr(ctxt
,
9768 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE
,
9769 NULL
, (xmlNodePtr
) attr
, NULL
,
9770 "(qualified | unqualified)", val
, NULL
, NULL
, NULL
);
9773 attr
= xmlSchemaGetPropNode(node
, "attributeFormDefault");
9775 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
9776 res
= xmlSchemaPValAttrFormDefault(val
, &schema
->flags
,
9777 XML_SCHEMAS_QUALIF_ATTR
);
9780 xmlSchemaPSimpleTypeErr(ctxt
,
9781 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE
,
9782 NULL
, (xmlNodePtr
) attr
, NULL
,
9783 "(qualified | unqualified)", val
, NULL
, NULL
, NULL
);
9786 attr
= xmlSchemaGetPropNode(node
, "finalDefault");
9788 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
9789 res
= xmlSchemaPValAttrBlockFinal(val
, &(schema
->flags
), -1,
9790 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION
,
9791 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION
,
9793 XML_SCHEMAS_FINAL_DEFAULT_LIST
,
9794 XML_SCHEMAS_FINAL_DEFAULT_UNION
);
9797 xmlSchemaPSimpleTypeErr(ctxt
,
9798 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
9799 NULL
, (xmlNodePtr
) attr
, NULL
,
9800 "(#all | List of (extension | restriction | list | union))",
9801 val
, NULL
, NULL
, NULL
);
9804 attr
= xmlSchemaGetPropNode(node
, "blockDefault");
9806 val
= xmlSchemaGetNodeContent(ctxt
, (xmlNodePtr
) attr
);
9807 res
= xmlSchemaPValAttrBlockFinal(val
, &(schema
->flags
), -1,
9808 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION
,
9809 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION
,
9810 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION
, -1, -1);
9813 xmlSchemaPSimpleTypeErr(ctxt
,
9814 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
9815 NULL
, (xmlNodePtr
) attr
, NULL
,
9816 "(#all | List of (extension | restriction | substitution))",
9817 val
, NULL
, NULL
, NULL
);
9822 if (oldErrs
!= ctxt
->nberrors
)
9830 * xmlSchemaParseSchemaTopLevel:
9831 * @ctxt: a schema validation context
9832 * @schema: the schemas
9833 * @nodes: the list of top level nodes
9835 * Returns the internal XML Schema structure built from the resource or
9836 * NULL in case of error
9839 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt
,
9840 xmlSchemaPtr schema
, xmlNodePtr nodes
)
9843 xmlSchemaAnnotPtr annot
;
9844 int res
= 0, oldErrs
, tmpOldErrs
;
9846 if ((ctxt
== NULL
) || (schema
== NULL
) || (nodes
== NULL
))
9849 oldErrs
= ctxt
->nberrors
;
9851 while ((IS_SCHEMA(child
, "include")) ||
9852 (IS_SCHEMA(child
, "import")) ||
9853 (IS_SCHEMA(child
, "redefine")) ||
9854 (IS_SCHEMA(child
, "annotation"))) {
9855 if (IS_SCHEMA(child
, "annotation")) {
9856 annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
9857 if (schema
->annot
== NULL
)
9858 schema
->annot
= annot
;
9860 xmlSchemaFreeAnnot(annot
);
9861 } else if (IS_SCHEMA(child
, "import")) {
9862 tmpOldErrs
= ctxt
->nberrors
;
9863 res
= xmlSchemaParseImport(ctxt
, schema
, child
);
9866 if (tmpOldErrs
!= ctxt
->nberrors
)
9868 } else if (IS_SCHEMA(child
, "include")) {
9869 tmpOldErrs
= ctxt
->nberrors
;
9870 res
= xmlSchemaParseInclude(ctxt
, schema
, child
);
9873 if (tmpOldErrs
!= ctxt
->nberrors
)
9875 } else if (IS_SCHEMA(child
, "redefine")) {
9876 tmpOldErrs
= ctxt
->nberrors
;
9877 res
= xmlSchemaParseRedefine(ctxt
, schema
, child
);
9880 if (tmpOldErrs
!= ctxt
->nberrors
)
9883 child
= child
->next
;
9886 * URGENT TODO: Change the functions to return int results.
9887 * We need especially to catch internal errors.
9889 while (child
!= NULL
) {
9890 if (IS_SCHEMA(child
, "complexType")) {
9891 xmlSchemaParseComplexType(ctxt
, schema
, child
, 1);
9892 child
= child
->next
;
9893 } else if (IS_SCHEMA(child
, "simpleType")) {
9894 xmlSchemaParseSimpleType(ctxt
, schema
, child
, 1);
9895 child
= child
->next
;
9896 } else if (IS_SCHEMA(child
, "element")) {
9897 xmlSchemaParseElement(ctxt
, schema
, child
, NULL
, 1);
9898 child
= child
->next
;
9899 } else if (IS_SCHEMA(child
, "attribute")) {
9900 xmlSchemaParseGlobalAttribute(ctxt
, schema
, child
);
9901 child
= child
->next
;
9902 } else if (IS_SCHEMA(child
, "attributeGroup")) {
9903 xmlSchemaParseAttributeGroupDefinition(ctxt
, schema
, child
);
9904 child
= child
->next
;
9905 } else if (IS_SCHEMA(child
, "group")) {
9906 xmlSchemaParseModelGroupDefinition(ctxt
, schema
, child
);
9907 child
= child
->next
;
9908 } else if (IS_SCHEMA(child
, "notation")) {
9909 xmlSchemaParseNotation(ctxt
, schema
, child
);
9910 child
= child
->next
;
9912 xmlSchemaPContentErr(ctxt
,
9913 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
9914 NULL
, child
->parent
, child
,
9915 NULL
, "((include | import | redefine | annotation)*, "
9916 "(((simpleType | complexType | group | attributeGroup) "
9917 "| element | attribute | notation), annotation*)*)");
9918 child
= child
->next
;
9920 while (IS_SCHEMA(child
, "annotation")) {
9922 * TODO: We should add all annotations.
9924 annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
9925 if (schema
->annot
== NULL
)
9926 schema
->annot
= annot
;
9928 xmlSchemaFreeAnnot(annot
);
9929 child
= child
->next
;
9933 ctxt
->ctxtType
= NULL
;
9934 if (oldErrs
!= ctxt
->nberrors
)
9941 static xmlSchemaSchemaRelationPtr
9942 xmlSchemaSchemaRelationCreate(void)
9944 xmlSchemaSchemaRelationPtr ret
;
9946 ret
= (xmlSchemaSchemaRelationPtr
)
9947 xmlMalloc(sizeof(xmlSchemaSchemaRelation
));
9949 xmlSchemaPErrMemory(NULL
, "allocating schema relation", NULL
);
9952 memset(ret
, 0, sizeof(xmlSchemaSchemaRelation
));
9958 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel
)
9965 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef
)
9967 xmlSchemaRedefPtr prev
;
9969 while (redef
!= NULL
) {
9971 redef
= redef
->next
;
9977 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con
)
9980 * After the construction context has been freed, there will be
9981 * no schema graph available any more. Only the schema buckets
9982 * will stay alive, which are put into the "schemasImports" and
9983 * "includes" slots of the xmlSchema.
9985 if (con
->buckets
!= NULL
)
9986 xmlSchemaItemListFree(con
->buckets
);
9987 if (con
->pending
!= NULL
)
9988 xmlSchemaItemListFree(con
->pending
);
9989 if (con
->substGroups
!= NULL
)
9990 xmlHashFree(con
->substGroups
, xmlSchemaSubstGroupFreeEntry
);
9991 if (con
->redefs
!= NULL
)
9992 xmlSchemaRedefListFree(con
->redefs
);
9993 if (con
->dict
!= NULL
)
9994 xmlDictFree(con
->dict
);
9998 static xmlSchemaConstructionCtxtPtr
9999 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict
)
10001 xmlSchemaConstructionCtxtPtr ret
;
10003 ret
= (xmlSchemaConstructionCtxtPtr
)
10004 xmlMalloc(sizeof(xmlSchemaConstructionCtxt
));
10006 xmlSchemaPErrMemory(NULL
,
10007 "allocating schema construction context", NULL
);
10010 memset(ret
, 0, sizeof(xmlSchemaConstructionCtxt
));
10012 ret
->buckets
= xmlSchemaItemListCreate();
10013 if (ret
->buckets
== NULL
) {
10014 xmlSchemaPErrMemory(NULL
,
10015 "allocating list of schema buckets", NULL
);
10019 ret
->pending
= xmlSchemaItemListCreate();
10020 if (ret
->pending
== NULL
) {
10021 xmlSchemaPErrMemory(NULL
,
10022 "allocating list of pending global components", NULL
);
10023 xmlSchemaConstructionCtxtFree(ret
);
10027 xmlDictReference(dict
);
10031 static xmlSchemaParserCtxtPtr
10032 xmlSchemaParserCtxtCreate(void)
10034 xmlSchemaParserCtxtPtr ret
;
10036 ret
= (xmlSchemaParserCtxtPtr
) xmlMalloc(sizeof(xmlSchemaParserCtxt
));
10038 xmlSchemaPErrMemory(NULL
, "allocating schema parser context",
10042 memset(ret
, 0, sizeof(xmlSchemaParserCtxt
));
10043 ret
->type
= XML_SCHEMA_CTXT_PARSER
;
10044 ret
->attrProhibs
= xmlSchemaItemListCreate();
10045 if (ret
->attrProhibs
== NULL
) {
10053 * xmlSchemaNewParserCtxtUseDict:
10054 * @URL: the location of the schema
10055 * @dict: the dictionary to be used
10057 * Create an XML Schemas parse context for that file/resource expected
10058 * to contain an XML Schemas file.
10060 * Returns the parser context or NULL in case of error
10062 static xmlSchemaParserCtxtPtr
10063 xmlSchemaNewParserCtxtUseDict(const char *URL
, xmlDictPtr dict
)
10065 xmlSchemaParserCtxtPtr ret
;
10067 ret
= xmlSchemaParserCtxtCreate();
10071 xmlDictReference(dict
);
10073 ret
->URL
= xmlDictLookup(dict
, (const xmlChar
*) URL
, -1);
10078 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt
)
10080 if (vctxt
->pctxt
== NULL
) {
10081 if (vctxt
->schema
!= NULL
)
10083 xmlSchemaNewParserCtxtUseDict("*", vctxt
->schema
->dict
);
10085 vctxt
->pctxt
= xmlSchemaNewParserCtxt("*");
10086 if (vctxt
->pctxt
== NULL
) {
10087 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
10088 "failed to create a temp. parser context");
10091 /* TODO: Pass user data. */
10092 xmlSchemaSetParserErrors(vctxt
->pctxt
, vctxt
->error
,
10093 vctxt
->warning
, vctxt
->errCtxt
);
10094 xmlSchemaSetParserStructuredErrors(vctxt
->pctxt
, vctxt
->serror
,
10101 * xmlSchemaGetSchemaBucket:
10102 * @pctxt: the schema parser context
10103 * @schemaLocation: the URI of the schema document
10105 * Returns a schema bucket if it was already parsed.
10107 * Returns a schema bucket if it was already parsed from
10108 * @schemaLocation, NULL otherwise.
10110 static xmlSchemaBucketPtr
10111 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt
,
10112 const xmlChar
*schemaLocation
)
10114 xmlSchemaBucketPtr cur
;
10115 xmlSchemaItemListPtr list
;
10117 list
= pctxt
->constructor
->buckets
;
10118 if (list
->nbItems
== 0)
10122 for (i
= 0; i
< list
->nbItems
; i
++) {
10123 cur
= (xmlSchemaBucketPtr
) list
->items
[i
];
10124 /* Pointer comparison! */
10125 if (cur
->schemaLocation
== schemaLocation
)
10132 static xmlSchemaBucketPtr
10133 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt
,
10134 const xmlChar
*schemaLocation
,
10135 const xmlChar
*targetNamespace
)
10137 xmlSchemaBucketPtr cur
;
10138 xmlSchemaItemListPtr list
;
10140 list
= pctxt
->constructor
->buckets
;
10141 if (list
->nbItems
== 0)
10145 for (i
= 0; i
< list
->nbItems
; i
++) {
10146 cur
= (xmlSchemaBucketPtr
) list
->items
[i
];
10147 /* Pointer comparison! */
10148 if ((cur
->origTargetNamespace
== NULL
) &&
10149 (cur
->schemaLocation
== schemaLocation
) &&
10150 (cur
->targetNamespace
== targetNamespace
))
10158 #define IS_BAD_SCHEMA_DOC(b) \
10159 (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10161 static xmlSchemaBucketPtr
10162 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt
,
10163 const xmlChar
*targetNamespace
,
10166 xmlSchemaBucketPtr cur
;
10167 xmlSchemaItemListPtr list
;
10169 list
= pctxt
->constructor
->buckets
;
10170 if (list
->nbItems
== 0)
10174 for (i
= 0; i
< list
->nbItems
; i
++) {
10175 cur
= (xmlSchemaBucketPtr
) list
->items
[i
];
10176 if ((! IS_BAD_SCHEMA_DOC(cur
)) &&
10177 (cur
->origTargetNamespace
== targetNamespace
) &&
10178 ((imported
&& cur
->imported
) ||
10179 ((!imported
) && (!cur
->imported
))))
10187 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt
,
10188 xmlSchemaPtr schema
,
10189 xmlSchemaBucketPtr bucket
)
10195 xmlSchemaBucketPtr oldbucket
= pctxt
->constructor
->bucket
;
10198 * Save old values; reset the *main* schema.
10199 * URGENT TODO: This is not good; move the per-document information
10200 * to the parser. Get rid of passing the main schema to the
10201 * parsing functions.
10203 oldFlags
= schema
->flags
;
10204 oldDoc
= schema
->doc
;
10205 if (schema
->flags
!= 0)
10206 xmlSchemaClearSchemaDefaults(schema
);
10207 schema
->doc
= bucket
->doc
;
10208 pctxt
->schema
= schema
;
10210 * Keep the current target namespace on the parser *not* on the
10213 pctxt
->targetNamespace
= bucket
->targetNamespace
;
10214 WXS_CONSTRUCTOR(pctxt
)->bucket
= bucket
;
10216 if ((bucket
->targetNamespace
!= NULL
) &&
10217 xmlStrEqual(bucket
->targetNamespace
, xmlSchemaNs
)) {
10219 * We are parsing the schema for schemas!
10223 /* Mark it as parsed, even if parsing fails. */
10225 /* Compile the schema doc. */
10226 node
= xmlDocGetRootElement(bucket
->doc
);
10227 ret
= xmlSchemaParseSchemaElement(pctxt
, schema
, node
);
10230 /* An empty schema; just get out. */
10231 if (node
->children
== NULL
)
10233 oldErrs
= pctxt
->nberrors
;
10234 ret
= xmlSchemaParseSchemaTopLevel(pctxt
, schema
, node
->children
);
10238 * TODO: Not nice, but I'm not 100% sure we will get always an error
10239 * as a result of the above functions; so better rely on pctxt->err
10242 if ((ret
== 0) && (oldErrs
!= pctxt
->nberrors
)) {
10248 WXS_CONSTRUCTOR(pctxt
)->bucket
= oldbucket
;
10249 /* Restore schema values. */
10250 schema
->doc
= oldDoc
;
10251 schema
->flags
= oldFlags
;
10256 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt
,
10257 xmlSchemaPtr schema
,
10258 xmlSchemaBucketPtr bucket
)
10260 xmlSchemaParserCtxtPtr newpctxt
;
10263 if (bucket
== NULL
)
10265 if (bucket
->parsed
) {
10266 PERROR_INT("xmlSchemaParseNewDoc",
10267 "reparsing a schema doc");
10270 if (bucket
->doc
== NULL
) {
10271 PERROR_INT("xmlSchemaParseNewDoc",
10272 "parsing a schema doc, but there's no doc");
10275 if (pctxt
->constructor
== NULL
) {
10276 PERROR_INT("xmlSchemaParseNewDoc",
10280 /* Create and init the temporary parser context. */
10281 newpctxt
= xmlSchemaNewParserCtxtUseDict(
10282 (const char *) bucket
->schemaLocation
, pctxt
->dict
);
10283 if (newpctxt
== NULL
)
10285 newpctxt
->constructor
= pctxt
->constructor
;
10287 * TODO: Can we avoid that the parser knows about the main schema?
10288 * It would be better if he knows about the current schema bucket
10291 newpctxt
->schema
= schema
;
10292 xmlSchemaSetParserErrors(newpctxt
, pctxt
->error
, pctxt
->warning
,
10294 xmlSchemaSetParserStructuredErrors(newpctxt
, pctxt
->serror
,
10296 newpctxt
->counter
= pctxt
->counter
;
10299 res
= xmlSchemaParseNewDocWithContext(newpctxt
, schema
, bucket
);
10301 /* Channel back errors and cleanup the temporary parser context. */
10304 pctxt
->nberrors
+= newpctxt
->nberrors
;
10305 pctxt
->counter
= newpctxt
->counter
;
10306 newpctxt
->constructor
= NULL
;
10307 /* Free the parser context. */
10308 xmlSchemaFreeParserCtxt(newpctxt
);
10313 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket
,
10314 xmlSchemaSchemaRelationPtr rel
)
10316 xmlSchemaSchemaRelationPtr cur
= bucket
->relations
;
10319 bucket
->relations
= rel
;
10322 while (cur
->next
!= NULL
)
10328 static const xmlChar
*
10329 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict
, const xmlChar
* location
,
10330 xmlNodePtr ctxtNode
)
10333 * Build an absolute location URI.
10335 if (location
!= NULL
) {
10336 if (ctxtNode
== NULL
)
10339 xmlChar
*base
, *URI
;
10340 const xmlChar
*ret
= NULL
;
10342 base
= xmlNodeGetBase(ctxtNode
->doc
, ctxtNode
);
10343 if (base
== NULL
) {
10344 URI
= xmlBuildURI(location
, ctxtNode
->doc
->URL
);
10346 URI
= xmlBuildURI(location
, base
);
10350 ret
= xmlDictLookup(dict
, URI
, -1);
10362 * xmlSchemaAddSchemaDoc:
10363 * @pctxt: a schema validation context
10364 * @schema: the schema being built
10365 * @node: a subtree containing XML Schema information
10367 * Parse an included (and to-be-redefined) XML schema document.
10369 * Returns 0 on success, a positive error code on errors and
10370 * -1 in case of an internal or API error.
10374 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt
,
10375 int type
, /* import or include or redefine */
10376 const xmlChar
*schemaLocation
,
10377 xmlDocPtr schemaDoc
,
10378 const char *schemaBuffer
,
10379 int schemaBufferLen
,
10380 xmlNodePtr invokingNode
,
10381 const xmlChar
*sourceTargetNamespace
,
10382 const xmlChar
*importNamespace
,
10383 xmlSchemaBucketPtr
*bucket
)
10385 const xmlChar
*targetNamespace
= NULL
;
10386 xmlSchemaSchemaRelationPtr relation
= NULL
;
10387 xmlDocPtr doc
= NULL
;
10388 int res
= 0, err
= 0, located
= 0, preserveDoc
= 0;
10389 xmlSchemaBucketPtr bkt
= NULL
;
10391 if (bucket
!= NULL
)
10395 case XML_SCHEMA_SCHEMA_IMPORT
:
10396 case XML_SCHEMA_SCHEMA_MAIN
:
10397 err
= XML_SCHEMAP_SRC_IMPORT
;
10399 case XML_SCHEMA_SCHEMA_INCLUDE
:
10400 err
= XML_SCHEMAP_SRC_INCLUDE
;
10402 case XML_SCHEMA_SCHEMA_REDEFINE
:
10403 err
= XML_SCHEMAP_SRC_REDEFINE
;
10408 /* Special handling for the main schema:
10409 * skip the location and relation logic and just parse the doc.
10410 * We need just a bucket to be returned in this case.
10412 if ((type
== XML_SCHEMA_SCHEMA_MAIN
) || (! WXS_HAS_BUCKETS(pctxt
)))
10415 /* Note that we expect the location to be an absolute URI. */
10416 if (schemaLocation
!= NULL
) {
10417 bkt
= xmlSchemaGetSchemaBucket(pctxt
, schemaLocation
);
10418 if ((bkt
!= NULL
) &&
10419 (pctxt
->constructor
->bucket
== bkt
)) {
10420 /* Report self-imports/inclusions/redefinitions. */
10422 xmlSchemaCustomErr(ACTXT_CAST pctxt
, err
,
10423 invokingNode
, NULL
,
10424 "The schema must not import/include/redefine itself",
10430 * Create a relation for the graph of schemas.
10432 relation
= xmlSchemaSchemaRelationCreate();
10433 if (relation
== NULL
)
10435 xmlSchemaSchemaRelationAddChild(pctxt
->constructor
->bucket
,
10437 relation
->type
= type
;
10440 * Save the namespace import information.
10442 if (WXS_IS_BUCKET_IMPMAIN(type
)) {
10443 relation
->importNamespace
= importNamespace
;
10444 if (schemaLocation
== NULL
) {
10446 * No location; this is just an import of the namespace.
10447 * Note that we don't assign a bucket to the relation
10452 targetNamespace
= importNamespace
;
10455 /* Did we already fetch the doc? */
10457 if ((WXS_IS_BUCKET_IMPMAIN(type
)) && (! bkt
->imported
)) {
10459 * We included/redefined and then try to import a schema,
10460 * but the new location provided for import was different.
10462 if (schemaLocation
== NULL
)
10463 schemaLocation
= BAD_CAST
"in_memory_buffer";
10464 if (!xmlStrEqual(schemaLocation
,
10465 bkt
->schemaLocation
)) {
10466 xmlSchemaCustomErr(ACTXT_CAST pctxt
, err
,
10467 invokingNode
, NULL
,
10468 "The schema document '%s' cannot be imported, since "
10469 "it was already included or redefined",
10470 schemaLocation
, NULL
);
10473 } else if ((! WXS_IS_BUCKET_IMPMAIN(type
)) && (bkt
->imported
)) {
10475 * We imported and then try to include/redefine a schema,
10476 * but the new location provided for the include/redefine
10479 if (schemaLocation
== NULL
)
10480 schemaLocation
= BAD_CAST
"in_memory_buffer";
10481 if (!xmlStrEqual(schemaLocation
,
10482 bkt
->schemaLocation
)) {
10483 xmlSchemaCustomErr(ACTXT_CAST pctxt
, err
,
10484 invokingNode
, NULL
,
10485 "The schema document '%s' cannot be included or "
10486 "redefined, since it was already imported",
10487 schemaLocation
, NULL
);
10493 if (WXS_IS_BUCKET_IMPMAIN(type
)) {
10495 * Given that the schemaLocation [attribute] is only a hint, it is open
10496 * to applications to ignore all but the first <import> for a given
10497 * namespace, regardless of the `actual value` of schemaLocation, but
10498 * such a strategy risks missing useful information when new
10499 * schemaLocations are offered.
10501 * We will use the first <import> that comes with a location.
10502 * Further <import>s *with* a location, will result in an error.
10503 * TODO: Better would be to just report a warning here, but
10504 * we'll try it this way until someone complains.
10506 * Schema Document Location Strategy:
10507 * 3 Based on the namespace name, identify an existing schema document,
10508 * either as a resource which is an XML document or a <schema> element
10509 * information item, in some local schema repository;
10510 * 5 Attempt to resolve the namespace name to locate such a resource.
10512 * NOTE: (3) and (5) are not supported.
10515 relation
->bucket
= bkt
;
10518 bkt
= xmlSchemaGetSchemaBucketByTNS(pctxt
,
10519 importNamespace
, 1);
10522 relation
->bucket
= bkt
;
10523 if (bkt
->schemaLocation
== NULL
) {
10524 /* First given location of the schema; load the doc. */
10525 bkt
->schemaLocation
= schemaLocation
;
10527 if (!xmlStrEqual(schemaLocation
,
10528 bkt
->schemaLocation
)) {
10530 * Additional location given; just skip it.
10531 * URGENT TODO: We should report a warning here.
10532 * res = XML_SCHEMAP_SRC_IMPORT;
10534 if (schemaLocation
== NULL
)
10535 schemaLocation
= BAD_CAST
"in_memory_buffer";
10537 xmlSchemaCustomWarning(ACTXT_CAST pctxt
,
10538 XML_SCHEMAP_WARN_SKIP_SCHEMA
,
10539 invokingNode
, NULL
,
10540 "Skipping import of schema located at '%s' for the "
10541 "namespace '%s', since this namespace was already "
10542 "imported with the schema located at '%s'",
10543 schemaLocation
, importNamespace
, bkt
->schemaLocation
);
10549 * No bucket + first location: load the doc and create a
10553 /* <include> and <redefine> */
10556 if ((bkt
->origTargetNamespace
== NULL
) &&
10557 (bkt
->targetNamespace
!= sourceTargetNamespace
)) {
10558 xmlSchemaBucketPtr chamel
;
10561 * Chameleon include/redefine: skip loading only if it was
10562 * already build for the targetNamespace of the including
10566 * URGENT TODO: If the schema is a chameleon-include then copy
10567 * the components into the including schema and modify the
10568 * targetNamespace of those components, do nothing otherwise.
10569 * NOTE: This is currently worked-around by compiling the
10570 * chameleon for every distinct including targetNamespace; thus
10571 * not performant at the moment.
10572 * TODO: Check when the namespace in wildcards for chameleons
10573 * needs to be converted: before we built wildcard intersections
10577 chamel
= xmlSchemaGetChameleonSchemaBucket(pctxt
,
10578 schemaLocation
, sourceTargetNamespace
);
10579 if (chamel
!= NULL
) {
10580 /* A fitting chameleon was already parsed; NOP. */
10581 relation
->bucket
= chamel
;
10585 * We need to parse the chameleon again for a different
10587 * CHAMELEON TODO: Optimize this by only parsing the
10588 * chameleon once, and then copying the components to
10589 * the new targetNamespace.
10593 relation
->bucket
= bkt
;
10598 if ((bkt
!= NULL
) && (bkt
->doc
!= NULL
)) {
10599 PERROR_INT("xmlSchemaAddSchemaDoc",
10600 "trying to load a schema doc, but a doc is already "
10601 "assigned to the schema bucket");
10607 * Load the document.
10609 if (schemaDoc
!= NULL
) {
10611 /* Don' free this one, since it was provided by the caller. */
10613 /* TODO: Does the context or the doc hold the location? */
10614 if (schemaDoc
->URL
!= NULL
)
10615 schemaLocation
= xmlDictLookup(pctxt
->dict
,
10616 schemaDoc
->URL
, -1);
10618 schemaLocation
= BAD_CAST
"in_memory_buffer";
10619 } else if ((schemaLocation
!= NULL
) || (schemaBuffer
!= NULL
)) {
10620 xmlParserCtxtPtr parserCtxt
;
10622 parserCtxt
= xmlNewParserCtxt();
10623 if (parserCtxt
== NULL
) {
10624 xmlSchemaPErrMemory(NULL
, "xmlSchemaGetDoc, "
10625 "allocating a parser context", NULL
);
10628 if ((pctxt
->dict
!= NULL
) && (parserCtxt
->dict
!= NULL
)) {
10630 * TODO: Do we have to burden the schema parser dict with all
10631 * the content of the schema doc?
10633 xmlDictFree(parserCtxt
->dict
);
10634 parserCtxt
->dict
= pctxt
->dict
;
10635 xmlDictReference(parserCtxt
->dict
);
10637 if (schemaLocation
!= NULL
) {
10638 /* Parse from file. */
10639 doc
= xmlCtxtReadFile(parserCtxt
, (const char *) schemaLocation
,
10640 NULL
, SCHEMAS_PARSE_OPTIONS
);
10641 } else if (schemaBuffer
!= NULL
) {
10642 /* Parse from memory buffer. */
10643 doc
= xmlCtxtReadMemory(parserCtxt
, schemaBuffer
, schemaBufferLen
,
10644 NULL
, NULL
, SCHEMAS_PARSE_OPTIONS
);
10645 schemaLocation
= BAD_CAST
"in_memory_buffer";
10647 doc
->URL
= xmlStrdup(schemaLocation
);
10651 * 2.1 The referent is (a fragment of) a resource which is an
10652 * XML document (see clause 1.1), which in turn corresponds to
10653 * a <schema> element information item in a well-formed information
10654 * set, which in turn corresponds to a valid schema.
10655 * TODO: (2.1) fragments of XML documents are not supported.
10657 * 2.2 The referent is a <schema> element information item in
10658 * a well-formed information set, which in turn corresponds
10659 * to a valid schema.
10660 * TODO: (2.2) is not supported.
10664 lerr
= xmlGetLastError();
10666 * Check if this a parser error, or if the document could
10667 * just not be located.
10668 * TODO: Try to find specific error codes to react only on
10669 * localisation failures.
10671 if ((lerr
== NULL
) || (lerr
->domain
!= XML_FROM_IO
)) {
10673 * We assume a parser error here.
10676 /* TODO: Error code ?? */
10677 res
= XML_SCHEMAP_SRC_IMPORT_2_1
;
10678 xmlSchemaCustomErr(ACTXT_CAST pctxt
, res
,
10679 invokingNode
, NULL
,
10680 "Failed to parse the XML resource '%s'",
10681 schemaLocation
, NULL
);
10684 xmlFreeParserCtxt(parserCtxt
);
10685 if ((doc
== NULL
) && located
)
10688 xmlSchemaPErr(pctxt
, NULL
,
10689 XML_SCHEMAP_NOTHING_TO_PARSE
,
10690 "No information for parsing was provided with the "
10691 "given schema parser context.\n",
10696 * Preprocess the document.
10699 xmlNodePtr docElem
= NULL
;
10702 docElem
= xmlDocGetRootElement(doc
);
10703 if (docElem
== NULL
) {
10704 xmlSchemaCustomErr(ACTXT_CAST pctxt
, XML_SCHEMAP_NOROOT
,
10705 invokingNode
, NULL
,
10706 "The document '%s' has no document element",
10707 schemaLocation
, NULL
);
10711 * Remove all the blank text nodes.
10713 xmlSchemaCleanupDoc(pctxt
, docElem
);
10715 * Check the schema's top level element.
10717 if (!IS_SCHEMA(docElem
, "schema")) {
10718 xmlSchemaCustomErr(ACTXT_CAST pctxt
, XML_SCHEMAP_NOT_SCHEMA
,
10719 invokingNode
, NULL
,
10720 "The XML document '%s' is not a schema document",
10721 schemaLocation
, NULL
);
10725 * Note that we don't apply a type check for the
10726 * targetNamespace value here.
10728 targetNamespace
= xmlSchemaGetProp(pctxt
, docElem
,
10729 "targetNamespace");
10732 /* after_doc_loading: */
10733 if ((bkt
== NULL
) && located
) {
10734 /* Only create a bucket if the schema was located. */
10735 bkt
= xmlSchemaBucketCreate(pctxt
, type
,
10741 bkt
->schemaLocation
= schemaLocation
;
10742 bkt
->located
= located
;
10745 bkt
->targetNamespace
= targetNamespace
;
10746 bkt
->origTargetNamespace
= targetNamespace
;
10748 bkt
->preserveDoc
= 1;
10750 if (WXS_IS_BUCKET_IMPMAIN(type
))
10753 * Add it to the graph of schemas.
10755 if (relation
!= NULL
)
10756 relation
->bucket
= bkt
;
10761 * Return the bucket explicitly; this is needed for the
10764 if (bucket
!= NULL
)
10769 if ((doc
!= NULL
) && (! preserveDoc
)) {
10774 return(pctxt
->err
);
10777 if ((doc
!= NULL
) && (! preserveDoc
)) {
10786 * xmlSchemaParseImport:
10787 * @ctxt: a schema validation context
10788 * @schema: the schema being built
10789 * @node: a subtree containing XML Schema information
10791 * parse a XML schema Import definition
10792 * *WARNING* this interface is highly subject to change
10794 * Returns 0 in case of success, a positive error code if
10795 * not valid and -1 in case of an internal error.
10798 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt
, xmlSchemaPtr schema
,
10802 const xmlChar
*namespaceName
= NULL
, *schemaLocation
= NULL
;
10803 const xmlChar
*thisTargetNamespace
;
10806 xmlSchemaBucketPtr bucket
= NULL
;
10808 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
10812 * Check for illegal attributes.
10814 attr
= node
->properties
;
10815 while (attr
!= NULL
) {
10816 if (attr
->ns
== NULL
) {
10817 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
10818 (!xmlStrEqual(attr
->name
, BAD_CAST
"namespace")) &&
10819 (!xmlStrEqual(attr
->name
, BAD_CAST
"schemaLocation"))) {
10820 xmlSchemaPIllegalAttrErr(pctxt
,
10821 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
10823 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
10824 xmlSchemaPIllegalAttrErr(pctxt
,
10825 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
10830 * Extract and validate attributes.
10832 if (xmlSchemaPValAttr(pctxt
, NULL
, node
,
10833 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
),
10834 &namespaceName
) != 0) {
10835 xmlSchemaPSimpleTypeErr(pctxt
,
10836 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
10838 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
),
10839 NULL
, namespaceName
, NULL
, NULL
, NULL
);
10840 return (pctxt
->err
);
10843 if (xmlSchemaPValAttr(pctxt
, NULL
, node
,
10844 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
),
10845 &schemaLocation
) != 0) {
10846 xmlSchemaPSimpleTypeErr(pctxt
,
10847 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
10849 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
),
10850 NULL
, schemaLocation
, NULL
, NULL
, NULL
);
10851 return (pctxt
->err
);
10854 * And now for the children...
10856 child
= node
->children
;
10857 if (IS_SCHEMA(child
, "annotation")) {
10859 * the annotation here is simply discarded ...
10862 child
= child
->next
;
10864 if (child
!= NULL
) {
10865 xmlSchemaPContentErr(pctxt
,
10866 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
10867 NULL
, node
, child
, NULL
,
10871 * Apply additional constraints.
10873 * Note that it is important to use the original @targetNamespace
10874 * (or none at all), to rule out imports of schemas _with_ a
10875 * @targetNamespace if the importing schema is a chameleon schema
10876 * (with no @targetNamespace).
10878 thisTargetNamespace
= WXS_BUCKET(pctxt
)->origTargetNamespace
;
10879 if (namespaceName
!= NULL
) {
10881 * 1.1 If the namespace [attribute] is present, then its `actual value`
10882 * must not match the `actual value` of the enclosing <schema>'s
10883 * targetNamespace [attribute].
10885 if (xmlStrEqual(thisTargetNamespace
, namespaceName
)) {
10886 xmlSchemaPCustomErr(pctxt
,
10887 XML_SCHEMAP_SRC_IMPORT_1_1
,
10889 "The value of the attribute 'namespace' must not match "
10890 "the target namespace '%s' of the importing schema",
10891 thisTargetNamespace
);
10892 return (pctxt
->err
);
10896 * 1.2 If the namespace [attribute] is not present, then the enclosing
10897 * <schema> must have a targetNamespace [attribute].
10899 if (thisTargetNamespace
== NULL
) {
10900 xmlSchemaPCustomErr(pctxt
,
10901 XML_SCHEMAP_SRC_IMPORT_1_2
,
10903 "The attribute 'namespace' must be existent if "
10904 "the importing schema has no target namespace",
10906 return (pctxt
->err
);
10910 * Locate and acquire the schema document.
10912 if (schemaLocation
!= NULL
)
10913 schemaLocation
= xmlSchemaBuildAbsoluteURI(pctxt
->dict
,
10914 schemaLocation
, node
);
10915 ret
= xmlSchemaAddSchemaDoc(pctxt
, XML_SCHEMA_SCHEMA_IMPORT
,
10916 schemaLocation
, NULL
, NULL
, 0, node
, thisTargetNamespace
,
10917 namespaceName
, &bucket
);
10923 * For <import>: "It is *not* an error for the application
10924 * schema reference strategy to fail."
10925 * So just don't parse if no schema document was found.
10926 * Note that we will get no bucket if the schema could not be
10927 * located or if there was no schemaLocation.
10929 if ((bucket
== NULL
) && (schemaLocation
!= NULL
)) {
10930 xmlSchemaCustomWarning(ACTXT_CAST pctxt
,
10931 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA
,
10933 "Failed to locate a schema at location '%s'. "
10934 "Skipping the import", schemaLocation
, NULL
, NULL
);
10937 if ((bucket
!= NULL
) && CAN_PARSE_SCHEMA(bucket
)) {
10938 ret
= xmlSchemaParseNewDoc(pctxt
, schema
, bucket
);
10945 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt
,
10946 xmlSchemaPtr schema
,
10948 xmlChar
**schemaLocation
,
10953 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
) ||
10954 (schemaLocation
== NULL
))
10957 *schemaLocation
= NULL
;
10959 * Check for illegal attributes.
10960 * Applies for both <include> and <redefine>.
10962 attr
= node
->properties
;
10963 while (attr
!= NULL
) {
10964 if (attr
->ns
== NULL
) {
10965 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
10966 (!xmlStrEqual(attr
->name
, BAD_CAST
"schemaLocation"))) {
10967 xmlSchemaPIllegalAttrErr(pctxt
,
10968 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
10970 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
10971 xmlSchemaPIllegalAttrErr(pctxt
,
10972 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
10976 xmlSchemaPValAttrID(pctxt
, node
, BAD_CAST
"id");
10978 * Preliminary step, extract the URI-Reference and make an URI
10982 * Attribute "schemaLocation" is mandatory.
10984 attr
= xmlSchemaGetPropNode(node
, "schemaLocation");
10985 if (attr
!= NULL
) {
10986 xmlChar
*base
= NULL
;
10987 xmlChar
*uri
= NULL
;
10989 if (xmlSchemaPValAttrNode(pctxt
, NULL
, attr
,
10990 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI
),
10991 (const xmlChar
**) schemaLocation
) != 0)
10993 base
= xmlNodeGetBase(node
->doc
, node
);
10994 if (base
== NULL
) {
10995 uri
= xmlBuildURI(*schemaLocation
, node
->doc
->URL
);
10997 uri
= xmlBuildURI(*schemaLocation
, base
);
11001 PERROR_INT("xmlSchemaParseIncludeOrRedefine",
11002 "could not build an URI from the schemaLocation")
11005 (*schemaLocation
) = (xmlChar
*) xmlDictLookup(pctxt
->dict
, uri
, -1);
11008 xmlSchemaPMissingAttrErr(pctxt
,
11009 XML_SCHEMAP_S4S_ATTR_MISSING
,
11010 NULL
, node
, "schemaLocation", NULL
);
11014 * Report self-inclusion and self-redefinition.
11016 if (xmlStrEqual(*schemaLocation
, pctxt
->URL
)) {
11017 if (type
== XML_SCHEMA_SCHEMA_REDEFINE
) {
11018 xmlSchemaPCustomErr(pctxt
,
11019 XML_SCHEMAP_SRC_REDEFINE
,
11021 "The schema document '%s' cannot redefine itself.",
11024 xmlSchemaPCustomErr(pctxt
,
11025 XML_SCHEMAP_SRC_INCLUDE
,
11027 "The schema document '%s' cannot include itself.",
11035 return(pctxt
->err
);
11041 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt
,
11042 xmlSchemaPtr schema
,
11046 xmlNodePtr child
= NULL
;
11047 const xmlChar
*schemaLocation
= NULL
;
11048 int res
= 0; /* hasRedefinitions = 0 */
11049 int isChameleon
= 0, wasChameleon
= 0;
11050 xmlSchemaBucketPtr bucket
= NULL
;
11052 if ((pctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
11056 * Parse attributes. Note that the returned schemaLocation will
11057 * be already converted to an absolute URI.
11059 res
= xmlSchemaParseIncludeOrRedefineAttrs(pctxt
, schema
,
11060 node
, (xmlChar
**) (&schemaLocation
), type
);
11064 * Load and add the schema document.
11066 res
= xmlSchemaAddSchemaDoc(pctxt
, type
, schemaLocation
, NULL
,
11067 NULL
, 0, node
, pctxt
->targetNamespace
, NULL
, &bucket
);
11071 * If we get no schema bucket back, then this means that the schema
11072 * document could not be located or was broken XML or was not
11073 * a schema document.
11075 if ((bucket
== NULL
) || (bucket
->doc
== NULL
)) {
11076 if (type
== XML_SCHEMA_SCHEMA_INCLUDE
) {
11078 * WARNING for <include>:
11079 * We will raise an error if the schema cannot be located
11080 * for inclusions, since the that was the feedback from the
11081 * schema people. I.e. the following spec piece will *not* be
11083 * SPEC src-include: "It is not an error for the `actual value` of the
11084 * schemaLocation [attribute] to fail to resolve it all, in which
11085 * case no corresponding inclusion is performed.
11086 * So do we need a warning report here?"
11088 res
= XML_SCHEMAP_SRC_INCLUDE
;
11089 xmlSchemaCustomErr(ACTXT_CAST pctxt
, res
,
11091 "Failed to load the document '%s' for inclusion",
11092 schemaLocation
, NULL
);
11095 * NOTE: This was changed to raise an error even if no redefinitions
11098 * SPEC src-redefine (1)
11099 * "If there are any element information items among the [children]
11100 * other than <annotation> then the `actual value` of the
11101 * schemaLocation [attribute] must successfully resolve."
11102 * TODO: Ask the WG if a the location has always to resolve
11105 res
= XML_SCHEMAP_SRC_REDEFINE
;
11106 xmlSchemaCustomErr(ACTXT_CAST pctxt
, res
,
11108 "Failed to load the document '%s' for redefinition",
11109 schemaLocation
, NULL
);
11113 * Check targetNamespace sanity before parsing the new schema.
11114 * TODO: Note that we won't check further content if the
11115 * targetNamespace was bad.
11117 if (bucket
->origTargetNamespace
!= NULL
) {
11119 * SPEC src-include (2.1)
11120 * "SII has a targetNamespace [attribute], and its `actual
11121 * value` is identical to the `actual value` of the targetNamespace
11122 * [attribute] of SII' (which must have such an [attribute])."
11124 if (pctxt
->targetNamespace
== NULL
) {
11125 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
11126 XML_SCHEMAP_SRC_INCLUDE
,
11128 "The target namespace of the included/redefined schema "
11129 "'%s' has to be absent, since the including/redefining "
11130 "schema has no target namespace",
11131 schemaLocation
, NULL
);
11133 } else if (!xmlStrEqual(bucket
->origTargetNamespace
,
11134 pctxt
->targetNamespace
)) {
11135 /* TODO: Change error function. */
11136 xmlSchemaPCustomErrExt(pctxt
,
11137 XML_SCHEMAP_SRC_INCLUDE
,
11139 "The target namespace '%s' of the included/redefined "
11140 "schema '%s' differs from '%s' of the "
11141 "including/redefining schema",
11142 bucket
->origTargetNamespace
, schemaLocation
,
11143 pctxt
->targetNamespace
);
11146 } else if (pctxt
->targetNamespace
!= NULL
) {
11148 * Chameleons: the original target namespace will
11149 * differ from the resulting namespace.
11152 if (bucket
->parsed
&&
11153 bucket
->origTargetNamespace
!= NULL
) {
11154 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
11155 XML_SCHEMAP_SRC_INCLUDE
,
11157 "The target namespace of the included/redefined schema "
11158 "'%s' has to be absent or the same as the "
11159 "including/redefining schema's target namespace",
11160 schemaLocation
, NULL
);
11163 bucket
->targetNamespace
= pctxt
->targetNamespace
;
11167 * Parse the schema.
11169 if (bucket
&& (!bucket
->parsed
) && (bucket
->doc
!= NULL
)) {
11171 /* TODO: Get rid of this flag on the schema itself. */
11172 if ((schema
->flags
& XML_SCHEMAS_INCLUDING_CONVERT_NS
) == 0) {
11173 schema
->flags
|= XML_SCHEMAS_INCLUDING_CONVERT_NS
;
11177 xmlSchemaParseNewDoc(pctxt
, schema
, bucket
);
11178 /* Restore chameleon flag. */
11179 if (isChameleon
&& (!wasChameleon
))
11180 schema
->flags
^= XML_SCHEMAS_INCLUDING_CONVERT_NS
;
11183 * And now for the children...
11185 child
= node
->children
;
11186 if (type
== XML_SCHEMA_SCHEMA_REDEFINE
) {
11188 * Parse (simpleType | complexType | group | attributeGroup))*
11190 pctxt
->redefined
= bucket
;
11192 * How to proceed if the redefined schema was not located?
11194 pctxt
->isRedefine
= 1;
11195 while (IS_SCHEMA(child
, "annotation") ||
11196 IS_SCHEMA(child
, "simpleType") ||
11197 IS_SCHEMA(child
, "complexType") ||
11198 IS_SCHEMA(child
, "group") ||
11199 IS_SCHEMA(child
, "attributeGroup")) {
11200 if (IS_SCHEMA(child
, "annotation")) {
11202 * TODO: discard or not?
11204 } else if (IS_SCHEMA(child
, "simpleType")) {
11205 xmlSchemaParseSimpleType(pctxt
, schema
, child
, 1);
11206 } else if (IS_SCHEMA(child
, "complexType")) {
11207 xmlSchemaParseComplexType(pctxt
, schema
, child
, 1);
11208 /* hasRedefinitions = 1; */
11209 } else if (IS_SCHEMA(child
, "group")) {
11210 /* hasRedefinitions = 1; */
11211 xmlSchemaParseModelGroupDefinition(pctxt
,
11213 } else if (IS_SCHEMA(child
, "attributeGroup")) {
11214 /* hasRedefinitions = 1; */
11215 xmlSchemaParseAttributeGroupDefinition(pctxt
, schema
,
11218 child
= child
->next
;
11220 pctxt
->redefined
= NULL
;
11221 pctxt
->isRedefine
= 0;
11223 if (IS_SCHEMA(child
, "annotation")) {
11225 * TODO: discard or not?
11227 child
= child
->next
;
11230 if (child
!= NULL
) {
11231 res
= XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
;
11232 if (type
== XML_SCHEMA_SCHEMA_REDEFINE
) {
11233 xmlSchemaPContentErr(pctxt
, res
,
11234 NULL
, node
, child
, NULL
,
11235 "(annotation | (simpleType | complexType | group | attributeGroup))*");
11237 xmlSchemaPContentErr(pctxt
, res
,
11238 NULL
, node
, child
, NULL
,
11245 return(pctxt
->err
);
11249 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt
, xmlSchemaPtr schema
,
11253 #ifndef ENABLE_REDEFINE
11257 res
= xmlSchemaParseIncludeOrRedefine(pctxt
, schema
, node
,
11258 XML_SCHEMA_SCHEMA_REDEFINE
);
11265 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt
, xmlSchemaPtr schema
,
11270 res
= xmlSchemaParseIncludeOrRedefine(pctxt
, schema
, node
,
11271 XML_SCHEMA_SCHEMA_INCLUDE
);
11278 * xmlSchemaParseModelGroup:
11279 * @ctxt: a schema validation context
11280 * @schema: the schema being built
11281 * @node: a subtree containing XML Schema information
11282 * @type: the "compositor" type
11283 * @particleNeeded: if a a model group with a particle
11285 * parse a XML schema Sequence definition.
11286 * Applies parts of:
11287 * Schema Representation Constraint:
11288 * Redefinition Constraints and Semantics (src-redefine)
11289 * (6.1), (6.1.1), (6.1.2)
11291 * Schema Component Constraint:
11292 * All Group Limited (cos-all-limited) (2)
11293 * TODO: Actually this should go to component-level checks,
11294 * but is done here due to performance. Move it to an other layer
11295 * is schema construction via an API is implemented.
11297 * *WARNING* this interface is highly subject to change
11299 * Returns -1 in case of error, 0 if the declaration is improper and
11300 * 1 in case of success.
11302 static xmlSchemaTreeItemPtr
11303 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
11304 xmlNodePtr node
, xmlSchemaTypeType type
,
11307 xmlSchemaModelGroupPtr item
;
11308 xmlSchemaParticlePtr particle
= NULL
;
11309 xmlNodePtr child
= NULL
;
11311 int min
= 1, max
= 1, isElemRef
, hasRefs
= 0;
11313 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
11316 * Create a model group with the given compositor.
11318 item
= xmlSchemaAddModelGroup(ctxt
, schema
, type
, node
);
11322 if (withParticle
) {
11323 if (type
== XML_SCHEMA_TYPE_ALL
) {
11324 min
= xmlGetMinOccurs(ctxt
, node
, 0, 1, 1, "(0 | 1)");
11325 max
= xmlGetMaxOccurs(ctxt
, node
, 1, 1, 1, "1");
11327 /* choice + sequence */
11328 min
= xmlGetMinOccurs(ctxt
, node
, 0, -1, 1, "xs:nonNegativeInteger");
11329 max
= xmlGetMaxOccurs(ctxt
, node
, 0, UNBOUNDED
, 1,
11330 "(xs:nonNegativeInteger | unbounded)");
11332 xmlSchemaPCheckParticleCorrect_2(ctxt
, NULL
, node
, min
, max
);
11334 * Create a particle
11336 particle
= xmlSchemaAddParticle(ctxt
, node
, min
, max
);
11337 if (particle
== NULL
)
11339 particle
->children
= (xmlSchemaTreeItemPtr
) item
;
11341 * Check for illegal attributes.
11343 attr
= node
->properties
;
11344 while (attr
!= NULL
) {
11345 if (attr
->ns
== NULL
) {
11346 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
11347 (!xmlStrEqual(attr
->name
, BAD_CAST
"maxOccurs")) &&
11348 (!xmlStrEqual(attr
->name
, BAD_CAST
"minOccurs"))) {
11349 xmlSchemaPIllegalAttrErr(ctxt
,
11350 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11352 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
11353 xmlSchemaPIllegalAttrErr(ctxt
,
11354 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11360 * Check for illegal attributes.
11362 attr
= node
->properties
;
11363 while (attr
!= NULL
) {
11364 if (attr
->ns
== NULL
) {
11365 if (!xmlStrEqual(attr
->name
, BAD_CAST
"id")) {
11366 xmlSchemaPIllegalAttrErr(ctxt
,
11367 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11369 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
11370 xmlSchemaPIllegalAttrErr(ctxt
,
11371 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11378 * Extract and validate attributes.
11380 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
11382 * And now for the children...
11384 child
= node
->children
;
11385 if (IS_SCHEMA(child
, "annotation")) {
11386 item
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
11387 child
= child
->next
;
11389 if (type
== XML_SCHEMA_TYPE_ALL
) {
11390 xmlSchemaParticlePtr part
, last
= NULL
;
11392 while (IS_SCHEMA(child
, "element")) {
11393 part
= (xmlSchemaParticlePtr
) xmlSchemaParseElement(ctxt
,
11394 schema
, child
, &isElemRef
, 0);
11396 * SPEC cos-all-limited (2)
11397 * "The {max occurs} of all the particles in the {particles}
11398 * of the ('all') group must be 0 or 1.
11400 if (part
!= NULL
) {
11403 if (part
->minOccurs
> 1) {
11404 xmlSchemaPCustomErr(ctxt
,
11405 XML_SCHEMAP_COS_ALL_LIMITED
,
11407 "Invalid value for minOccurs (must be 0 or 1)",
11410 part
->minOccurs
= 1;
11412 if (part
->maxOccurs
> 1) {
11413 xmlSchemaPCustomErr(ctxt
,
11414 XML_SCHEMAP_COS_ALL_LIMITED
,
11416 "Invalid value for maxOccurs (must be 0 or 1)",
11419 part
->maxOccurs
= 1;
11422 item
->children
= (xmlSchemaTreeItemPtr
) part
;
11424 last
->next
= (xmlSchemaTreeItemPtr
) part
;
11427 child
= child
->next
;
11429 if (child
!= NULL
) {
11430 xmlSchemaPContentErr(ctxt
,
11431 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11432 NULL
, node
, child
, NULL
,
11433 "(annotation?, (annotation?, element*)");
11436 /* choice + sequence */
11437 xmlSchemaTreeItemPtr part
= NULL
, last
= NULL
;
11439 while ((IS_SCHEMA(child
, "element")) ||
11440 (IS_SCHEMA(child
, "group")) ||
11441 (IS_SCHEMA(child
, "any")) ||
11442 (IS_SCHEMA(child
, "choice")) ||
11443 (IS_SCHEMA(child
, "sequence"))) {
11445 if (IS_SCHEMA(child
, "element")) {
11446 part
= (xmlSchemaTreeItemPtr
)
11447 xmlSchemaParseElement(ctxt
, schema
, child
, &isElemRef
, 0);
11448 if (part
&& isElemRef
)
11450 } else if (IS_SCHEMA(child
, "group")) {
11452 xmlSchemaParseModelGroupDefRef(ctxt
, schema
, child
);
11456 * Handle redefinitions.
11458 if (ctxt
->isRedefine
&& ctxt
->redef
&&
11459 (ctxt
->redef
->item
->type
== XML_SCHEMA_TYPE_GROUP
) &&
11460 part
&& part
->children
)
11462 if ((xmlSchemaGetQNameRefName(part
->children
) ==
11463 ctxt
->redef
->refName
) &&
11464 (xmlSchemaGetQNameRefTargetNs(part
->children
) ==
11465 ctxt
->redef
->refTargetNs
))
11468 * SPEC src-redefine:
11469 * (6.1) "If it has a <group> among its contents at
11470 * some level the `actual value` of whose ref
11471 * [attribute] is the same as the `actual value` of
11472 * its own name attribute plus target namespace, then
11473 * all of the following must be true:"
11474 * (6.1.1) "It must have exactly one such group."
11476 if (ctxt
->redefCounter
!= 0) {
11477 xmlChar
*str
= NULL
;
11479 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
11480 XML_SCHEMAP_SRC_REDEFINE
, child
, NULL
,
11481 "The redefining model group definition "
11482 "'%s' must not contain more than one "
11483 "reference to the redefined definition",
11484 xmlSchemaFormatQName(&str
,
11485 ctxt
->redef
->refTargetNs
,
11486 ctxt
->redef
->refName
),
11490 } else if (((WXS_PARTICLE(part
))->minOccurs
!= 1) ||
11491 ((WXS_PARTICLE(part
))->maxOccurs
!= 1))
11493 xmlChar
*str
= NULL
;
11495 * SPEC src-redefine:
11496 * (6.1.2) "The `actual value` of both that
11497 * group's minOccurs and maxOccurs [attribute]
11498 * must be 1 (or `absent`).
11500 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
11501 XML_SCHEMAP_SRC_REDEFINE
, child
, NULL
,
11502 "The redefining model group definition "
11503 "'%s' must not contain a reference to the "
11504 "redefined definition with a "
11505 "maxOccurs/minOccurs other than 1",
11506 xmlSchemaFormatQName(&str
,
11507 ctxt
->redef
->refTargetNs
,
11508 ctxt
->redef
->refName
),
11513 ctxt
->redef
->reference
= WXS_BASIC_CAST part
;
11514 ctxt
->redefCounter
++;
11517 } else if (IS_SCHEMA(child
, "any")) {
11518 part
= (xmlSchemaTreeItemPtr
)
11519 xmlSchemaParseAny(ctxt
, schema
, child
);
11520 } else if (IS_SCHEMA(child
, "choice")) {
11521 part
= xmlSchemaParseModelGroup(ctxt
, schema
, child
,
11522 XML_SCHEMA_TYPE_CHOICE
, 1);
11523 } else if (IS_SCHEMA(child
, "sequence")) {
11524 part
= xmlSchemaParseModelGroup(ctxt
, schema
, child
,
11525 XML_SCHEMA_TYPE_SEQUENCE
, 1);
11527 if (part
!= NULL
) {
11529 item
->children
= part
;
11534 child
= child
->next
;
11536 if (child
!= NULL
) {
11537 xmlSchemaPContentErr(ctxt
,
11538 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11539 NULL
, node
, child
, NULL
,
11540 "(annotation?, (element | group | choice | sequence | any)*)");
11543 if ((max
== 0) && (min
== 0))
11547 * We need to resolve references.
11549 WXS_ADD_PENDING(ctxt
, item
);
11552 return ((xmlSchemaTreeItemPtr
) particle
);
11554 return ((xmlSchemaTreeItemPtr
) item
);
11558 * xmlSchemaParseRestriction:
11559 * @ctxt: a schema validation context
11560 * @schema: the schema being built
11561 * @node: a subtree containing XML Schema information
11563 * parse a XML schema Restriction definition
11564 * *WARNING* this interface is highly subject to change
11566 * Returns the type definition or NULL in case of error
11568 static xmlSchemaTypePtr
11569 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
11570 xmlNodePtr node
, xmlSchemaTypeType parentType
)
11572 xmlSchemaTypePtr type
;
11573 xmlNodePtr child
= NULL
;
11576 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
11578 /* Not a component, don't create it. */
11579 type
= ctxt
->ctxtType
;
11580 type
->flags
|= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION
;
11583 * Check for illegal attributes.
11585 attr
= node
->properties
;
11586 while (attr
!= NULL
) {
11587 if (attr
->ns
== NULL
) {
11588 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
11589 (!xmlStrEqual(attr
->name
, BAD_CAST
"base"))) {
11590 xmlSchemaPIllegalAttrErr(ctxt
,
11591 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11593 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
11594 xmlSchemaPIllegalAttrErr(ctxt
,
11595 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11600 * Extract and validate attributes.
11602 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
11607 * Extract the base type. The "base" attribute is mandatory if inside
11608 * a complex type or if redefining.
11610 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11611 * among its [children]), the simple type definition which is
11612 * the {content type} of the type definition `resolved` to by
11613 * the `actual value` of the base [attribute]"
11615 if (xmlSchemaPValAttrQName(ctxt
, schema
, NULL
, node
, "base",
11616 &(type
->baseNs
), &(type
->base
)) == 0)
11618 if ((type
->base
== NULL
) && (type
->type
== XML_SCHEMA_TYPE_COMPLEX
)) {
11619 xmlSchemaPMissingAttrErr(ctxt
,
11620 XML_SCHEMAP_S4S_ATTR_MISSING
,
11621 NULL
, node
, "base", NULL
);
11622 } else if ((ctxt
->isRedefine
) &&
11623 (type
->flags
& XML_SCHEMAS_TYPE_GLOBAL
))
11625 if (type
->base
== NULL
) {
11626 xmlSchemaPMissingAttrErr(ctxt
,
11627 XML_SCHEMAP_S4S_ATTR_MISSING
,
11628 NULL
, node
, "base", NULL
);
11629 } else if ((! xmlStrEqual(type
->base
, type
->name
)) ||
11630 (! xmlStrEqual(type
->baseNs
, type
->targetNamespace
)))
11632 xmlChar
*str1
= NULL
, *str2
= NULL
;
11634 * REDEFINE: SPEC src-redefine (5)
11635 * "Within the [children], each <simpleType> must have a
11636 * <restriction> among its [children] ... the `actual value` of
11637 * whose base [attribute] must be the same as the `actual value`
11638 * of its own name attribute plus target namespace;"
11640 xmlSchemaPCustomErrExt(ctxt
, XML_SCHEMAP_SRC_REDEFINE
,
11641 NULL
, node
, "This is a redefinition, but the QName "
11642 "value '%s' of the 'base' attribute does not match the "
11643 "type's designation '%s'",
11644 xmlSchemaFormatQName(&str1
, type
->baseNs
, type
->base
),
11645 xmlSchemaFormatQName(&str2
, type
->targetNamespace
,
11646 type
->name
), NULL
);
11647 FREE_AND_NULL(str1
);
11648 FREE_AND_NULL(str2
);
11649 /* Avoid confusion and erase the values. */
11651 type
->baseNs
= NULL
;
11656 * And now for the children...
11658 child
= node
->children
;
11659 if (IS_SCHEMA(child
, "annotation")) {
11661 * Add the annotation to the simple type ancestor.
11663 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) type
,
11664 xmlSchemaParseAnnotation(ctxt
, child
, 1));
11665 child
= child
->next
;
11667 if (parentType
== XML_SCHEMA_TYPE_SIMPLE
) {
11669 * Corresponds to <simpleType><restriction><simpleType>.
11671 if (IS_SCHEMA(child
, "simpleType")) {
11672 if (type
->base
!= NULL
) {
11674 * src-restriction-base-or-simpleType
11675 * Either the base [attribute] or the simpleType [child] of the
11676 * <restriction> element must be present, but not both.
11678 xmlSchemaPContentErr(ctxt
,
11679 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE
,
11681 "The attribute 'base' and the <simpleType> child are "
11682 "mutually exclusive", NULL
);
11684 type
->baseType
= (xmlSchemaTypePtr
)
11685 xmlSchemaParseSimpleType(ctxt
, schema
, child
, 0);
11687 child
= child
->next
;
11688 } else if (type
->base
== NULL
) {
11689 xmlSchemaPContentErr(ctxt
,
11690 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE
,
11692 "Either the attribute 'base' or a <simpleType> child "
11693 "must be present", NULL
);
11695 } else if (parentType
== XML_SCHEMA_TYPE_COMPLEX_CONTENT
) {
11697 * Corresponds to <complexType><complexContent><restriction>...
11700 * Model groups <all>, <choice> and <sequence>.
11702 if (IS_SCHEMA(child
, "all")) {
11703 type
->subtypes
= (xmlSchemaTypePtr
)
11704 xmlSchemaParseModelGroup(ctxt
, schema
, child
,
11705 XML_SCHEMA_TYPE_ALL
, 1);
11706 child
= child
->next
;
11707 } else if (IS_SCHEMA(child
, "choice")) {
11708 type
->subtypes
= (xmlSchemaTypePtr
)
11709 xmlSchemaParseModelGroup(ctxt
,
11710 schema
, child
, XML_SCHEMA_TYPE_CHOICE
, 1);
11711 child
= child
->next
;
11712 } else if (IS_SCHEMA(child
, "sequence")) {
11713 type
->subtypes
= (xmlSchemaTypePtr
)
11714 xmlSchemaParseModelGroup(ctxt
, schema
, child
,
11715 XML_SCHEMA_TYPE_SEQUENCE
, 1);
11716 child
= child
->next
;
11718 * Model group reference <group>.
11720 } else if (IS_SCHEMA(child
, "group")) {
11721 type
->subtypes
= (xmlSchemaTypePtr
)
11722 xmlSchemaParseModelGroupDefRef(ctxt
, schema
, child
);
11724 * Note that the reference will be resolved in
11725 * xmlSchemaResolveTypeReferences();
11727 child
= child
->next
;
11729 } else if (parentType
== XML_SCHEMA_TYPE_SIMPLE_CONTENT
) {
11731 * Corresponds to <complexType><simpleContent><restriction>...
11733 * "1.1 the simple type definition corresponding to the <simpleType>
11734 * among the [children] of <restriction> if there is one;"
11736 if (IS_SCHEMA(child
, "simpleType")) {
11738 * We will store the to-be-restricted simple type in
11739 * type->contentTypeDef *temporarily*.
11741 type
->contentTypeDef
= (xmlSchemaTypePtr
)
11742 xmlSchemaParseSimpleType(ctxt
, schema
, child
, 0);
11743 if ( type
->contentTypeDef
== NULL
)
11745 child
= child
->next
;
11749 if ((parentType
== XML_SCHEMA_TYPE_SIMPLE
) ||
11750 (parentType
== XML_SCHEMA_TYPE_SIMPLE_CONTENT
)) {
11751 xmlSchemaFacetPtr facet
, lastfacet
= NULL
;
11753 * Corresponds to <complexType><simpleContent><restriction>...
11754 * <simpleType><restriction>...
11758 * Add the facets to the simple type ancestor.
11761 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11762 * Simple Type Definition Schema Representation Constraint:
11763 * *Single Facet Value*
11765 while ((IS_SCHEMA(child
, "minInclusive")) ||
11766 (IS_SCHEMA(child
, "minExclusive")) ||
11767 (IS_SCHEMA(child
, "maxInclusive")) ||
11768 (IS_SCHEMA(child
, "maxExclusive")) ||
11769 (IS_SCHEMA(child
, "totalDigits")) ||
11770 (IS_SCHEMA(child
, "fractionDigits")) ||
11771 (IS_SCHEMA(child
, "pattern")) ||
11772 (IS_SCHEMA(child
, "enumeration")) ||
11773 (IS_SCHEMA(child
, "whiteSpace")) ||
11774 (IS_SCHEMA(child
, "length")) ||
11775 (IS_SCHEMA(child
, "maxLength")) ||
11776 (IS_SCHEMA(child
, "minLength"))) {
11777 facet
= xmlSchemaParseFacet(ctxt
, schema
, child
);
11778 if (facet
!= NULL
) {
11779 if (lastfacet
== NULL
)
11780 type
->facets
= facet
;
11782 lastfacet
->next
= facet
;
11784 lastfacet
->next
= NULL
;
11786 child
= child
->next
;
11789 * Create links for derivation and validation.
11791 if (type
->facets
!= NULL
) {
11792 xmlSchemaFacetLinkPtr facetLink
, lastFacetLink
= NULL
;
11794 facet
= type
->facets
;
11796 facetLink
= (xmlSchemaFacetLinkPtr
)
11797 xmlMalloc(sizeof(xmlSchemaFacetLink
));
11798 if (facetLink
== NULL
) {
11799 xmlSchemaPErrMemory(ctxt
, "allocating a facet link", NULL
);
11800 xmlFree(facetLink
);
11803 facetLink
->facet
= facet
;
11804 facetLink
->next
= NULL
;
11805 if (lastFacetLink
== NULL
)
11806 type
->facetSet
= facetLink
;
11808 lastFacetLink
->next
= facetLink
;
11809 lastFacetLink
= facetLink
;
11810 facet
= facet
->next
;
11811 } while (facet
!= NULL
);
11814 if (type
->type
== XML_SCHEMA_TYPE_COMPLEX
) {
11816 * Attribute uses/declarations.
11818 if (xmlSchemaParseLocalAttributes(ctxt
, schema
, &child
,
11819 (xmlSchemaItemListPtr
*) &(type
->attrUses
),
11820 XML_SCHEMA_TYPE_RESTRICTION
, NULL
) == -1)
11823 * Attribute wildcard.
11825 if (IS_SCHEMA(child
, "anyAttribute")) {
11826 type
->attributeWildcard
=
11827 xmlSchemaParseAnyAttribute(ctxt
, schema
, child
);
11828 child
= child
->next
;
11831 if (child
!= NULL
) {
11832 if (parentType
== XML_SCHEMA_TYPE_COMPLEX_CONTENT
) {
11833 xmlSchemaPContentErr(ctxt
,
11834 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11835 NULL
, node
, child
, NULL
,
11836 "annotation?, (group | all | choice | sequence)?, "
11837 "((attribute | attributeGroup)*, anyAttribute?))");
11838 } else if (parentType
== XML_SCHEMA_TYPE_SIMPLE_CONTENT
) {
11839 xmlSchemaPContentErr(ctxt
,
11840 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11841 NULL
, node
, child
, NULL
,
11842 "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11843 "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11844 "length | minLength | maxLength | enumeration | whiteSpace | "
11845 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11848 xmlSchemaPContentErr(ctxt
,
11849 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11850 NULL
, node
, child
, NULL
,
11851 "(annotation?, (simpleType?, (minExclusive | minInclusive | "
11852 "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11853 "length | minLength | maxLength | enumeration | whiteSpace | "
11861 * xmlSchemaParseExtension:
11862 * @ctxt: a schema validation context
11863 * @schema: the schema being built
11864 * @node: a subtree containing XML Schema information
11866 * Parses an <extension>, which is found inside a
11867 * <simpleContent> or <complexContent>.
11868 * *WARNING* this interface is highly subject to change.
11870 * TODO: Returns the type definition or NULL in case of error
11872 static xmlSchemaTypePtr
11873 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
11874 xmlNodePtr node
, xmlSchemaTypeType parentType
)
11876 xmlSchemaTypePtr type
;
11877 xmlNodePtr child
= NULL
;
11880 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
11882 /* Not a component, don't create it. */
11883 type
= ctxt
->ctxtType
;
11884 type
->flags
|= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION
;
11887 * Check for illegal attributes.
11889 attr
= node
->properties
;
11890 while (attr
!= NULL
) {
11891 if (attr
->ns
== NULL
) {
11892 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
11893 (!xmlStrEqual(attr
->name
, BAD_CAST
"base"))) {
11894 xmlSchemaPIllegalAttrErr(ctxt
,
11895 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11897 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
11898 xmlSchemaPIllegalAttrErr(ctxt
,
11899 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
11904 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
11907 * Attribute "base" - mandatory.
11909 if ((xmlSchemaPValAttrQName(ctxt
, schema
, NULL
, node
,
11910 "base", &(type
->baseNs
), &(type
->base
)) == 0) &&
11911 (type
->base
== NULL
)) {
11912 xmlSchemaPMissingAttrErr(ctxt
,
11913 XML_SCHEMAP_S4S_ATTR_MISSING
,
11914 NULL
, node
, "base", NULL
);
11917 * And now for the children...
11919 child
= node
->children
;
11920 if (IS_SCHEMA(child
, "annotation")) {
11922 * Add the annotation to the type ancestor.
11924 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) type
,
11925 xmlSchemaParseAnnotation(ctxt
, child
, 1));
11926 child
= child
->next
;
11928 if (parentType
== XML_SCHEMA_TYPE_COMPLEX_CONTENT
) {
11930 * Corresponds to <complexType><complexContent><extension>... and:
11932 * Model groups <all>, <choice>, <sequence> and <group>.
11934 if (IS_SCHEMA(child
, "all")) {
11935 type
->subtypes
= (xmlSchemaTypePtr
)
11936 xmlSchemaParseModelGroup(ctxt
, schema
,
11937 child
, XML_SCHEMA_TYPE_ALL
, 1);
11938 child
= child
->next
;
11939 } else if (IS_SCHEMA(child
, "choice")) {
11940 type
->subtypes
= (xmlSchemaTypePtr
)
11941 xmlSchemaParseModelGroup(ctxt
, schema
,
11942 child
, XML_SCHEMA_TYPE_CHOICE
, 1);
11943 child
= child
->next
;
11944 } else if (IS_SCHEMA(child
, "sequence")) {
11945 type
->subtypes
= (xmlSchemaTypePtr
)
11946 xmlSchemaParseModelGroup(ctxt
, schema
,
11947 child
, XML_SCHEMA_TYPE_SEQUENCE
, 1);
11948 child
= child
->next
;
11949 } else if (IS_SCHEMA(child
, "group")) {
11950 type
->subtypes
= (xmlSchemaTypePtr
)
11951 xmlSchemaParseModelGroupDefRef(ctxt
, schema
, child
);
11953 * Note that the reference will be resolved in
11954 * xmlSchemaResolveTypeReferences();
11956 child
= child
->next
;
11959 if (child
!= NULL
) {
11961 * Attribute uses/declarations.
11963 if (xmlSchemaParseLocalAttributes(ctxt
, schema
, &child
,
11964 (xmlSchemaItemListPtr
*) &(type
->attrUses
),
11965 XML_SCHEMA_TYPE_EXTENSION
, NULL
) == -1)
11968 * Attribute wildcard.
11970 if (IS_SCHEMA(child
, "anyAttribute")) {
11971 ctxt
->ctxtType
->attributeWildcard
=
11972 xmlSchemaParseAnyAttribute(ctxt
, schema
, child
);
11973 child
= child
->next
;
11976 if (child
!= NULL
) {
11977 if (parentType
== XML_SCHEMA_TYPE_COMPLEX_CONTENT
) {
11978 /* Complex content extension. */
11979 xmlSchemaPContentErr(ctxt
,
11980 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11981 NULL
, node
, child
, NULL
,
11982 "(annotation?, ((group | all | choice | sequence)?, "
11983 "((attribute | attributeGroup)*, anyAttribute?)))");
11985 /* Simple content extension. */
11986 xmlSchemaPContentErr(ctxt
,
11987 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
11988 NULL
, node
, child
, NULL
,
11989 "(annotation?, ((attribute | attributeGroup)*, "
11990 "anyAttribute?))");
11997 * xmlSchemaParseSimpleContent:
11998 * @ctxt: a schema validation context
11999 * @schema: the schema being built
12000 * @node: a subtree containing XML Schema information
12002 * parse a XML schema SimpleContent definition
12003 * *WARNING* this interface is highly subject to change
12005 * Returns the type definition or NULL in case of error
12008 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt
,
12009 xmlSchemaPtr schema
, xmlNodePtr node
,
12010 int *hasRestrictionOrExtension
)
12012 xmlSchemaTypePtr type
;
12013 xmlNodePtr child
= NULL
;
12016 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
) ||
12017 (hasRestrictionOrExtension
== NULL
))
12019 *hasRestrictionOrExtension
= 0;
12020 /* Not a component, don't create it. */
12021 type
= ctxt
->ctxtType
;
12022 type
->contentType
= XML_SCHEMA_CONTENT_SIMPLE
;
12024 * Check for illegal attributes.
12026 attr
= node
->properties
;
12027 while (attr
!= NULL
) {
12028 if (attr
->ns
== NULL
) {
12029 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id"))) {
12030 xmlSchemaPIllegalAttrErr(ctxt
,
12031 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12033 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
12034 xmlSchemaPIllegalAttrErr(ctxt
,
12035 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12040 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
12043 * And now for the children...
12045 child
= node
->children
;
12046 if (IS_SCHEMA(child
, "annotation")) {
12048 * Add the annotation to the complex type ancestor.
12050 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) type
,
12051 xmlSchemaParseAnnotation(ctxt
, child
, 1));
12052 child
= child
->next
;
12054 if (child
== NULL
) {
12055 xmlSchemaPContentErr(ctxt
,
12056 XML_SCHEMAP_S4S_ELEM_MISSING
,
12057 NULL
, node
, NULL
, NULL
,
12058 "(annotation?, (restriction | extension))");
12060 if (child
== NULL
) {
12061 xmlSchemaPContentErr(ctxt
,
12062 XML_SCHEMAP_S4S_ELEM_MISSING
,
12063 NULL
, node
, NULL
, NULL
,
12064 "(annotation?, (restriction | extension))");
12066 if (IS_SCHEMA(child
, "restriction")) {
12067 xmlSchemaParseRestriction(ctxt
, schema
, child
,
12068 XML_SCHEMA_TYPE_SIMPLE_CONTENT
);
12069 (*hasRestrictionOrExtension
) = 1;
12070 child
= child
->next
;
12071 } else if (IS_SCHEMA(child
, "extension")) {
12072 xmlSchemaParseExtension(ctxt
, schema
, child
,
12073 XML_SCHEMA_TYPE_SIMPLE_CONTENT
);
12074 (*hasRestrictionOrExtension
) = 1;
12075 child
= child
->next
;
12077 if (child
!= NULL
) {
12078 xmlSchemaPContentErr(ctxt
,
12079 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
12080 NULL
, node
, child
, NULL
,
12081 "(annotation?, (restriction | extension))");
12087 * xmlSchemaParseComplexContent:
12088 * @ctxt: a schema validation context
12089 * @schema: the schema being built
12090 * @node: a subtree containing XML Schema information
12092 * parse a XML schema ComplexContent definition
12093 * *WARNING* this interface is highly subject to change
12095 * Returns the type definition or NULL in case of error
12098 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt
,
12099 xmlSchemaPtr schema
, xmlNodePtr node
,
12100 int *hasRestrictionOrExtension
)
12102 xmlSchemaTypePtr type
;
12103 xmlNodePtr child
= NULL
;
12106 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
) ||
12107 (hasRestrictionOrExtension
== NULL
))
12109 *hasRestrictionOrExtension
= 0;
12110 /* Not a component, don't create it. */
12111 type
= ctxt
->ctxtType
;
12113 * Check for illegal attributes.
12115 attr
= node
->properties
;
12116 while (attr
!= NULL
) {
12117 if (attr
->ns
== NULL
) {
12118 if ((!xmlStrEqual(attr
->name
, BAD_CAST
"id")) &&
12119 (!xmlStrEqual(attr
->name
, BAD_CAST
"mixed")))
12121 xmlSchemaPIllegalAttrErr(ctxt
,
12122 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12124 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
12125 xmlSchemaPIllegalAttrErr(ctxt
,
12126 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12131 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
12134 * Set the 'mixed' on the complex type ancestor.
12136 if (xmlGetBooleanProp(ctxt
, node
, "mixed", 0)) {
12137 if ((type
->flags
& XML_SCHEMAS_TYPE_MIXED
) == 0)
12138 type
->flags
|= XML_SCHEMAS_TYPE_MIXED
;
12140 child
= node
->children
;
12141 if (IS_SCHEMA(child
, "annotation")) {
12143 * Add the annotation to the complex type ancestor.
12145 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr
) type
,
12146 xmlSchemaParseAnnotation(ctxt
, child
, 1));
12147 child
= child
->next
;
12149 if (child
== NULL
) {
12150 xmlSchemaPContentErr(ctxt
,
12151 XML_SCHEMAP_S4S_ELEM_MISSING
,
12153 NULL
, "(annotation?, (restriction | extension))");
12155 if (child
== NULL
) {
12156 xmlSchemaPContentErr(ctxt
,
12157 XML_SCHEMAP_S4S_ELEM_MISSING
,
12159 NULL
, "(annotation?, (restriction | extension))");
12161 if (IS_SCHEMA(child
, "restriction")) {
12162 xmlSchemaParseRestriction(ctxt
, schema
, child
,
12163 XML_SCHEMA_TYPE_COMPLEX_CONTENT
);
12164 (*hasRestrictionOrExtension
) = 1;
12165 child
= child
->next
;
12166 } else if (IS_SCHEMA(child
, "extension")) {
12167 xmlSchemaParseExtension(ctxt
, schema
, child
,
12168 XML_SCHEMA_TYPE_COMPLEX_CONTENT
);
12169 (*hasRestrictionOrExtension
) = 1;
12170 child
= child
->next
;
12172 if (child
!= NULL
) {
12173 xmlSchemaPContentErr(ctxt
,
12174 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
12176 NULL
, "(annotation?, (restriction | extension))");
12182 * xmlSchemaParseComplexType:
12183 * @ctxt: a schema validation context
12184 * @schema: the schema being built
12185 * @node: a subtree containing XML Schema information
12187 * parse a XML schema Complex Type definition
12188 * *WARNING* this interface is highly subject to change
12190 * Returns the type definition or NULL in case of error
12192 static xmlSchemaTypePtr
12193 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt
, xmlSchemaPtr schema
,
12194 xmlNodePtr node
, int topLevel
)
12196 xmlSchemaTypePtr type
, ctxtType
;
12197 xmlNodePtr child
= NULL
;
12198 const xmlChar
*name
= NULL
;
12200 const xmlChar
*attrValue
;
12201 #ifdef ENABLE_NAMED_LOCALS
12204 int final
= 0, block
= 0, hasRestrictionOrExtension
= 0;
12207 if ((ctxt
== NULL
) || (schema
== NULL
) || (node
== NULL
))
12210 ctxtType
= ctxt
->ctxtType
;
12213 attr
= xmlSchemaGetPropNode(node
, "name");
12214 if (attr
== NULL
) {
12215 xmlSchemaPMissingAttrErr(ctxt
,
12216 XML_SCHEMAP_S4S_ATTR_MISSING
, NULL
, node
, "name", NULL
);
12218 } else if (xmlSchemaPValAttrNode(ctxt
, NULL
, attr
,
12219 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME
), &name
) != 0) {
12224 if (topLevel
== 0) {
12226 * Parse as local complex type definition.
12228 #ifdef ENABLE_NAMED_LOCALS
12229 snprintf(buf
, 39, "#CT%d", ctxt
->counter
++ + 1);
12230 type
= xmlSchemaAddType(ctxt
, schema
,
12231 XML_SCHEMA_TYPE_COMPLEX
,
12232 xmlDictLookup(ctxt
->dict
, (const xmlChar
*)buf
, -1),
12233 ctxt
->targetNamespace
, node
, 0);
12235 type
= xmlSchemaAddType(ctxt
, schema
,
12236 XML_SCHEMA_TYPE_COMPLEX
,
12237 NULL
, ctxt
->targetNamespace
, node
, 0);
12243 type
->type
= XML_SCHEMA_TYPE_COMPLEX
;
12245 * TODO: We need the target namespace.
12249 * Parse as global complex type definition.
12251 type
= xmlSchemaAddType(ctxt
, schema
,
12252 XML_SCHEMA_TYPE_COMPLEX
,
12253 name
, ctxt
->targetNamespace
, node
, 1);
12257 type
->type
= XML_SCHEMA_TYPE_COMPLEX
;
12258 type
->flags
|= XML_SCHEMAS_TYPE_GLOBAL
;
12260 type
->targetNamespace
= ctxt
->targetNamespace
;
12262 * Handle attributes.
12264 attr
= node
->properties
;
12265 while (attr
!= NULL
) {
12266 if (attr
->ns
== NULL
) {
12267 if (xmlStrEqual(attr
->name
, BAD_CAST
"id")) {
12271 xmlSchemaPValAttrID(ctxt
, node
, BAD_CAST
"id");
12272 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"mixed")) {
12274 * Attribute "mixed".
12276 if (xmlSchemaPGetBoolNodeValue(ctxt
,
12277 NULL
, (xmlNodePtr
) attr
))
12278 type
->flags
|= XML_SCHEMAS_TYPE_MIXED
;
12279 } else if (topLevel
) {
12281 * Attributes of global complex type definitions.
12283 if (xmlStrEqual(attr
->name
, BAD_CAST
"name")) {
12285 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"abstract")) {
12287 * Attribute "abstract".
12289 if (xmlSchemaPGetBoolNodeValue(ctxt
,
12290 NULL
, (xmlNodePtr
) attr
))
12291 type
->flags
|= XML_SCHEMAS_TYPE_ABSTRACT
;
12292 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"final")) {
12294 * Attribute "final".
12296 attrValue
= xmlSchemaGetNodeContent(ctxt
,
12297 (xmlNodePtr
) attr
);
12298 if (xmlSchemaPValAttrBlockFinal(attrValue
,
12301 XML_SCHEMAS_TYPE_FINAL_EXTENSION
,
12302 XML_SCHEMAS_TYPE_FINAL_RESTRICTION
,
12305 xmlSchemaPSimpleTypeErr(ctxt
,
12306 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
12307 NULL
, (xmlNodePtr
) attr
, NULL
,
12308 "(#all | List of (extension | restriction))",
12309 attrValue
, NULL
, NULL
, NULL
);
12312 } else if (xmlStrEqual(attr
->name
, BAD_CAST
"block")) {
12314 * Attribute "block".
12316 attrValue
= xmlSchemaGetNodeContent(ctxt
,
12317 (xmlNodePtr
) attr
);
12318 if (xmlSchemaPValAttrBlockFinal(attrValue
, &(type
->flags
),
12320 XML_SCHEMAS_TYPE_BLOCK_EXTENSION
,
12321 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
,
12322 -1, -1, -1) != 0) {
12323 xmlSchemaPSimpleTypeErr(ctxt
,
12324 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE
,
12325 NULL
, (xmlNodePtr
) attr
, NULL
,
12326 "(#all | List of (extension | restriction)) ",
12327 attrValue
, NULL
, NULL
, NULL
);
12331 xmlSchemaPIllegalAttrErr(ctxt
,
12332 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12335 xmlSchemaPIllegalAttrErr(ctxt
,
12336 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12338 } else if (xmlStrEqual(attr
->ns
->href
, xmlSchemaNs
)) {
12339 xmlSchemaPIllegalAttrErr(ctxt
,
12340 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED
, NULL
, attr
);
12346 * Apply default "block" values.
12348 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION
)
12349 type
->flags
|= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
;
12350 if (schema
->flags
& XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION
)
12351 type
->flags
|= XML_SCHEMAS_TYPE_BLOCK_EXTENSION
;
12355 * Apply default "block" values.
12357 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION
)
12358 type
->flags
|= XML_SCHEMAS_TYPE_FINAL_RESTRICTION
;
12359 if (schema
->flags
& XML_SCHEMAS_FINAL_DEFAULT_EXTENSION
)
12360 type
->flags
|= XML_SCHEMAS_TYPE_FINAL_EXTENSION
;
12363 * And now for the children...
12365 child
= node
->children
;
12366 if (IS_SCHEMA(child
, "annotation")) {
12367 type
->annot
= xmlSchemaParseAnnotation(ctxt
, child
, 1);
12368 child
= child
->next
;
12370 ctxt
->ctxtType
= type
;
12371 if (IS_SCHEMA(child
, "simpleContent")) {
12373 * <complexType><simpleContent>...
12375 * Specifying mixed='true' when the <simpleContent>
12376 * alternative is chosen has no effect
12378 if (type
->flags
& XML_SCHEMAS_TYPE_MIXED
)
12379 type
->flags
^= XML_SCHEMAS_TYPE_MIXED
;
12380 xmlSchemaParseSimpleContent(ctxt
, schema
, child
,
12381 &hasRestrictionOrExtension
);
12382 child
= child
->next
;
12383 } else if (IS_SCHEMA(child
, "complexContent")) {
12385 * <complexType><complexContent>...
12387 type
->contentType
= XML_SCHEMA_CONTENT_EMPTY
;
12388 xmlSchemaParseComplexContent(ctxt
, schema
, child
,
12389 &hasRestrictionOrExtension
);
12390 child
= child
->next
;
12393 * E.g <complexType><sequence>... or <complexType><attribute>... etc.
12396 * "...the third alternative (neither <simpleContent> nor
12397 * <complexContent>) is chosen. This case is understood as shorthand
12398 * for complex content restricting the `ur-type definition`, and the
12399 * details of the mappings should be modified as necessary.
12401 type
->baseType
= xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE
);
12402 type
->flags
|= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION
;
12404 * Parse model groups.
12406 if (IS_SCHEMA(child
, "all")) {
12407 type
->subtypes
= (xmlSchemaTypePtr
)
12408 xmlSchemaParseModelGroup(ctxt
, schema
, child
,
12409 XML_SCHEMA_TYPE_ALL
, 1);
12410 child
= child
->next
;
12411 } else if (IS_SCHEMA(child
, "choice")) {
12412 type
->subtypes
= (xmlSchemaTypePtr
)
12413 xmlSchemaParseModelGroup(ctxt
, schema
, child
,
12414 XML_SCHEMA_TYPE_CHOICE
, 1);
12415 child
= child
->next
;
12416 } else if (IS_SCHEMA(child
, "sequence")) {
12417 type
->subtypes
= (xmlSchemaTypePtr
)
12418 xmlSchemaParseModelGroup(ctxt
, schema
, child
,
12419 XML_SCHEMA_TYPE_SEQUENCE
, 1);
12420 child
= child
->next
;
12421 } else if (IS_SCHEMA(child
, "group")) {
12422 type
->subtypes
= (xmlSchemaTypePtr
)
12423 xmlSchemaParseModelGroupDefRef(ctxt
, schema
, child
);
12425 * Note that the reference will be resolved in
12426 * xmlSchemaResolveTypeReferences();
12428 child
= child
->next
;
12431 * Parse attribute decls/refs.
12433 if (xmlSchemaParseLocalAttributes(ctxt
, schema
, &child
,
12434 (xmlSchemaItemListPtr
*) &(type
->attrUses
),
12435 XML_SCHEMA_TYPE_RESTRICTION
, NULL
) == -1)
12438 * Parse attribute wildcard.
12440 if (IS_SCHEMA(child
, "anyAttribute")) {
12441 type
->attributeWildcard
= xmlSchemaParseAnyAttribute(ctxt
, schema
, child
);
12442 child
= child
->next
;
12445 if (child
!= NULL
) {
12446 xmlSchemaPContentErr(ctxt
,
12447 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED
,
12449 NULL
, "(annotation?, (simpleContent | complexContent | "
12450 "((group | all | choice | sequence)?, ((attribute | "
12451 "attributeGroup)*, anyAttribute?))))");
12454 * REDEFINE: SPEC src-redefine (5)
12456 if (topLevel
&& ctxt
->isRedefine
&& (! hasRestrictionOrExtension
)) {
12457 xmlSchemaPCustomErr(ctxt
, XML_SCHEMAP_SRC_REDEFINE
,
12458 NULL
, node
, "This is a redefinition, thus the "
12459 "<complexType> must have a <restriction> or <extension> "
12460 "grand-child", NULL
);
12462 ctxt
->ctxtType
= ctxtType
;
12466 /************************************************************************
12468 * Validating using Schemas *
12470 ************************************************************************/
12472 /************************************************************************
12474 * Reading/Writing Schemas *
12476 ************************************************************************/
12478 #if 0 /* Will be enabled if it is clear what options are needed. */
12480 * xmlSchemaParserCtxtSetOptions:
12481 * @ctxt: a schema parser context
12482 * @options: a combination of xmlSchemaParserOption
12484 * Sets the options to be used during the parse.
12486 * Returns 0 in case of success, -1 in case of an
12490 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt
,
12499 * WARNING: Change the start value if adding to the
12500 * xmlSchemaParseOption.
12502 for (i
= 1; i
< (int) sizeof(int) * 8; i
++) {
12503 if (options
& 1<<i
) {
12507 ctxt
->options
= options
;
12512 * xmlSchemaValidCtxtGetOptions:
12513 * @ctxt: a schema parser context
12515 * Returns the option combination of the parser context.
12518 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt
)
12524 return (ctxt
->options
);
12529 * xmlSchemaNewParserCtxt:
12530 * @URL: the location of the schema
12532 * Create an XML Schemas parse context for that file/resource expected
12533 * to contain an XML Schemas file.
12535 * Returns the parser context or NULL in case of error
12537 xmlSchemaParserCtxtPtr
12538 xmlSchemaNewParserCtxt(const char *URL
)
12540 xmlSchemaParserCtxtPtr ret
;
12545 ret
= xmlSchemaParserCtxtCreate();
12548 ret
->dict
= xmlDictCreate();
12549 ret
->URL
= xmlDictLookup(ret
->dict
, (const xmlChar
*) URL
, -1);
12554 * xmlSchemaNewMemParserCtxt:
12555 * @buffer: a pointer to a char array containing the schemas
12556 * @size: the size of the array
12558 * Create an XML Schemas parse context for that memory buffer expected
12559 * to contain an XML Schemas file.
12561 * Returns the parser context or NULL in case of error
12563 xmlSchemaParserCtxtPtr
12564 xmlSchemaNewMemParserCtxt(const char *buffer
, int size
)
12566 xmlSchemaParserCtxtPtr ret
;
12568 if ((buffer
== NULL
) || (size
<= 0))
12570 ret
= xmlSchemaParserCtxtCreate();
12573 ret
->buffer
= buffer
;
12575 ret
->dict
= xmlDictCreate();
12580 * xmlSchemaNewDocParserCtxt:
12581 * @doc: a preparsed document tree
12583 * Create an XML Schemas parse context for that document.
12584 * NB. The document may be modified during the parsing process.
12586 * Returns the parser context or NULL in case of error
12588 xmlSchemaParserCtxtPtr
12589 xmlSchemaNewDocParserCtxt(xmlDocPtr doc
)
12591 xmlSchemaParserCtxtPtr ret
;
12595 ret
= xmlSchemaParserCtxtCreate();
12599 ret
->dict
= xmlDictCreate();
12600 /* The application has responsibility for the document */
12607 * xmlSchemaFreeParserCtxt:
12608 * @ctxt: the schema parser context
12610 * Free the resources associated to the schema parser context
12613 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt
)
12617 if (ctxt
->doc
!= NULL
&& !ctxt
->preserve
)
12618 xmlFreeDoc(ctxt
->doc
);
12619 if (ctxt
->vctxt
!= NULL
) {
12620 xmlSchemaFreeValidCtxt(ctxt
->vctxt
);
12622 if (ctxt
->ownsConstructor
&& (ctxt
->constructor
!= NULL
)) {
12623 xmlSchemaConstructionCtxtFree(ctxt
->constructor
);
12624 ctxt
->constructor
= NULL
;
12625 ctxt
->ownsConstructor
= 0;
12627 if (ctxt
->attrProhibs
!= NULL
)
12628 xmlSchemaItemListFree(ctxt
->attrProhibs
);
12629 xmlDictFree(ctxt
->dict
);
12633 /************************************************************************
12635 * Building the content models *
12637 ************************************************************************/
12640 * xmlSchemaBuildContentModelForSubstGroup:
12642 * Returns 1 if nillable, 0 otherwise
12645 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt
,
12646 xmlSchemaParticlePtr particle
, int counter
, xmlAutomataStatePtr end
)
12648 xmlAutomataStatePtr start
, tmp
;
12649 xmlSchemaElementPtr elemDecl
, member
;
12650 xmlSchemaSubstGroupPtr substGroup
;
12654 elemDecl
= (xmlSchemaElementPtr
) particle
->children
;
12656 * Wrap the substitution group with a CHOICE.
12658 start
= pctxt
->state
;
12660 end
= xmlAutomataNewState(pctxt
->am
);
12661 substGroup
= xmlSchemaSubstGroupGet(pctxt
, elemDecl
);
12662 if (substGroup
== NULL
) {
12663 xmlSchemaPErr(pctxt
, WXS_ITEM_NODE(particle
),
12664 XML_SCHEMAP_INTERNAL
,
12665 "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12666 "declaration is marked having a subst. group but none "
12667 "available.\n", elemDecl
->name
, NULL
);
12670 if (counter
>= 0) {
12672 * NOTE that we put the declaration in, even if it's abstract.
12673 * However, an error will be raised during *validation* if an element
12674 * information item shall be validated against an abstract element
12677 tmp
= xmlAutomataNewCountedTrans(pctxt
->am
, start
, NULL
, counter
);
12678 xmlAutomataNewTransition2(pctxt
->am
, tmp
, end
,
12679 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
);
12681 * Add subst. group members.
12683 for (i
= 0; i
< substGroup
->members
->nbItems
; i
++) {
12684 member
= (xmlSchemaElementPtr
) substGroup
->members
->items
[i
];
12685 xmlAutomataNewTransition2(pctxt
->am
, tmp
, end
,
12686 member
->name
, member
->targetNamespace
, member
);
12688 } else if (particle
->maxOccurs
== 1) {
12690 * NOTE that we put the declaration in, even if it's abstract,
12692 xmlAutomataNewEpsilon(pctxt
->am
,
12693 xmlAutomataNewTransition2(pctxt
->am
,
12695 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
), end
);
12697 * Add subst. group members.
12699 for (i
= 0; i
< substGroup
->members
->nbItems
; i
++) {
12700 member
= (xmlSchemaElementPtr
) substGroup
->members
->items
[i
];
12702 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12703 * was incorrectly used instead of xmlAutomataNewTransition2()
12704 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12705 * section in xmlSchemaBuildAContentModel() ).
12706 * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12707 * intended for the above "counter" section originally. I.e.,
12708 * check xs:all with subst-groups.
12710 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12711 * member->name, member->targetNamespace,
12714 tmp
= xmlAutomataNewTransition2(pctxt
->am
, start
, NULL
,
12715 member
->name
, member
->targetNamespace
, member
);
12716 xmlAutomataNewEpsilon(pctxt
->am
, tmp
, end
);
12719 xmlAutomataStatePtr hop
;
12720 int maxOccurs
= particle
->maxOccurs
== UNBOUNDED
?
12721 UNBOUNDED
: particle
->maxOccurs
- 1;
12722 int minOccurs
= particle
->minOccurs
< 1 ? 0 : particle
->minOccurs
- 1;
12725 xmlAutomataNewCounter(pctxt
->am
, minOccurs
,
12727 hop
= xmlAutomataNewState(pctxt
->am
);
12729 xmlAutomataNewEpsilon(pctxt
->am
,
12730 xmlAutomataNewTransition2(pctxt
->am
,
12732 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
),
12735 * Add subst. group members.
12737 for (i
= 0; i
< substGroup
->members
->nbItems
; i
++) {
12738 member
= (xmlSchemaElementPtr
) substGroup
->members
->items
[i
];
12739 xmlAutomataNewEpsilon(pctxt
->am
,
12740 xmlAutomataNewTransition2(pctxt
->am
,
12742 member
->name
, member
->targetNamespace
, member
),
12745 xmlAutomataNewCountedTrans(pctxt
->am
, hop
, start
, counter
);
12746 xmlAutomataNewCounterTrans(pctxt
->am
, hop
, end
, counter
);
12748 if (particle
->minOccurs
== 0) {
12749 xmlAutomataNewEpsilon(pctxt
->am
, start
, end
);
12752 pctxt
->state
= end
;
12757 * xmlSchemaBuildContentModelForElement:
12759 * Returns 1 if nillable, 0 otherwise
12762 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt
,
12763 xmlSchemaParticlePtr particle
)
12767 if (((xmlSchemaElementPtr
) particle
->children
)->flags
&
12768 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD
) {
12770 * Substitution groups.
12772 ret
= xmlSchemaBuildContentModelForSubstGroup(ctxt
, particle
, -1, NULL
);
12774 xmlSchemaElementPtr elemDecl
;
12775 xmlAutomataStatePtr start
;
12777 elemDecl
= (xmlSchemaElementPtr
) particle
->children
;
12779 if (elemDecl
->flags
& XML_SCHEMAS_ELEM_ABSTRACT
)
12781 if (particle
->maxOccurs
== 1) {
12782 start
= ctxt
->state
;
12783 ctxt
->state
= xmlAutomataNewTransition2(ctxt
->am
, start
, NULL
,
12784 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
);
12785 } else if ((particle
->maxOccurs
>= UNBOUNDED
) &&
12786 (particle
->minOccurs
< 2)) {
12787 /* Special case. */
12788 start
= ctxt
->state
;
12789 ctxt
->state
= xmlAutomataNewTransition2(ctxt
->am
, start
, NULL
,
12790 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
);
12791 ctxt
->state
= xmlAutomataNewTransition2(ctxt
->am
, ctxt
->state
, ctxt
->state
,
12792 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
);
12795 int maxOccurs
= particle
->maxOccurs
== UNBOUNDED
?
12796 UNBOUNDED
: particle
->maxOccurs
- 1;
12797 int minOccurs
= particle
->minOccurs
< 1 ?
12798 0 : particle
->minOccurs
- 1;
12800 start
= xmlAutomataNewEpsilon(ctxt
->am
, ctxt
->state
, NULL
);
12801 counter
= xmlAutomataNewCounter(ctxt
->am
, minOccurs
, maxOccurs
);
12802 ctxt
->state
= xmlAutomataNewTransition2(ctxt
->am
, start
, NULL
,
12803 elemDecl
->name
, elemDecl
->targetNamespace
, elemDecl
);
12804 xmlAutomataNewCountedTrans(ctxt
->am
, ctxt
->state
, start
, counter
);
12805 ctxt
->state
= xmlAutomataNewCounterTrans(ctxt
->am
, ctxt
->state
,
12808 if (particle
->minOccurs
== 0) {
12809 xmlAutomataNewEpsilon(ctxt
->am
, start
, ctxt
->state
);
12817 * xmlSchemaBuildAContentModel:
12818 * @ctxt: the schema parser context
12819 * @particle: the particle component
12820 * @name: the complex type's name whose content is being built
12822 * Create the automaton for the {content type} of a complex type.
12824 * Returns 1 if the content is nillable, 0 otherwise
12827 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt
,
12828 xmlSchemaParticlePtr particle
)
12832 if (particle
== NULL
) {
12833 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12836 if (particle
->children
== NULL
) {
12838 * Just return in this case. A missing "term" of the particle
12839 * might arise due to an invalid "term" component.
12844 switch (particle
->children
->type
) {
12845 case XML_SCHEMA_TYPE_ANY
: {
12846 xmlAutomataStatePtr start
, end
;
12847 xmlSchemaWildcardPtr wild
;
12848 xmlSchemaWildcardNsPtr ns
;
12850 wild
= (xmlSchemaWildcardPtr
) particle
->children
;
12852 start
= pctxt
->state
;
12853 end
= xmlAutomataNewState(pctxt
->am
);
12855 if (particle
->maxOccurs
== 1) {
12856 if (wild
->any
== 1) {
12858 * We need to add both transitions:
12860 * 1. the {"*", "*"} for elements in a namespace.
12863 xmlAutomataNewTransition2(pctxt
->am
,
12864 start
, NULL
, BAD_CAST
"*", BAD_CAST
"*", wild
);
12865 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, end
);
12867 * 2. the {"*"} for elements in no namespace.
12870 xmlAutomataNewTransition2(pctxt
->am
,
12871 start
, NULL
, BAD_CAST
"*", NULL
, wild
);
12872 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, end
);
12874 } else if (wild
->nsSet
!= NULL
) {
12877 pctxt
->state
= start
;
12878 pctxt
->state
= xmlAutomataNewTransition2(pctxt
->am
,
12879 pctxt
->state
, NULL
, BAD_CAST
"*", ns
->value
, wild
);
12880 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, end
);
12882 } while (ns
!= NULL
);
12884 } else if (wild
->negNsSet
!= NULL
) {
12885 pctxt
->state
= xmlAutomataNewNegTrans(pctxt
->am
,
12886 start
, end
, BAD_CAST
"*", wild
->negNsSet
->value
,
12891 xmlAutomataStatePtr hop
;
12893 particle
->maxOccurs
== UNBOUNDED
? UNBOUNDED
:
12894 particle
->maxOccurs
- 1;
12896 particle
->minOccurs
< 1 ? 0 : particle
->minOccurs
- 1;
12898 counter
= xmlAutomataNewCounter(pctxt
->am
, minOccurs
, maxOccurs
);
12899 hop
= xmlAutomataNewState(pctxt
->am
);
12900 if (wild
->any
== 1) {
12902 xmlAutomataNewTransition2(pctxt
->am
,
12903 start
, NULL
, BAD_CAST
"*", BAD_CAST
"*", wild
);
12904 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, hop
);
12906 xmlAutomataNewTransition2(pctxt
->am
,
12907 start
, NULL
, BAD_CAST
"*", NULL
, wild
);
12908 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, hop
);
12909 } else if (wild
->nsSet
!= NULL
) {
12913 xmlAutomataNewTransition2(pctxt
->am
,
12914 start
, NULL
, BAD_CAST
"*", ns
->value
, wild
);
12915 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, hop
);
12917 } while (ns
!= NULL
);
12919 } else if (wild
->negNsSet
!= NULL
) {
12920 pctxt
->state
= xmlAutomataNewNegTrans(pctxt
->am
,
12921 start
, hop
, BAD_CAST
"*", wild
->negNsSet
->value
,
12924 xmlAutomataNewCountedTrans(pctxt
->am
, hop
, start
, counter
);
12925 xmlAutomataNewCounterTrans(pctxt
->am
, hop
, end
, counter
);
12927 if (particle
->minOccurs
== 0) {
12928 xmlAutomataNewEpsilon(pctxt
->am
, start
, end
);
12931 pctxt
->state
= end
;
12934 case XML_SCHEMA_TYPE_ELEMENT
:
12935 ret
= xmlSchemaBuildContentModelForElement(pctxt
, particle
);
12937 case XML_SCHEMA_TYPE_SEQUENCE
:{
12938 xmlSchemaTreeItemPtr sub
;
12942 * If max and min occurrences are default (1) then
12943 * simply iterate over the particles of the <sequence>.
12945 if ((particle
->minOccurs
== 1) && (particle
->maxOccurs
== 1)) {
12946 sub
= particle
->children
->children
;
12948 while (sub
!= NULL
) {
12949 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
12950 (xmlSchemaParticlePtr
) sub
);
12951 if (tmp2
!= 1) ret
= 0;
12955 xmlAutomataStatePtr oldstate
= pctxt
->state
;
12957 if (particle
->maxOccurs
>= UNBOUNDED
) {
12958 if (particle
->minOccurs
> 1) {
12959 xmlAutomataStatePtr tmp
;
12962 pctxt
->state
= xmlAutomataNewEpsilon(pctxt
->am
,
12964 oldstate
= pctxt
->state
;
12966 counter
= xmlAutomataNewCounter(pctxt
->am
,
12967 particle
->minOccurs
- 1, UNBOUNDED
);
12969 sub
= particle
->children
->children
;
12970 while (sub
!= NULL
) {
12971 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
12972 (xmlSchemaParticlePtr
) sub
);
12973 if (tmp2
!= 1) ret
= 0;
12976 tmp
= pctxt
->state
;
12977 xmlAutomataNewCountedTrans(pctxt
->am
, tmp
,
12978 oldstate
, counter
);
12980 xmlAutomataNewCounterTrans(pctxt
->am
, tmp
,
12983 xmlAutomataNewEpsilon(pctxt
->am
,
12984 oldstate
, pctxt
->state
);
12987 pctxt
->state
= xmlAutomataNewEpsilon(pctxt
->am
,
12989 oldstate
= pctxt
->state
;
12991 sub
= particle
->children
->children
;
12992 while (sub
!= NULL
) {
12993 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
12994 (xmlSchemaParticlePtr
) sub
);
12995 if (tmp2
!= 1) ret
= 0;
12998 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
,
13001 * epsilon needed to block previous trans from
13002 * being allowed to enter back from another
13005 pctxt
->state
= xmlAutomataNewEpsilon(pctxt
->am
,
13006 pctxt
->state
, NULL
);
13007 if (particle
->minOccurs
== 0) {
13008 xmlAutomataNewEpsilon(pctxt
->am
,
13009 oldstate
, pctxt
->state
);
13013 } else if ((particle
->maxOccurs
> 1)
13014 || (particle
->minOccurs
> 1)) {
13015 xmlAutomataStatePtr tmp
;
13018 pctxt
->state
= xmlAutomataNewEpsilon(pctxt
->am
,
13020 oldstate
= pctxt
->state
;
13022 counter
= xmlAutomataNewCounter(pctxt
->am
,
13023 particle
->minOccurs
- 1,
13024 particle
->maxOccurs
- 1);
13026 sub
= particle
->children
->children
;
13027 while (sub
!= NULL
) {
13028 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
13029 (xmlSchemaParticlePtr
) sub
);
13030 if (tmp2
!= 1) ret
= 0;
13033 tmp
= pctxt
->state
;
13034 xmlAutomataNewCountedTrans(pctxt
->am
,
13035 tmp
, oldstate
, counter
);
13037 xmlAutomataNewCounterTrans(pctxt
->am
, tmp
, NULL
,
13039 if ((particle
->minOccurs
== 0) || (ret
== 1)) {
13040 xmlAutomataNewEpsilon(pctxt
->am
,
13041 oldstate
, pctxt
->state
);
13045 sub
= particle
->children
->children
;
13046 while (sub
!= NULL
) {
13047 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
13048 (xmlSchemaParticlePtr
) sub
);
13049 if (tmp2
!= 1) ret
= 0;
13054 * epsilon needed to block previous trans from
13055 * being allowed to enter back from another
13058 pctxt
->state
= xmlAutomataNewEpsilon(pctxt
->am
,
13059 pctxt
->state
, NULL
);
13061 if (particle
->minOccurs
== 0) {
13062 xmlAutomataNewEpsilon(pctxt
->am
, oldstate
,
13070 case XML_SCHEMA_TYPE_CHOICE
:{
13071 xmlSchemaTreeItemPtr sub
;
13072 xmlAutomataStatePtr start
, end
;
13075 start
= pctxt
->state
;
13076 end
= xmlAutomataNewState(pctxt
->am
);
13079 * iterate over the subtypes and remerge the end with an
13080 * epsilon transition
13082 if (particle
->maxOccurs
== 1) {
13083 sub
= particle
->children
->children
;
13084 while (sub
!= NULL
) {
13085 pctxt
->state
= start
;
13086 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
13087 (xmlSchemaParticlePtr
) sub
);
13088 if (tmp2
== 1) ret
= 1;
13089 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, end
);
13094 xmlAutomataStatePtr hop
, base
;
13095 int maxOccurs
= particle
->maxOccurs
== UNBOUNDED
?
13096 UNBOUNDED
: particle
->maxOccurs
- 1;
13098 particle
->minOccurs
< 1 ? 0 : particle
->minOccurs
- 1;
13101 * use a counter to keep track of the number of transitions
13102 * which went through the choice.
13105 xmlAutomataNewCounter(pctxt
->am
, minOccurs
, maxOccurs
);
13106 hop
= xmlAutomataNewState(pctxt
->am
);
13107 base
= xmlAutomataNewState(pctxt
->am
);
13109 sub
= particle
->children
->children
;
13110 while (sub
!= NULL
) {
13111 pctxt
->state
= base
;
13112 tmp2
= xmlSchemaBuildAContentModel(pctxt
,
13113 (xmlSchemaParticlePtr
) sub
);
13114 if (tmp2
== 1) ret
= 1;
13115 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, hop
);
13118 xmlAutomataNewEpsilon(pctxt
->am
, start
, base
);
13119 xmlAutomataNewCountedTrans(pctxt
->am
, hop
, base
, counter
);
13120 xmlAutomataNewCounterTrans(pctxt
->am
, hop
, end
, counter
);
13122 xmlAutomataNewEpsilon(pctxt
->am
, base
, end
);
13124 if (particle
->minOccurs
== 0) {
13125 xmlAutomataNewEpsilon(pctxt
->am
, start
, end
);
13128 pctxt
->state
= end
;
13131 case XML_SCHEMA_TYPE_ALL
:{
13132 xmlAutomataStatePtr start
, tmp
;
13133 xmlSchemaParticlePtr sub
;
13134 xmlSchemaElementPtr elemDecl
;
13138 sub
= (xmlSchemaParticlePtr
) particle
->children
->children
;
13144 start
= pctxt
->state
;
13145 tmp
= xmlAutomataNewState(pctxt
->am
);
13146 xmlAutomataNewEpsilon(pctxt
->am
, pctxt
->state
, tmp
);
13147 pctxt
->state
= tmp
;
13148 while (sub
!= NULL
) {
13149 pctxt
->state
= tmp
;
13151 elemDecl
= (xmlSchemaElementPtr
) sub
->children
;
13152 if (elemDecl
== NULL
) {
13153 PERROR_INT("xmlSchemaBuildAContentModel",
13154 "<element> particle has no term");
13158 * NOTE: The {max occurs} of all the particles in the
13159 * {particles} of the group must be 0 or 1; this is
13160 * already ensured during the parse of the content of
13163 if (elemDecl
->flags
& XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD
) {
13167 * This is an abstract group, we need to share
13168 * the same counter for all the element transitions
13169 * derived from the group
13171 counter
= xmlAutomataNewCounter(pctxt
->am
,
13172 sub
->minOccurs
, sub
->maxOccurs
);
13173 xmlSchemaBuildContentModelForSubstGroup(pctxt
,
13174 sub
, counter
, pctxt
->state
);
13176 if ((sub
->minOccurs
== 1) &&
13177 (sub
->maxOccurs
== 1)) {
13178 xmlAutomataNewOnceTrans2(pctxt
->am
, pctxt
->state
,
13181 elemDecl
->targetNamespace
,
13183 } else if ((sub
->minOccurs
== 0) &&
13184 (sub
->maxOccurs
== 1)) {
13186 xmlAutomataNewCountTrans2(pctxt
->am
, pctxt
->state
,
13189 elemDecl
->targetNamespace
,
13195 sub
= (xmlSchemaParticlePtr
) sub
->next
;
13198 xmlAutomataNewAllTrans(pctxt
->am
, pctxt
->state
, NULL
, 0);
13199 if (particle
->minOccurs
== 0) {
13200 xmlAutomataNewEpsilon(pctxt
->am
, start
, pctxt
->state
);
13205 case XML_SCHEMA_TYPE_GROUP
:
13207 * If we hit a model group definition, then this means that
13208 * it was empty, thus was not substituted for the containing
13209 * model group. Just do nothing in this case.
13210 * TODO: But the group should be substituted and not occur at
13211 * all in the content model at this point. Fix this.
13216 xmlSchemaInternalErr2(ACTXT_CAST pctxt
,
13217 "xmlSchemaBuildAContentModel",
13218 "found unexpected term of type '%s' in content model",
13219 WXS_ITEM_TYPE_NAME(particle
->children
), NULL
);
13226 * xmlSchemaBuildContentModel:
13227 * @ctxt: the schema parser context
13228 * @type: the complex type definition
13229 * @name: the element name
13231 * Builds the content model of the complex type.
13234 xmlSchemaBuildContentModel(xmlSchemaTypePtr type
,
13235 xmlSchemaParserCtxtPtr ctxt
)
13237 if ((type
->type
!= XML_SCHEMA_TYPE_COMPLEX
) ||
13238 (type
->contModel
!= NULL
) ||
13239 ((type
->contentType
!= XML_SCHEMA_CONTENT_ELEMENTS
) &&
13240 (type
->contentType
!= XML_SCHEMA_CONTENT_MIXED
)))
13243 #ifdef DEBUG_CONTENT
13244 xmlGenericError(xmlGenericErrorContext
,
13245 "Building content model for %s\n", name
);
13248 ctxt
->am
= xmlNewAutomata();
13249 if (ctxt
->am
== NULL
) {
13250 xmlGenericError(xmlGenericErrorContext
,
13251 "Cannot create automata for complex type %s\n", type
->name
);
13254 ctxt
->state
= xmlAutomataGetInitState(ctxt
->am
);
13256 * Build the automaton.
13258 xmlSchemaBuildAContentModel(ctxt
, WXS_TYPE_PARTICLE(type
));
13259 xmlAutomataSetFinalState(ctxt
->am
, ctxt
->state
);
13260 type
->contModel
= xmlAutomataCompile(ctxt
->am
);
13261 if (type
->contModel
== NULL
) {
13262 xmlSchemaPCustomErr(ctxt
,
13263 XML_SCHEMAP_INTERNAL
,
13264 WXS_BASIC_CAST type
, type
->node
,
13265 "Failed to compile the content model", NULL
);
13266 } else if (xmlRegexpIsDeterminist(type
->contModel
) != 1) {
13267 xmlSchemaPCustomErr(ctxt
,
13268 XML_SCHEMAP_NOT_DETERMINISTIC
,
13269 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13270 WXS_BASIC_CAST type
, type
->node
,
13271 "The content model is not determinist", NULL
);
13273 #ifdef DEBUG_CONTENT_REGEXP
13274 xmlGenericError(xmlGenericErrorContext
,
13275 "Content model of %s:\n", type
->name
);
13276 xmlRegexpPrint(stderr
, type
->contModel
);
13279 ctxt
->state
= NULL
;
13280 xmlFreeAutomata(ctxt
->am
);
13285 * xmlSchemaResolveElementReferences:
13286 * @elem: the schema element context
13287 * @ctxt: the schema parser context
13289 * Resolves the references of an element declaration
13290 * or particle, which has an element declaration as it's
13294 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl
,
13295 xmlSchemaParserCtxtPtr ctxt
)
13297 if ((ctxt
== NULL
) || (elemDecl
== NULL
) ||
13298 ((elemDecl
!= NULL
) &&
13299 (elemDecl
->flags
& XML_SCHEMAS_ELEM_INTERNAL_RESOLVED
)))
13301 elemDecl
->flags
|= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED
;
13303 if ((elemDecl
->subtypes
== NULL
) && (elemDecl
->namedType
!= NULL
)) {
13304 xmlSchemaTypePtr type
;
13306 /* (type definition) ... otherwise the type definition `resolved`
13307 * to by the `actual value` of the type [attribute] ...
13309 type
= xmlSchemaGetType(ctxt
->schema
, elemDecl
->namedType
,
13310 elemDecl
->namedTypeNs
);
13311 if (type
== NULL
) {
13312 xmlSchemaPResCompAttrErr(ctxt
,
13313 XML_SCHEMAP_SRC_RESOLVE
,
13314 WXS_BASIC_CAST elemDecl
, elemDecl
->node
,
13315 "type", elemDecl
->namedType
, elemDecl
->namedTypeNs
,
13316 XML_SCHEMA_TYPE_BASIC
, "type definition");
13318 elemDecl
->subtypes
= type
;
13320 if (elemDecl
->substGroup
!= NULL
) {
13321 xmlSchemaElementPtr substHead
;
13324 * FIXME TODO: Do we need a new field in _xmlSchemaElement for
13325 * substitutionGroup?
13327 substHead
= xmlSchemaGetElem(ctxt
->schema
, elemDecl
->substGroup
,
13328 elemDecl
->substGroupNs
);
13329 if (substHead
== NULL
) {
13330 xmlSchemaPResCompAttrErr(ctxt
,
13331 XML_SCHEMAP_SRC_RESOLVE
,
13332 WXS_BASIC_CAST elemDecl
, NULL
,
13333 "substitutionGroup", elemDecl
->substGroup
,
13334 elemDecl
->substGroupNs
, XML_SCHEMA_TYPE_ELEMENT
, NULL
);
13336 xmlSchemaResolveElementReferences(substHead
, ctxt
);
13338 * Set the "substitution group affiliation".
13339 * NOTE that now we use the "refDecl" field for this.
13341 WXS_SUBST_HEAD(elemDecl
) = substHead
;
13343 * The type definitions is set to:
13344 * SPEC "...the {type definition} of the element
13345 * declaration `resolved` to by the `actual value`
13346 * of the substitutionGroup [attribute], if present"
13348 if (elemDecl
->subtypes
== NULL
)
13349 elemDecl
->subtypes
= substHead
->subtypes
;
13353 * SPEC "The definition of anyType serves as the default type definition
13354 * for element declarations whose XML representation does not specify one."
13356 if ((elemDecl
->subtypes
== NULL
) &&
13357 (elemDecl
->namedType
== NULL
) &&
13358 (elemDecl
->substGroup
== NULL
))
13359 elemDecl
->subtypes
= xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE
);
13363 * xmlSchemaResolveUnionMemberTypes:
13364 * @ctxt: the schema parser context
13365 * @type: the schema simple type definition
13367 * Checks and builds the "member type definitions" property of the union
13368 * simple type. This handles part (1), part (2) is done in
13369 * xmlSchemaFinishMemberTypeDefinitionsProperty()
13371 * Returns -1 in case of an internal error, 0 otherwise.
13374 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt
,
13375 xmlSchemaTypePtr type
)
13378 xmlSchemaTypeLinkPtr link
, lastLink
, newLink
;
13379 xmlSchemaTypePtr memberType
;
13382 * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13383 * define the explicit members as the type definitions `resolved`
13384 * to by the items in the `actual value` of the memberTypes [attribute],
13385 * if any, followed by the type definitions corresponding to the
13386 * <simpleType>s among the [children] of <union>, if any."
13389 * Resolve references.
13391 link
= type
->memberTypes
;
13393 while (link
!= NULL
) {
13394 const xmlChar
*name
, *nsName
;
13396 name
= ((xmlSchemaQNameRefPtr
) link
->type
)->name
;
13397 nsName
= ((xmlSchemaQNameRefPtr
) link
->type
)->targetNamespace
;
13399 memberType
= xmlSchemaGetType(ctxt
->schema
, name
, nsName
);
13400 if ((memberType
== NULL
) || (! WXS_IS_SIMPLE(memberType
))) {
13401 xmlSchemaPResCompAttrErr(ctxt
, XML_SCHEMAP_SRC_RESOLVE
,
13402 WXS_BASIC_CAST type
, type
->node
, "memberTypes",
13403 name
, nsName
, XML_SCHEMA_TYPE_SIMPLE
, NULL
);
13405 * Remove the member type link.
13407 if (lastLink
== NULL
)
13408 type
->memberTypes
= link
->next
;
13410 lastLink
->next
= link
->next
;
13415 link
->type
= memberType
;
13421 * Add local simple types,
13423 memberType
= type
->subtypes
;
13424 while (memberType
!= NULL
) {
13425 link
= (xmlSchemaTypeLinkPtr
) xmlMalloc(sizeof(xmlSchemaTypeLink
));
13426 if (link
== NULL
) {
13427 xmlSchemaPErrMemory(ctxt
, "allocating a type link", NULL
);
13430 link
->type
= memberType
;
13432 if (lastLink
== NULL
)
13433 type
->memberTypes
= link
;
13435 lastLink
->next
= link
;
13437 memberType
= memberType
->next
;
13443 * xmlSchemaIsDerivedFromBuiltInType:
13444 * @ctxt: the schema parser context
13445 * @type: the type definition
13446 * @valType: the value type
13449 * Returns 1 if the type has the given value type, or
13450 * is derived from such a type.
13453 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type
, int valType
)
13457 if (WXS_IS_COMPLEX(type
))
13459 if (type
->type
== XML_SCHEMA_TYPE_BASIC
) {
13460 if (type
->builtInType
== valType
)
13462 if ((type
->builtInType
== XML_SCHEMAS_ANYSIMPLETYPE
) ||
13463 (type
->builtInType
== XML_SCHEMAS_ANYTYPE
))
13465 return(xmlSchemaIsDerivedFromBuiltInType(type
->subtypes
, valType
));
13467 return(xmlSchemaIsDerivedFromBuiltInType(type
->subtypes
, valType
));
13472 * xmlSchemaIsDerivedFromBuiltInType:
13473 * @ctxt: the schema parser context
13474 * @type: the type definition
13475 * @valType: the value type
13478 * Returns 1 if the type has the given value type, or
13479 * is derived from such a type.
13482 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type
, int valType
)
13486 if (WXS_IS_COMPLEX(type
))
13488 if (type
->type
== XML_SCHEMA_TYPE_BASIC
) {
13489 if (type
->builtInType
== valType
)
13493 return(xmlSchemaIsDerivedFromBuiltInType(type
->subtypes
, valType
));
13498 static xmlSchemaTypePtr
13499 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type
)
13503 if (WXS_IS_COMPLEX(type
))
13505 if (type
->type
== XML_SCHEMA_TYPE_BASIC
)
13507 return(xmlSchemaQueryBuiltInType(type
->subtypes
));
13512 * xmlSchemaGetPrimitiveType:
13513 * @type: the simpleType definition
13515 * Returns the primitive type of the given type or
13516 * NULL in case of error.
13518 static xmlSchemaTypePtr
13519 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type
)
13522 while (type
!= NULL
) {
13524 * Note that anySimpleType is actually not a primitive type
13525 * but we need that here.
13527 if ((type
->builtInType
== XML_SCHEMAS_ANYSIMPLETYPE
) ||
13528 (type
->flags
& XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE
))
13530 type
= type
->baseType
;
13538 * xmlSchemaGetBuiltInTypeAncestor:
13539 * @type: the simpleType definition
13541 * Returns the primitive type of the given type or
13542 * NULL in case of error.
13544 static xmlSchemaTypePtr
13545 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type
)
13547 if (WXS_IS_LIST(type
) || WXS_IS_UNION(type
))
13549 while (type
!= NULL
) {
13550 if (type
->type
== XML_SCHEMA_TYPE_BASIC
)
13552 type
= type
->baseType
;
13560 * xmlSchemaCloneWildcardNsConstraints:
13561 * @ctxt: the schema parser context
13562 * @dest: the destination wildcard
13563 * @source: the source wildcard
13565 * Clones the namespace constraints of source
13566 * and assigns them to dest.
13567 * Returns -1 on internal error, 0 otherwise.
13570 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt
,
13571 xmlSchemaWildcardPtr dest
,
13572 xmlSchemaWildcardPtr source
)
13574 xmlSchemaWildcardNsPtr cur
, tmp
, last
;
13576 if ((source
== NULL
) || (dest
== NULL
))
13578 dest
->any
= source
->any
;
13579 cur
= source
->nsSet
;
13581 while (cur
!= NULL
) {
13582 tmp
= xmlSchemaNewWildcardNsConstraint(ctxt
);
13585 tmp
->value
= cur
->value
;
13593 if (dest
->negNsSet
!= NULL
)
13594 xmlSchemaFreeWildcardNsSet(dest
->negNsSet
);
13595 if (source
->negNsSet
!= NULL
) {
13596 dest
->negNsSet
= xmlSchemaNewWildcardNsConstraint(ctxt
);
13597 if (dest
->negNsSet
== NULL
)
13599 dest
->negNsSet
->value
= source
->negNsSet
->value
;
13601 dest
->negNsSet
= NULL
;
13606 * xmlSchemaUnionWildcards:
13607 * @ctxt: the schema parser context
13608 * @completeWild: the first wildcard
13609 * @curWild: the second wildcard
13611 * Unions the namespace constraints of the given wildcards.
13612 * @completeWild will hold the resulting union.
13613 * Returns a positive error code on failure, -1 in case of an
13614 * internal error, 0 otherwise.
13617 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt
,
13618 xmlSchemaWildcardPtr completeWild
,
13619 xmlSchemaWildcardPtr curWild
)
13621 xmlSchemaWildcardNsPtr cur
, curB
, tmp
;
13624 * 1 If O1 and O2 are the same value, then that value must be the
13627 if ((completeWild
->any
== curWild
->any
) &&
13628 ((completeWild
->nsSet
== NULL
) == (curWild
->nsSet
== NULL
)) &&
13629 ((completeWild
->negNsSet
== NULL
) == (curWild
->negNsSet
== NULL
))) {
13631 if ((completeWild
->negNsSet
== NULL
) ||
13632 (completeWild
->negNsSet
->value
== curWild
->negNsSet
->value
)) {
13634 if (completeWild
->nsSet
!= NULL
) {
13638 * Check equality of sets.
13640 cur
= completeWild
->nsSet
;
13641 while (cur
!= NULL
) {
13643 curB
= curWild
->nsSet
;
13644 while (curB
!= NULL
) {
13645 if (cur
->value
== curB
->value
) {
13662 * 2 If either O1 or O2 is any, then any must be the value
13664 if (completeWild
->any
!= curWild
->any
) {
13665 if (completeWild
->any
== 0) {
13666 completeWild
->any
= 1;
13667 if (completeWild
->nsSet
!= NULL
) {
13668 xmlSchemaFreeWildcardNsSet(completeWild
->nsSet
);
13669 completeWild
->nsSet
= NULL
;
13671 if (completeWild
->negNsSet
!= NULL
) {
13672 xmlFree(completeWild
->negNsSet
);
13673 completeWild
->negNsSet
= NULL
;
13679 * 3 If both O1 and O2 are sets of (namespace names or `absent`),
13680 * then the union of those sets must be the value.
13682 if ((completeWild
->nsSet
!= NULL
) && (curWild
->nsSet
!= NULL
)) {
13684 xmlSchemaWildcardNsPtr start
;
13686 cur
= curWild
->nsSet
;
13687 start
= completeWild
->nsSet
;
13688 while (cur
!= NULL
) {
13691 while (curB
!= NULL
) {
13692 if (cur
->value
== curB
->value
) {
13699 tmp
= xmlSchemaNewWildcardNsConstraint(ctxt
);
13702 tmp
->value
= cur
->value
;
13703 tmp
->next
= completeWild
->nsSet
;
13704 completeWild
->nsSet
= tmp
;
13712 * 4 If the two are negations of different values (namespace names
13713 * or `absent`), then a pair of not and `absent` must be the value.
13715 if ((completeWild
->negNsSet
!= NULL
) &&
13716 (curWild
->negNsSet
!= NULL
) &&
13717 (completeWild
->negNsSet
->value
!= curWild
->negNsSet
->value
)) {
13718 completeWild
->negNsSet
->value
= NULL
;
13725 if (((completeWild
->negNsSet
!= NULL
) &&
13726 (completeWild
->negNsSet
->value
!= NULL
) &&
13727 (curWild
->nsSet
!= NULL
)) ||
13728 ((curWild
->negNsSet
!= NULL
) &&
13729 (curWild
->negNsSet
->value
!= NULL
) &&
13730 (completeWild
->nsSet
!= NULL
))) {
13732 int nsFound
, absentFound
= 0;
13734 if (completeWild
->nsSet
!= NULL
) {
13735 cur
= completeWild
->nsSet
;
13736 curB
= curWild
->negNsSet
;
13738 cur
= curWild
->nsSet
;
13739 curB
= completeWild
->negNsSet
;
13742 while (cur
!= NULL
) {
13743 if (cur
->value
== NULL
)
13745 else if (cur
->value
== curB
->value
)
13747 if (nsFound
&& absentFound
)
13752 if (nsFound
&& absentFound
) {
13754 * 5.1 If the set S includes both the negated namespace
13755 * name and `absent`, then any must be the value.
13757 completeWild
->any
= 1;
13758 if (completeWild
->nsSet
!= NULL
) {
13759 xmlSchemaFreeWildcardNsSet(completeWild
->nsSet
);
13760 completeWild
->nsSet
= NULL
;
13762 if (completeWild
->negNsSet
!= NULL
) {
13763 xmlFree(completeWild
->negNsSet
);
13764 completeWild
->negNsSet
= NULL
;
13766 } else if (nsFound
&& (!absentFound
)) {
13768 * 5.2 If the set S includes the negated namespace name
13769 * but not `absent`, then a pair of not and `absent` must
13772 if (completeWild
->nsSet
!= NULL
) {
13773 xmlSchemaFreeWildcardNsSet(completeWild
->nsSet
);
13774 completeWild
->nsSet
= NULL
;
13776 if (completeWild
->negNsSet
== NULL
) {
13777 completeWild
->negNsSet
= xmlSchemaNewWildcardNsConstraint(ctxt
);
13778 if (completeWild
->negNsSet
== NULL
)
13781 completeWild
->negNsSet
->value
= NULL
;
13782 } else if ((!nsFound
) && absentFound
) {
13784 * 5.3 If the set S includes `absent` but not the negated
13785 * namespace name, then the union is not expressible.
13787 xmlSchemaPErr(ctxt
, completeWild
->node
,
13788 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE
,
13789 "The union of the wildcard is not expressible.\n",
13791 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE
);
13792 } else if ((!nsFound
) && (!absentFound
)) {
13794 * 5.4 If the set S does not include either the negated namespace
13795 * name or `absent`, then whichever of O1 or O2 is a pair of not
13796 * and a namespace name must be the value.
13798 if (completeWild
->negNsSet
== NULL
) {
13799 if (completeWild
->nsSet
!= NULL
) {
13800 xmlSchemaFreeWildcardNsSet(completeWild
->nsSet
);
13801 completeWild
->nsSet
= NULL
;
13803 completeWild
->negNsSet
= xmlSchemaNewWildcardNsConstraint(ctxt
);
13804 if (completeWild
->negNsSet
== NULL
)
13806 completeWild
->negNsSet
->value
= curWild
->negNsSet
->value
;
13814 if (((completeWild
->negNsSet
!= NULL
) &&
13815 (completeWild
->negNsSet
->value
== NULL
) &&
13816 (curWild
->nsSet
!= NULL
)) ||
13817 ((curWild
->negNsSet
!= NULL
) &&
13818 (curWild
->negNsSet
->value
== NULL
) &&
13819 (completeWild
->nsSet
!= NULL
))) {
13821 if (completeWild
->nsSet
!= NULL
) {
13822 cur
= completeWild
->nsSet
;
13824 cur
= curWild
->nsSet
;
13826 while (cur
!= NULL
) {
13827 if (cur
->value
== NULL
) {
13829 * 6.1 If the set S includes `absent`, then any must be the
13832 completeWild
->any
= 1;
13833 if (completeWild
->nsSet
!= NULL
) {
13834 xmlSchemaFreeWildcardNsSet(completeWild
->nsSet
);
13835 completeWild
->nsSet
= NULL
;
13837 if (completeWild
->negNsSet
!= NULL
) {
13838 xmlFree(completeWild
->negNsSet
);
13839 completeWild
->negNsSet
= NULL
;
13845 if (completeWild
->negNsSet
== NULL
) {
13847 * 6.2 If the set S does not include `absent`, then a pair of not
13848 * and `absent` must be the value.
13850 if (completeWild
->nsSet
!= NULL
) {
13851 xmlSchemaFreeWildcardNsSet(completeWild
->nsSet
);
13852 completeWild
->nsSet
= NULL
;
13854 completeWild
->negNsSet
= xmlSchemaNewWildcardNsConstraint(ctxt
);
13855 if (completeWild
->negNsSet
== NULL
)
13857 completeWild
->negNsSet
->value
= NULL
;
13866 * xmlSchemaIntersectWildcards:
13867 * @ctxt: the schema parser context
13868 * @completeWild: the first wildcard
13869 * @curWild: the second wildcard
13871 * Intersects the namespace constraints of the given wildcards.
13872 * @completeWild will hold the resulting intersection.
13873 * Returns a positive error code on failure, -1 in case of an
13874 * internal error, 0 otherwise.
13877 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt
,
13878 xmlSchemaWildcardPtr completeWild
,
13879 xmlSchemaWildcardPtr curWild
)
13881 xmlSchemaWildcardNsPtr cur
, curB
, prev
, tmp
;
13884 * 1 If O1 and O2 are the same value, then that value must be the
13887 if ((completeWild
->any
== curWild
->any
) &&
13888 ((completeWild
->nsSet
== NULL
) == (curWild
->nsSet
== NULL
)) &&
13889 ((completeWild
->negNsSet
== NULL
) == (curWild
->negNsSet
== NULL
))) {
13891 if ((completeWild
->negNsSet
== NULL
) ||
13892 (completeWild
->negNsSet
->value
== curWild
->negNsSet
->value
)) {
13894 if (completeWild
->nsSet
!= NULL
) {
13898 * Check equality of sets.
13900 cur
= completeWild
->nsSet
;
13901 while (cur
!= NULL
) {
13903 curB
= curWild
->nsSet
;
13904 while (curB
!= NULL
) {
13905 if (cur
->value
== curB
->value
) {
13922 * 2 If either O1 or O2 is any, then the other must be the value.
13924 if ((completeWild
->any
!= curWild
->any
) && (completeWild
->any
)) {
13925 if (xmlSchemaCloneWildcardNsConstraints(ctxt
, completeWild
, curWild
) == -1)
13930 * 3 If either O1 or O2 is a pair of not and a value (a namespace
13931 * name or `absent`) and the other is a set of (namespace names or
13932 * `absent`), then that set, minus the negated value if it was in
13933 * the set, minus `absent` if it was in the set, must be the value.
13935 if (((completeWild
->negNsSet
!= NULL
) && (curWild
->nsSet
!= NULL
)) ||
13936 ((curWild
->negNsSet
!= NULL
) && (completeWild
->nsSet
!= NULL
))) {
13937 const xmlChar
*neg
;
13939 if (completeWild
->nsSet
== NULL
) {
13940 neg
= completeWild
->negNsSet
->value
;
13941 if (xmlSchemaCloneWildcardNsConstraints(ctxt
, completeWild
, curWild
) == -1)
13944 neg
= curWild
->negNsSet
->value
;
13946 * Remove absent and negated.
13949 cur
= completeWild
->nsSet
;
13950 while (cur
!= NULL
) {
13951 if (cur
->value
== NULL
) {
13953 completeWild
->nsSet
= cur
->next
;
13955 prev
->next
= cur
->next
;
13964 cur
= completeWild
->nsSet
;
13965 while (cur
!= NULL
) {
13966 if (cur
->value
== neg
) {
13968 completeWild
->nsSet
= cur
->next
;
13970 prev
->next
= cur
->next
;
13982 * 4 If both O1 and O2 are sets of (namespace names or `absent`),
13983 * then the intersection of those sets must be the value.
13985 if ((completeWild
->nsSet
!= NULL
) && (curWild
->nsSet
!= NULL
)) {
13988 cur
= completeWild
->nsSet
;
13990 while (cur
!= NULL
) {
13992 curB
= curWild
->nsSet
;
13993 while (curB
!= NULL
) {
13994 if (cur
->value
== curB
->value
) {
14002 completeWild
->nsSet
= cur
->next
;
14004 prev
->next
= cur
->next
;
14016 /* 5 If the two are negations of different namespace names,
14017 * then the intersection is not expressible
14019 if ((completeWild
->negNsSet
!= NULL
) &&
14020 (curWild
->negNsSet
!= NULL
) &&
14021 (completeWild
->negNsSet
->value
!= curWild
->negNsSet
->value
) &&
14022 (completeWild
->negNsSet
->value
!= NULL
) &&
14023 (curWild
->negNsSet
->value
!= NULL
)) {
14025 xmlSchemaPErr(ctxt
, completeWild
->node
, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE
,
14026 "The intersection of the wildcard is not expressible.\n",
14028 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE
);
14031 * 6 If the one is a negation of a namespace name and the other
14032 * is a negation of `absent`, then the one which is the negation
14033 * of a namespace name must be the value.
14035 if ((completeWild
->negNsSet
!= NULL
) && (curWild
->negNsSet
!= NULL
) &&
14036 (completeWild
->negNsSet
->value
!= curWild
->negNsSet
->value
) &&
14037 (completeWild
->negNsSet
->value
== NULL
)) {
14038 completeWild
->negNsSet
->value
= curWild
->negNsSet
->value
;
14044 * xmlSchemaIsWildcardNsConstraintSubset:
14045 * @ctxt: the schema parser context
14046 * @sub: the first wildcard
14047 * @super: the second wildcard
14049 * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
14051 * Returns 0 if the namespace constraint of @sub is an intensional
14052 * subset of @super, 1 otherwise.
14055 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub
,
14056 xmlSchemaWildcardPtr super
)
14059 * 1 super must be any.
14064 * 2.1 sub must be a pair of not and a namespace name or `absent`.
14065 * 2.2 super must be a pair of not and the same value.
14067 if ((sub
->negNsSet
!= NULL
) &&
14068 (super
->negNsSet
!= NULL
) &&
14069 (sub
->negNsSet
->value
== super
->negNsSet
->value
))
14072 * 3.1 sub must be a set whose members are either namespace names or `absent`.
14074 if (sub
->nsSet
!= NULL
) {
14076 * 3.2.1 super must be the same set or a superset thereof.
14078 if (super
->nsSet
!= NULL
) {
14079 xmlSchemaWildcardNsPtr cur
, curB
;
14083 while (cur
!= NULL
) {
14085 curB
= super
->nsSet
;
14086 while (curB
!= NULL
) {
14087 if (cur
->value
== curB
->value
) {
14099 } else if (super
->negNsSet
!= NULL
) {
14100 xmlSchemaWildcardNsPtr cur
;
14102 * 3.2.2 super must be a pair of not and a namespace name or
14103 * `absent` and that value must not be in sub's set.
14106 while (cur
!= NULL
) {
14107 if (cur
->value
== super
->negNsSet
->value
)
14118 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse
,
14120 const xmlChar
**value
,
14121 xmlSchemaValPtr
*val
)
14128 if (attruse
->defValue
!= NULL
) {
14129 *value
= attruse
->defValue
;
14131 *val
= attruse
->defVal
;
14132 if (attruse
->flags
& XML_SCHEMA_ATTR_USE_FIXED
)
14135 } else if ((attruse
->attrDecl
!= NULL
) &&
14136 (attruse
->attrDecl
->defValue
!= NULL
)) {
14137 *value
= attruse
->attrDecl
->defValue
;
14139 *val
= attruse
->attrDecl
->defVal
;
14140 if (attruse
->attrDecl
->flags
& XML_SCHEMAS_ATTR_FIXED
)
14147 * xmlSchemaCheckCVCWildcardNamespace:
14148 * @wild: the wildcard
14149 * @ns: the namespace
14151 * Validation Rule: Wildcard allows Namespace Name
14152 * (cvc-wildcard-namespace)
14154 * Returns 0 if the given namespace matches the wildcard,
14155 * 1 otherwise and -1 on API errors.
14158 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild
,
14166 else if (wild
->nsSet
!= NULL
) {
14167 xmlSchemaWildcardNsPtr cur
;
14170 while (cur
!= NULL
) {
14171 if (xmlStrEqual(cur
->value
, ns
))
14175 } else if ((wild
->negNsSet
!= NULL
) && (ns
!= NULL
) &&
14176 (!xmlStrEqual(wild
->negNsSet
->value
, ns
)))
14182 #define XML_SCHEMA_ACTION_DERIVE 0
14183 #define XML_SCHEMA_ACTION_REDEFINE 1
14185 #define WXS_ACTION_STR(a) \
14186 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14189 * Schema Component Constraint:
14190 * Derivation Valid (Restriction, Complex)
14191 * derivation-ok-restriction (2) - (4)
14194 * In XML Schema 1.1 this will be:
14196 * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14200 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt
,
14202 xmlSchemaBasicItemPtr item
,
14203 xmlSchemaBasicItemPtr baseItem
,
14204 xmlSchemaItemListPtr uses
,
14205 xmlSchemaItemListPtr baseUses
,
14206 xmlSchemaWildcardPtr wild
,
14207 xmlSchemaWildcardPtr baseWild
)
14209 xmlSchemaAttributeUsePtr cur
= NULL
, bcur
;
14210 int i
, j
, found
; /* err = 0; */
14211 const xmlChar
*bEffValue
;
14214 if (uses
!= NULL
) {
14215 for (i
= 0; i
< uses
->nbItems
; i
++) {
14216 cur
= uses
->items
[i
];
14218 if (baseUses
== NULL
)
14220 for (j
= 0; j
< baseUses
->nbItems
; j
++) {
14221 bcur
= baseUses
->items
[j
];
14222 if ((WXS_ATTRUSE_DECL_NAME(cur
) ==
14223 WXS_ATTRUSE_DECL_NAME(bcur
)) &&
14224 (WXS_ATTRUSE_DECL_TNS(cur
) ==
14225 WXS_ATTRUSE_DECL_TNS(bcur
)))
14228 * (2.1) "If there is an attribute use in the {attribute
14229 * uses} of the {base type definition} (call this B) whose
14230 * {attribute declaration} has the same {name} and {target
14231 * namespace}, then all of the following must be true:"
14235 if ((cur
->occurs
== XML_SCHEMAS_ATTR_USE_OPTIONAL
) &&
14236 (bcur
->occurs
== XML_SCHEMAS_ATTR_USE_REQUIRED
))
14238 xmlChar
*str
= NULL
;
14240 * (2.1.1) "one of the following must be true:"
14241 * (2.1.1.1) "B's {required} is false."
14242 * (2.1.1.2) "R's {required} is true."
14244 xmlSchemaPAttrUseErr4(pctxt
,
14245 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1
,
14246 WXS_ITEM_NODE(item
), item
, cur
,
14247 "The 'optional' attribute use is inconsistent "
14248 "with the corresponding 'required' attribute use of "
14250 WXS_ACTION_STR(action
),
14251 xmlSchemaGetComponentDesignation(&str
, baseItem
),
14253 FREE_AND_NULL(str
);
14254 /* err = pctxt->err; */
14255 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt
,
14256 WXS_ATTRUSE_TYPEDEF(cur
),
14257 WXS_ATTRUSE_TYPEDEF(bcur
), 0) != 0)
14259 xmlChar
*strA
= NULL
, *strB
= NULL
, *strC
= NULL
;
14262 * SPEC (2.1.2) "R's {attribute declaration}'s
14263 * {type definition} must be validly derived from
14264 * B's {type definition} given the empty set as
14265 * defined in Type Derivation OK (Simple) ($3.14.6)."
14267 xmlSchemaPAttrUseErr4(pctxt
,
14268 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2
,
14269 WXS_ITEM_NODE(item
), item
, cur
,
14270 "The attribute declaration's %s "
14271 "is not validly derived from "
14272 "the corresponding %s of the "
14273 "attribute declaration in the %s %s",
14274 xmlSchemaGetComponentDesignation(&strA
,
14275 WXS_ATTRUSE_TYPEDEF(cur
)),
14276 xmlSchemaGetComponentDesignation(&strB
,
14277 WXS_ATTRUSE_TYPEDEF(bcur
)),
14278 WXS_ACTION_STR(action
),
14279 xmlSchemaGetComponentDesignation(&strC
, baseItem
));
14280 /* xmlSchemaGetComponentDesignation(&str, baseItem), */
14281 FREE_AND_NULL(strA
);
14282 FREE_AND_NULL(strB
);
14283 FREE_AND_NULL(strC
);
14284 /* err = pctxt->err; */
14287 * 2.1.3 [Definition:] Let the effective value
14288 * constraint of an attribute use be its {value
14289 * constraint}, if present, otherwise its {attribute
14290 * declaration}'s {value constraint} .
14292 xmlSchemaGetEffectiveValueConstraint(bcur
,
14293 &effFixed
, &bEffValue
, NULL
);
14295 * 2.1.3 ... one of the following must be true
14297 * 2.1.3.1 B's `effective value constraint` is
14298 * `absent` or default.
14300 if ((bEffValue
!= NULL
) &&
14302 const xmlChar
*rEffValue
= NULL
;
14304 xmlSchemaGetEffectiveValueConstraint(bcur
,
14305 &effFixed
, &rEffValue
, NULL
);
14307 * 2.1.3.2 R's `effective value constraint` is
14308 * fixed with the same string as B's.
14309 * MAYBE TODO: Compare the computed values.
14310 * Hmm, it says "same string" so
14311 * string-equality might really be sufficient.
14313 if ((effFixed
== 0) ||
14314 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue
, bEffValue
)))
14316 xmlChar
*str
= NULL
;
14318 xmlSchemaPAttrUseErr4(pctxt
,
14319 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3
,
14320 WXS_ITEM_NODE(item
), item
, cur
,
14321 "The effective value constraint of the "
14322 "attribute use is inconsistent with "
14323 "its correspondent in the %s %s",
14324 WXS_ACTION_STR(action
),
14325 xmlSchemaGetComponentDesignation(&str
,
14328 FREE_AND_NULL(str
);
14329 /* err = pctxt->err; */
14339 * (2.2) "otherwise the {base type definition} must have an
14340 * {attribute wildcard} and the {target namespace} of the
14341 * R's {attribute declaration} must be `valid` with respect
14342 * to that wildcard, as defined in Wildcard allows Namespace
14345 if ((baseWild
== NULL
) ||
14346 (xmlSchemaCheckCVCWildcardNamespace(baseWild
,
14347 (WXS_ATTRUSE_DECL(cur
))->targetNamespace
) != 0))
14349 xmlChar
*str
= NULL
;
14351 xmlSchemaPAttrUseErr4(pctxt
,
14352 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2
,
14353 WXS_ITEM_NODE(item
), item
, cur
,
14354 "Neither a matching attribute use, "
14355 "nor a matching wildcard exists in the %s %s",
14356 WXS_ACTION_STR(action
),
14357 xmlSchemaGetComponentDesignation(&str
, baseItem
),
14359 FREE_AND_NULL(str
);
14360 /* err = pctxt->err; */
14366 * SPEC derivation-ok-restriction (3):
14367 * (3) "For each attribute use in the {attribute uses} of the {base type
14368 * definition} whose {required} is true, there must be an attribute
14369 * use with an {attribute declaration} with the same {name} and
14370 * {target namespace} as its {attribute declaration} in the {attribute
14371 * uses} of the complex type definition itself whose {required} is true.
14373 if (baseUses
!= NULL
) {
14374 for (j
= 0; j
< baseUses
->nbItems
; j
++) {
14375 bcur
= baseUses
->items
[j
];
14376 if (bcur
->occurs
!= XML_SCHEMAS_ATTR_USE_REQUIRED
)
14379 if (uses
!= NULL
) {
14380 for (i
= 0; i
< uses
->nbItems
; i
++) {
14381 cur
= uses
->items
[i
];
14382 if ((WXS_ATTRUSE_DECL_NAME(cur
) ==
14383 WXS_ATTRUSE_DECL_NAME(bcur
)) &&
14384 (WXS_ATTRUSE_DECL_TNS(cur
) ==
14385 WXS_ATTRUSE_DECL_TNS(bcur
))) {
14392 xmlChar
*strA
= NULL
, *strB
= NULL
;
14394 xmlSchemaCustomErr4(ACTXT_CAST pctxt
,
14395 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3
,
14397 "A matching attribute use for the "
14398 "'required' %s of the %s %s is missing",
14399 xmlSchemaGetComponentDesignation(&strA
, bcur
),
14400 WXS_ACTION_STR(action
),
14401 xmlSchemaGetComponentDesignation(&strB
, baseItem
),
14403 FREE_AND_NULL(strA
);
14404 FREE_AND_NULL(strB
);
14409 * derivation-ok-restriction (4)
14411 if (wild
!= NULL
) {
14413 * (4) "If there is an {attribute wildcard}, all of the
14414 * following must be true:"
14416 if (baseWild
== NULL
) {
14417 xmlChar
*str
= NULL
;
14420 * (4.1) "The {base type definition} must also have one."
14422 xmlSchemaCustomErr4(ACTXT_CAST pctxt
,
14423 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1
,
14425 "The %s has an attribute wildcard, "
14426 "but the %s %s '%s' does not have one",
14427 WXS_ITEM_TYPE_NAME(item
),
14428 WXS_ACTION_STR(action
),
14429 WXS_ITEM_TYPE_NAME(baseItem
),
14430 xmlSchemaGetComponentQName(&str
, baseItem
));
14431 FREE_AND_NULL(str
);
14432 return(pctxt
->err
);
14433 } else if ((baseWild
->any
== 0) &&
14434 xmlSchemaCheckCOSNSSubset(wild
, baseWild
))
14436 xmlChar
*str
= NULL
;
14438 * (4.2) "The complex type definition's {attribute wildcard}'s
14439 * {namespace constraint} must be a subset of the {base type
14440 * definition}'s {attribute wildcard}'s {namespace constraint},
14441 * as defined by Wildcard Subset ($3.10.6)."
14443 xmlSchemaCustomErr4(ACTXT_CAST pctxt
,
14444 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2
,
14446 "The attribute wildcard is not a valid "
14447 "subset of the wildcard in the %s %s '%s'",
14448 WXS_ACTION_STR(action
),
14449 WXS_ITEM_TYPE_NAME(baseItem
),
14450 xmlSchemaGetComponentQName(&str
, baseItem
),
14452 FREE_AND_NULL(str
);
14453 return(pctxt
->err
);
14455 /* 4.3 Unless the {base type definition} is the `ur-type
14456 * definition`, the complex type definition's {attribute
14457 * wildcard}'s {process contents} must be identical to or
14458 * stronger than the {base type definition}'s {attribute
14459 * wildcard}'s {process contents}, where strict is stronger
14460 * than lax is stronger than skip.
14462 if ((! WXS_IS_ANYTYPE(baseItem
)) &&
14463 (wild
->processContents
< baseWild
->processContents
)) {
14464 xmlChar
*str
= NULL
;
14465 xmlSchemaCustomErr4(ACTXT_CAST pctxt
,
14466 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3
,
14468 "The {process contents} of the attribute wildcard is "
14469 "weaker than the one in the %s %s '%s'",
14470 WXS_ACTION_STR(action
),
14471 WXS_ITEM_TYPE_NAME(baseItem
),
14472 xmlSchemaGetComponentQName(&str
, baseItem
),
14475 return(pctxt
->err
);
14483 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt
,
14484 xmlSchemaBasicItemPtr item
,
14485 xmlSchemaWildcardPtr
*completeWild
,
14486 xmlSchemaItemListPtr list
,
14487 xmlSchemaItemListPtr prohibs
);
14489 * xmlSchemaFixupTypeAttributeUses:
14490 * @ctxt: the schema parser context
14491 * @type: the complex type definition
14494 * Builds the wildcard and the attribute uses on the given complex type.
14495 * Returns -1 if an internal error occurs, 0 otherwise.
14497 * ATTENTION TODO: Experimentally this uses pointer comparisons for
14498 * strings, so recheck this if we start to hardcode some schemata, since
14499 * they might not be in the same dict.
14500 * NOTE: It is allowed to "extend" the xs:anyType type.
14503 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt
,
14504 xmlSchemaTypePtr type
)
14506 xmlSchemaTypePtr baseType
= NULL
;
14507 xmlSchemaAttributeUsePtr use
;
14508 xmlSchemaItemListPtr uses
, baseUses
, prohibs
= NULL
;
14510 if (type
->baseType
== NULL
) {
14511 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14515 baseType
= type
->baseType
;
14516 if (WXS_IS_TYPE_NOT_FIXED(baseType
))
14517 if (xmlSchemaTypeFixup(baseType
, ACTXT_CAST pctxt
) == -1)
14520 uses
= type
->attrUses
;
14521 baseUses
= baseType
->attrUses
;
14523 * Expand attribute group references. And build the 'complete'
14524 * wildcard, i.e. intersect multiple wildcards.
14525 * Move attribute prohibitions into a separate list.
14527 if (uses
!= NULL
) {
14528 if (WXS_IS_RESTRICTION(type
)) {
14530 * This one will transfer all attr. prohibitions
14531 * into pctxt->attrProhibs.
14533 if (xmlSchemaExpandAttributeGroupRefs(pctxt
,
14534 WXS_BASIC_CAST type
, &(type
->attributeWildcard
), uses
,
14535 pctxt
->attrProhibs
) == -1)
14537 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14538 "failed to expand attributes");
14540 if (pctxt
->attrProhibs
->nbItems
!= 0)
14541 prohibs
= pctxt
->attrProhibs
;
14543 if (xmlSchemaExpandAttributeGroupRefs(pctxt
,
14544 WXS_BASIC_CAST type
, &(type
->attributeWildcard
), uses
,
14547 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14548 "failed to expand attributes");
14553 * Inherit the attribute uses of the base type.
14555 if (baseUses
!= NULL
) {
14557 xmlSchemaAttributeUseProhibPtr pro
;
14559 if (WXS_IS_RESTRICTION(type
)) {
14561 xmlSchemaAttributeUsePtr tmp
;
14564 usesCount
= uses
->nbItems
;
14569 for (i
= 0; i
< baseUses
->nbItems
; i
++) {
14570 use
= baseUses
->items
[i
];
14573 * Filter out prohibited uses.
14575 for (j
= 0; j
< prohibs
->nbItems
; j
++) {
14576 pro
= prohibs
->items
[j
];
14577 if ((WXS_ATTRUSE_DECL_NAME(use
) == pro
->name
) &&
14578 (WXS_ATTRUSE_DECL_TNS(use
) ==
14579 pro
->targetNamespace
))
14587 * Filter out existing uses.
14589 for (j
= 0; j
< usesCount
; j
++) {
14590 tmp
= uses
->items
[j
];
14591 if ((WXS_ATTRUSE_DECL_NAME(use
) ==
14592 WXS_ATTRUSE_DECL_NAME(tmp
)) &&
14593 (WXS_ATTRUSE_DECL_TNS(use
) ==
14594 WXS_ATTRUSE_DECL_TNS(tmp
)))
14600 if (uses
== NULL
) {
14601 type
->attrUses
= xmlSchemaItemListCreate();
14602 if (type
->attrUses
== NULL
)
14604 uses
= type
->attrUses
;
14606 xmlSchemaItemListAddSize(uses
, 2, use
);
14611 for (i
= 0; i
< baseUses
->nbItems
; i
++) {
14612 use
= baseUses
->items
[i
];
14613 if (uses
== NULL
) {
14614 type
->attrUses
= xmlSchemaItemListCreate();
14615 if (type
->attrUses
== NULL
)
14617 uses
= type
->attrUses
;
14619 xmlSchemaItemListAddSize(uses
, baseUses
->nbItems
, use
);
14624 * Shrink attr. uses.
14627 if (uses
->nbItems
== 0) {
14628 xmlSchemaItemListFree(uses
);
14629 type
->attrUses
= NULL
;
14632 * TODO: We could shrink the size of the array
14633 * to fit the actual number of items.
14637 * Compute the complete wildcard.
14639 if (WXS_IS_EXTENSION(type
)) {
14640 if (baseType
->attributeWildcard
!= NULL
) {
14642 * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
14643 * the appropriate case among the following:"
14645 if (type
->attributeWildcard
!= NULL
) {
14647 * Union the complete wildcard with the base wildcard.
14648 * SPEC {attribute wildcard}
14649 * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14650 * and {annotation} are those of the `complete wildcard`,
14651 * and whose {namespace constraint} is the intensional union
14652 * of the {namespace constraint} of the `complete wildcard`
14653 * and of the `base wildcard`, as defined in Attribute
14654 * Wildcard Union ($3.10.6)."
14656 if (xmlSchemaUnionWildcards(pctxt
, type
->attributeWildcard
,
14657 baseType
->attributeWildcard
) == -1)
14661 * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
14662 * then the `base wildcard`."
14664 type
->attributeWildcard
= baseType
->attributeWildcard
;
14668 * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
14669 * `complete wildcard`"
14675 * SPEC {attribute wildcard}
14676 * (3.1) "If the <restriction> alternative is chosen, then the
14677 * `complete wildcard`;"
14689 * xmlSchemaTypeFinalContains:
14690 * @schema: the schema
14691 * @type: the type definition
14692 * @final: the final
14694 * Evaluates if a type definition contains the given "final".
14695 * This does take "finalDefault" into account as well.
14697 * Returns 1 if the type does contain the given "final",
14701 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type
, int final
)
14705 if (type
->flags
& final
)
14712 * xmlSchemaGetUnionSimpleTypeMemberTypes:
14713 * @type: the Union Simple Type
14715 * Returns a list of member types of @type if existing,
14716 * returns NULL otherwise.
14718 static xmlSchemaTypeLinkPtr
14719 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type
)
14721 while ((type
!= NULL
) && (type
->type
== XML_SCHEMA_TYPE_SIMPLE
)) {
14722 if (type
->memberTypes
!= NULL
)
14723 return (type
->memberTypes
);
14725 type
= type
->baseType
;
14732 * xmlSchemaGetParticleTotalRangeMin:
14733 * @particle: the particle
14735 * Schema Component Constraint: Effective Total Range
14736 * (all and sequence) + (choice)
14738 * Returns the minimum Effective Total Range.
14741 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle
)
14743 if ((particle
->children
== NULL
) ||
14744 (particle
->minOccurs
== 0))
14746 if (particle
->children
->type
== XML_SCHEMA_TYPE_CHOICE
) {
14748 xmlSchemaParticlePtr part
=
14749 (xmlSchemaParticlePtr
) particle
->children
->children
;
14753 while (part
!= NULL
) {
14754 if ((part
->children
->type
== XML_SCHEMA_TYPE_ELEMENT
) ||
14755 (part
->children
->type
== XML_SCHEMA_TYPE_ANY
))
14756 cur
= part
->minOccurs
;
14758 cur
= xmlSchemaGetParticleTotalRangeMin(part
);
14761 if ((min
> cur
) || (min
== -1))
14763 part
= (xmlSchemaParticlePtr
) part
->next
;
14765 return (particle
->minOccurs
* min
);
14767 /* <all> and <sequence> */
14769 xmlSchemaParticlePtr part
=
14770 (xmlSchemaParticlePtr
) particle
->children
->children
;
14775 if ((part
->children
->type
== XML_SCHEMA_TYPE_ELEMENT
) ||
14776 (part
->children
->type
== XML_SCHEMA_TYPE_ANY
))
14777 sum
+= part
->minOccurs
;
14779 sum
+= xmlSchemaGetParticleTotalRangeMin(part
);
14780 part
= (xmlSchemaParticlePtr
) part
->next
;
14781 } while (part
!= NULL
);
14782 return (particle
->minOccurs
* sum
);
14787 * xmlSchemaGetParticleTotalRangeMax:
14788 * @particle: the particle
14790 * Schema Component Constraint: Effective Total Range
14791 * (all and sequence) + (choice)
14793 * Returns the maximum Effective Total Range.
14796 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle
)
14798 if ((particle
->children
== NULL
) ||
14799 (particle
->children
->children
== NULL
))
14801 if (particle
->children
->type
== XML_SCHEMA_TYPE_CHOICE
) {
14803 xmlSchemaParticlePtr part
=
14804 (xmlSchemaParticlePtr
) particle
->children
->children
;
14806 for (; part
!= NULL
; part
= (xmlSchemaParticlePtr
) part
->next
) {
14807 if (part
->children
== NULL
)
14809 if ((part
->children
->type
== XML_SCHEMA_TYPE_ELEMENT
) ||
14810 (part
->children
->type
== XML_SCHEMA_TYPE_ANY
))
14811 cur
= part
->maxOccurs
;
14813 cur
= xmlSchemaGetParticleTotalRangeMax(part
);
14814 if (cur
== UNBOUNDED
)
14815 return (UNBOUNDED
);
14816 if ((max
< cur
) || (max
== -1))
14819 /* TODO: Handle overflows? */
14820 return (particle
->maxOccurs
* max
);
14822 /* <all> and <sequence> */
14824 xmlSchemaParticlePtr part
=
14825 (xmlSchemaParticlePtr
) particle
->children
->children
;
14827 for (; part
!= NULL
; part
= (xmlSchemaParticlePtr
) part
->next
) {
14828 if (part
->children
== NULL
)
14830 if ((part
->children
->type
== XML_SCHEMA_TYPE_ELEMENT
) ||
14831 (part
->children
->type
== XML_SCHEMA_TYPE_ANY
))
14832 cur
= part
->maxOccurs
;
14834 cur
= xmlSchemaGetParticleTotalRangeMax(part
);
14835 if (cur
== UNBOUNDED
)
14836 return (UNBOUNDED
);
14837 if ((cur
> 0) && (particle
->maxOccurs
== UNBOUNDED
))
14838 return (UNBOUNDED
);
14841 /* TODO: Handle overflows? */
14842 return (particle
->maxOccurs
* sum
);
14848 * xmlSchemaGetParticleEmptiable:
14849 * @particle: the particle
14851 * Returns 1 if emptiable, 0 otherwise.
14854 xmlSchemaGetParticleEmptiable(xmlSchemaParticlePtr particle
)
14856 xmlSchemaParticlePtr part
;
14859 if ((particle
->children
== NULL
) || (particle
->minOccurs
== 0))
14862 part
= (xmlSchemaParticlePtr
) particle
->children
->children
;
14866 while (part
!= NULL
) {
14867 if ((part
->children
->type
== XML_SCHEMA_TYPE_ELEMENT
) ||
14868 (part
->children
->type
== XML_SCHEMA_TYPE_ANY
))
14869 emptiable
= (part
->minOccurs
== 0);
14871 emptiable
= xmlSchemaGetParticleEmptiable(part
);
14872 if (particle
->children
->type
== XML_SCHEMA_TYPE_CHOICE
) {
14876 /* <all> and <sequence> */
14880 part
= (xmlSchemaParticlePtr
) part
->next
;
14883 if (particle
->children
->type
== XML_SCHEMA_TYPE_CHOICE
)
14890 * xmlSchemaIsParticleEmptiable:
14891 * @particle: the particle
14893 * Schema Component Constraint: Particle Emptiable
14894 * Checks whether the given particle is emptiable.
14896 * Returns 1 if emptiable, 0 otherwise.
14899 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle
)
14902 * SPEC (1) "Its {min occurs} is 0."
14904 if ((particle
== NULL
) || (particle
->minOccurs
== 0) ||
14905 (particle
->children
== NULL
))
14908 * SPEC (2) "Its {term} is a group and the minimum part of the
14909 * effective total range of that group, [...] is 0."
14911 if (WXS_IS_MODEL_GROUP(particle
->children
))
14912 return (xmlSchemaGetParticleEmptiable(particle
));
14917 * xmlSchemaCheckCOSSTDerivedOK:
14918 * @actxt: a context
14919 * @type: the derived simple type definition
14920 * @baseType: the base type definition
14921 * @subset: the subset of ('restriction', etc.)
14923 * Schema Component Constraint:
14924 * Type Derivation OK (Simple) (cos-st-derived-OK)
14926 * Checks whether @type can be validly
14927 * derived from @baseType.
14929 * Returns 0 on success, an positive error code otherwise.
14932 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt
,
14933 xmlSchemaTypePtr type
,
14934 xmlSchemaTypePtr baseType
,
14938 * 1 They are the same type definition.
14939 * TODO: The identity check might have to be more complex than this.
14941 if (type
== baseType
)
14944 * 2.1 restriction is not in the subset, or in the {final}
14945 * of its own {base type definition};
14947 * NOTE that this will be used also via "xsi:type".
14949 * TODO: Revise this, it looks strange. How can the "type"
14950 * not be fixed or *in* fixing?
14952 if (WXS_IS_TYPE_NOT_FIXED(type
))
14953 if (xmlSchemaTypeFixup(type
, actxt
) == -1)
14955 if (WXS_IS_TYPE_NOT_FIXED(baseType
))
14956 if (xmlSchemaTypeFixup(baseType
, actxt
) == -1)
14958 if ((subset
& SUBSET_RESTRICTION
) ||
14959 (xmlSchemaTypeFinalContains(type
->baseType
,
14960 XML_SCHEMAS_TYPE_FINAL_RESTRICTION
))) {
14961 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1
);
14964 if (type
->baseType
== baseType
) {
14966 * 2.2.1 D's `base type definition` is B.
14971 * 2.2.2 D's `base type definition` is not the `ur-type definition`
14972 * and is validly derived from B given the subset, as defined by this
14975 if ((! WXS_IS_ANYTYPE(type
->baseType
)) &&
14976 (xmlSchemaCheckCOSSTDerivedOK(actxt
, type
->baseType
,
14977 baseType
, subset
) == 0)) {
14981 * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
14984 if (WXS_IS_ANY_SIMPLE_TYPE(baseType
) &&
14985 (WXS_IS_LIST(type
) || WXS_IS_UNION(type
))) {
14989 * 2.2.4 B's {variety} is union and D is validly derived from a type
14990 * definition in B's {member type definitions} given the subset, as
14991 * defined by this constraint.
14993 * NOTE: This seems not to involve built-in types, since there is no
14994 * built-in Union Simple Type.
14996 if (WXS_IS_UNION(baseType
)) {
14997 xmlSchemaTypeLinkPtr cur
;
14999 cur
= baseType
->memberTypes
;
15000 while (cur
!= NULL
) {
15001 if (WXS_IS_TYPE_NOT_FIXED(cur
->type
))
15002 if (xmlSchemaTypeFixup(cur
->type
, actxt
) == -1)
15004 if (xmlSchemaCheckCOSSTDerivedOK(actxt
,
15005 type
, cur
->type
, subset
) == 0)
15008 * It just has to be validly derived from at least one
15016 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2
);
15020 * xmlSchemaCheckTypeDefCircularInternal:
15021 * @pctxt: the schema parser context
15022 * @ctxtType: the type definition
15023 * @ancestor: an ancestor of @ctxtType
15025 * Checks st-props-correct (2) + ct-props-correct (3).
15026 * Circular type definitions are not allowed.
15028 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
15029 * circular, 0 otherwise.
15032 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt
,
15033 xmlSchemaTypePtr ctxtType
,
15034 xmlSchemaTypePtr ancestor
)
15038 if ((ancestor
== NULL
) || (ancestor
->type
== XML_SCHEMA_TYPE_BASIC
))
15041 if (ctxtType
== ancestor
) {
15042 xmlSchemaPCustomErr(pctxt
,
15043 XML_SCHEMAP_ST_PROPS_CORRECT_2
,
15044 WXS_BASIC_CAST ctxtType
, WXS_ITEM_NODE(ctxtType
),
15045 "The definition is circular", NULL
);
15046 return (XML_SCHEMAP_ST_PROPS_CORRECT_2
);
15048 if (ancestor
->flags
& XML_SCHEMAS_TYPE_MARKED
) {
15050 * Avoid infinite recursion on circular types not yet checked.
15054 ancestor
->flags
|= XML_SCHEMAS_TYPE_MARKED
;
15055 ret
= xmlSchemaCheckTypeDefCircularInternal(pctxt
, ctxtType
,
15056 ancestor
->baseType
);
15057 ancestor
->flags
^= XML_SCHEMAS_TYPE_MARKED
;
15062 * xmlSchemaCheckTypeDefCircular:
15063 * @item: the complex/simple type definition
15064 * @ctxt: the parser context
15067 * Checks for circular type definitions.
15070 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item
,
15071 xmlSchemaParserCtxtPtr ctxt
)
15073 if ((item
== NULL
) ||
15074 (item
->type
== XML_SCHEMA_TYPE_BASIC
) ||
15075 (item
->baseType
== NULL
))
15077 xmlSchemaCheckTypeDefCircularInternal(ctxt
, item
,
15082 * Simple Type Definition Representation OK (src-simple-type) 4
15084 * "4 Circular union type definition is disallowed. That is, if the
15085 * <union> alternative is chosen, there must not be any entries in the
15086 * memberTypes [attribute] at any depth which resolve to the component
15087 * corresponding to the <simpleType>."
15089 * Note that this should work on the *representation* of a component,
15090 * thus assumes any union types in the member types not being yet
15091 * substituted. At this stage we need the variety of the types
15092 * to be already computed.
15095 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt
,
15096 xmlSchemaTypePtr ctxType
,
15097 xmlSchemaTypeLinkPtr members
)
15099 xmlSchemaTypeLinkPtr member
;
15100 xmlSchemaTypePtr memberType
;
15103 while (member
!= NULL
) {
15104 memberType
= member
->type
;
15105 while ((memberType
!= NULL
) &&
15106 (memberType
->type
!= XML_SCHEMA_TYPE_BASIC
)) {
15107 if (memberType
== ctxType
) {
15108 xmlSchemaPCustomErr(pctxt
,
15109 XML_SCHEMAP_SRC_SIMPLE_TYPE_4
,
15110 WXS_BASIC_CAST ctxType
, NULL
,
15111 "The union type definition is circular", NULL
);
15112 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4
);
15114 if ((WXS_IS_UNION(memberType
)) &&
15115 ((memberType
->flags
& XML_SCHEMAS_TYPE_MARKED
) == 0))
15118 memberType
->flags
|= XML_SCHEMAS_TYPE_MARKED
;
15119 res
= xmlSchemaCheckUnionTypeDefCircularRecur(pctxt
,
15121 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType
));
15122 memberType
->flags
^= XML_SCHEMAS_TYPE_MARKED
;
15126 memberType
= memberType
->baseType
;
15128 member
= member
->next
;
15134 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt
,
15135 xmlSchemaTypePtr type
)
15137 if (! WXS_IS_UNION(type
))
15139 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt
, type
,
15140 type
->memberTypes
));
15144 * xmlSchemaResolveTypeReferences:
15145 * @item: the complex/simple type definition
15146 * @ctxt: the parser context
15149 * Resolves type definition references
15152 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef
,
15153 xmlSchemaParserCtxtPtr ctxt
)
15155 if (typeDef
== NULL
)
15159 * Resolve the base type.
15161 if (typeDef
->baseType
== NULL
) {
15162 typeDef
->baseType
= xmlSchemaGetType(ctxt
->schema
,
15163 typeDef
->base
, typeDef
->baseNs
);
15164 if (typeDef
->baseType
== NULL
) {
15165 xmlSchemaPResCompAttrErr(ctxt
,
15166 XML_SCHEMAP_SRC_RESOLVE
,
15167 WXS_BASIC_CAST typeDef
, typeDef
->node
,
15168 "base", typeDef
->base
, typeDef
->baseNs
,
15169 XML_SCHEMA_TYPE_SIMPLE
, NULL
);
15173 if (WXS_IS_SIMPLE(typeDef
)) {
15174 if (WXS_IS_UNION(typeDef
)) {
15176 * Resolve the memberTypes.
15178 xmlSchemaResolveUnionMemberTypes(ctxt
, typeDef
);
15180 } else if (WXS_IS_LIST(typeDef
)) {
15182 * Resolve the itemType.
15184 if ((typeDef
->subtypes
== NULL
) && (typeDef
->base
!= NULL
)) {
15186 typeDef
->subtypes
= xmlSchemaGetType(ctxt
->schema
,
15187 typeDef
->base
, typeDef
->baseNs
);
15189 if ((typeDef
->subtypes
== NULL
) ||
15190 (! WXS_IS_SIMPLE(typeDef
->subtypes
)))
15192 typeDef
->subtypes
= NULL
;
15193 xmlSchemaPResCompAttrErr(ctxt
,
15194 XML_SCHEMAP_SRC_RESOLVE
,
15195 WXS_BASIC_CAST typeDef
, typeDef
->node
,
15196 "itemType", typeDef
->base
, typeDef
->baseNs
,
15197 XML_SCHEMA_TYPE_SIMPLE
, NULL
);
15204 * The ball of letters below means, that if we have a particle
15205 * which has a QName-helper component as its {term}, we want
15208 else if ((WXS_TYPE_CONTENTTYPE(typeDef
) != NULL
) &&
15209 ((WXS_TYPE_CONTENTTYPE(typeDef
))->type
==
15210 XML_SCHEMA_TYPE_PARTICLE
) &&
15211 (WXS_TYPE_PARTICLE_TERM(typeDef
) != NULL
) &&
15212 ((WXS_TYPE_PARTICLE_TERM(typeDef
))->type
==
15213 XML_SCHEMA_EXTRA_QNAMEREF
))
15215 xmlSchemaQNameRefPtr ref
=
15216 WXS_QNAME_CAST
WXS_TYPE_PARTICLE_TERM(typeDef
);
15217 xmlSchemaModelGroupDefPtr groupDef
;
15220 * URGENT TODO: Test this.
15222 WXS_TYPE_PARTICLE_TERM(typeDef
) = NULL
;
15224 * Resolve the MG definition reference.
15227 WXS_MODEL_GROUPDEF_CAST
xmlSchemaGetNamedComponent(ctxt
->schema
,
15228 ref
->itemType
, ref
->name
, ref
->targetNamespace
);
15229 if (groupDef
== NULL
) {
15230 xmlSchemaPResCompAttrErr(ctxt
, XML_SCHEMAP_SRC_RESOLVE
,
15231 NULL
, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef
)),
15232 "ref", ref
->name
, ref
->targetNamespace
, ref
->itemType
,
15234 /* Remove the particle. */
15235 WXS_TYPE_CONTENTTYPE(typeDef
) = NULL
;
15236 } else if (WXS_MODELGROUPDEF_MODEL(groupDef
) == NULL
)
15237 /* Remove the particle. */
15238 WXS_TYPE_CONTENTTYPE(typeDef
) = NULL
;
15241 * Assign the MG definition's {model group} to the
15242 * particle's {term}.
15244 WXS_TYPE_PARTICLE_TERM(typeDef
) = WXS_MODELGROUPDEF_MODEL(groupDef
);
15246 if (WXS_MODELGROUPDEF_MODEL(groupDef
)->type
== XML_SCHEMA_TYPE_ALL
) {
15248 * SPEC cos-all-limited (1.2)
15249 * "1.2 the {term} property of a particle with
15250 * {max occurs}=1 which is part of a pair which constitutes
15251 * the {content type} of a complex type definition."
15253 if ((WXS_TYPE_PARTICLE(typeDef
))->maxOccurs
!= 1) {
15254 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
15255 /* TODO: error code */
15256 XML_SCHEMAP_COS_ALL_LIMITED
,
15257 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef
)), NULL
,
15258 "The particle's {max occurs} must be 1, since the "
15259 "reference resolves to an 'all' model group",
15270 * xmlSchemaCheckSTPropsCorrect:
15271 * @ctxt: the schema parser context
15272 * @type: the simple type definition
15274 * Checks st-props-correct.
15276 * Returns 0 if the properties are correct,
15277 * if not, a positive error code and -1 on internal
15281 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt
,
15282 xmlSchemaTypePtr type
)
15284 xmlSchemaTypePtr baseType
= type
->baseType
;
15285 xmlChar
*str
= NULL
;
15287 /* STATE: error funcs converted. */
15289 * Schema Component Constraint: Simple Type Definition Properties Correct
15291 * NOTE: This is somehow redundant, since we actually built a simple type
15292 * to have all the needed information; this acts as an self test.
15294 /* Base type: If the datatype has been `derived` by `restriction`
15295 * then the Simple Type Definition component from which it is `derived`,
15296 * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
15298 if (baseType
== NULL
) {
15300 * TODO: Think about: "modulo the impact of Missing
15301 * Sub-components ($5.3)."
15303 xmlSchemaPCustomErr(ctxt
,
15304 XML_SCHEMAP_ST_PROPS_CORRECT_1
,
15305 WXS_BASIC_CAST type
, NULL
,
15306 "No base type existent", NULL
);
15307 return (XML_SCHEMAP_ST_PROPS_CORRECT_1
);
15310 if (! WXS_IS_SIMPLE(baseType
)) {
15311 xmlSchemaPCustomErr(ctxt
,
15312 XML_SCHEMAP_ST_PROPS_CORRECT_1
,
15313 WXS_BASIC_CAST type
, NULL
,
15314 "The base type '%s' is not a simple type",
15315 xmlSchemaGetComponentQName(&str
, baseType
));
15317 return (XML_SCHEMAP_ST_PROPS_CORRECT_1
);
15319 if ((WXS_IS_LIST(type
) || WXS_IS_UNION(type
)) &&
15320 (WXS_IS_RESTRICTION(type
) == 0) &&
15321 ((! WXS_IS_ANY_SIMPLE_TYPE(baseType
)) &&
15322 (baseType
->type
!= XML_SCHEMA_TYPE_SIMPLE
))) {
15323 xmlSchemaPCustomErr(ctxt
,
15324 XML_SCHEMAP_ST_PROPS_CORRECT_1
,
15325 WXS_BASIC_CAST type
, NULL
,
15326 "A type, derived by list or union, must have "
15327 "the simple ur-type definition as base type, not '%s'",
15328 xmlSchemaGetComponentQName(&str
, baseType
));
15330 return (XML_SCHEMAP_ST_PROPS_CORRECT_1
);
15333 * Variety: One of {atomic, list, union}.
15335 if ((! WXS_IS_ATOMIC(type
)) && (! WXS_IS_UNION(type
)) &&
15336 (! WXS_IS_LIST(type
))) {
15337 xmlSchemaPCustomErr(ctxt
,
15338 XML_SCHEMAP_ST_PROPS_CORRECT_1
,
15339 WXS_BASIC_CAST type
, NULL
,
15340 "The variety is absent", NULL
);
15341 return (XML_SCHEMAP_ST_PROPS_CORRECT_1
);
15343 /* TODO: Finish this. Hmm, is this finished? */
15346 * 3 The {final} of the {base type definition} must not contain restriction.
15348 if (xmlSchemaTypeFinalContains(baseType
,
15349 XML_SCHEMAS_TYPE_FINAL_RESTRICTION
)) {
15350 xmlSchemaPCustomErr(ctxt
,
15351 XML_SCHEMAP_ST_PROPS_CORRECT_3
,
15352 WXS_BASIC_CAST type
, NULL
,
15353 "The 'final' of its base type '%s' must not contain "
15355 xmlSchemaGetComponentQName(&str
, baseType
));
15357 return (XML_SCHEMAP_ST_PROPS_CORRECT_3
);
15361 * 2 All simple type definitions must be derived ultimately from the `simple
15362 * ur-type definition` (so circular definitions are disallowed). That is, it
15363 * must be possible to reach a built-in primitive datatype or the `simple
15364 * ur-type definition` by repeatedly following the {base type definition}.
15366 * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15372 * xmlSchemaCheckCOSSTRestricts:
15373 * @ctxt: the schema parser context
15374 * @type: the simple type definition
15376 * Schema Component Constraint:
15377 * Derivation Valid (Restriction, Simple) (cos-st-restricts)
15379 * Checks if the given @type (simpleType) is derived validly by restriction.
15382 * Returns -1 on internal errors, 0 if the type is validly derived,
15383 * a positive error code otherwise.
15386 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt
,
15387 xmlSchemaTypePtr type
)
15389 xmlChar
*str
= NULL
;
15391 if (type
->type
!= XML_SCHEMA_TYPE_SIMPLE
) {
15392 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15393 "given type is not a user-derived simpleType");
15397 if (WXS_IS_ATOMIC(type
)) {
15398 xmlSchemaTypePtr primitive
;
15400 * 1.1 The {base type definition} must be an atomic simple
15401 * type definition or a built-in primitive datatype.
15403 if (! WXS_IS_ATOMIC(type
->baseType
)) {
15404 xmlSchemaPCustomErr(pctxt
,
15405 XML_SCHEMAP_COS_ST_RESTRICTS_1_1
,
15406 WXS_BASIC_CAST type
, NULL
,
15407 "The base type '%s' is not an atomic simple type",
15408 xmlSchemaGetComponentQName(&str
, type
->baseType
));
15410 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1
);
15412 /* 1.2 The {final} of the {base type definition} must not contain
15415 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15416 if (xmlSchemaTypeFinalContains(type
->baseType
,
15417 XML_SCHEMAS_TYPE_FINAL_RESTRICTION
)) {
15418 xmlSchemaPCustomErr(pctxt
,
15419 XML_SCHEMAP_COS_ST_RESTRICTS_1_2
,
15420 WXS_BASIC_CAST type
, NULL
,
15421 "The final of its base type '%s' must not contain 'restriction'",
15422 xmlSchemaGetComponentQName(&str
, type
->baseType
));
15424 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2
);
15428 * 1.3.1 DF must be an allowed constraining facet for the {primitive
15429 * type definition}, as specified in the appropriate subsection of 3.2
15430 * Primitive datatypes.
15432 if (type
->facets
!= NULL
) {
15433 xmlSchemaFacetPtr facet
;
15436 primitive
= xmlSchemaGetPrimitiveType(type
);
15437 if (primitive
== NULL
) {
15438 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15439 "failed to get primitive type");
15442 facet
= type
->facets
;
15444 if (xmlSchemaIsBuiltInTypeFacet(primitive
, facet
->type
) == 0) {
15446 xmlSchemaPIllegalFacetAtomicErr(pctxt
,
15447 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1
,
15448 type
, primitive
, facet
);
15450 facet
= facet
->next
;
15451 } while (facet
!= NULL
);
15453 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1
);
15456 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15457 * of the {base type definition} (call this BF),then the DF's {value}
15458 * must be a valid restriction of BF's {value} as defined in
15459 * [XML Schemas: Datatypes]."
15461 * NOTE (1.3.2) Facet derivation constraints are currently handled in
15462 * xmlSchemaDeriveAndValidateFacets()
15464 } else if (WXS_IS_LIST(type
)) {
15465 xmlSchemaTypePtr itemType
= NULL
;
15467 itemType
= type
->subtypes
;
15468 if ((itemType
== NULL
) || (! WXS_IS_SIMPLE(itemType
))) {
15469 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15470 "failed to evaluate the item type");
15473 if (WXS_IS_TYPE_NOT_FIXED(itemType
))
15474 xmlSchemaTypeFixup(itemType
, ACTXT_CAST pctxt
);
15476 * 2.1 The {item type definition} must have a {variety} of atomic or
15477 * union (in which case all the {member type definitions}
15480 if ((! WXS_IS_ATOMIC(itemType
)) &&
15481 (! WXS_IS_UNION(itemType
))) {
15482 xmlSchemaPCustomErr(pctxt
,
15483 XML_SCHEMAP_COS_ST_RESTRICTS_2_1
,
15484 WXS_BASIC_CAST type
, NULL
,
15485 "The item type '%s' does not have a variety of atomic or union",
15486 xmlSchemaGetComponentQName(&str
, itemType
));
15488 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1
);
15489 } else if (WXS_IS_UNION(itemType
)) {
15490 xmlSchemaTypeLinkPtr member
;
15492 member
= itemType
->memberTypes
;
15493 while (member
!= NULL
) {
15494 if (! WXS_IS_ATOMIC(member
->type
)) {
15495 xmlSchemaPCustomErr(pctxt
,
15496 XML_SCHEMAP_COS_ST_RESTRICTS_2_1
,
15497 WXS_BASIC_CAST type
, NULL
,
15498 "The item type is a union type, but the "
15499 "member type '%s' of this item type is not atomic",
15500 xmlSchemaGetComponentQName(&str
, member
->type
));
15502 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1
);
15504 member
= member
->next
;
15508 if (WXS_IS_ANY_SIMPLE_TYPE(type
->baseType
)) {
15509 xmlSchemaFacetPtr facet
;
15511 * This is the case if we have: <simpleType><list ..
15515 * 2.3.1.1 The {final} of the {item type definition} must not
15518 if (xmlSchemaTypeFinalContains(itemType
,
15519 XML_SCHEMAS_TYPE_FINAL_LIST
)) {
15520 xmlSchemaPCustomErr(pctxt
,
15521 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1
,
15522 WXS_BASIC_CAST type
, NULL
,
15523 "The final of its item type '%s' must not contain 'list'",
15524 xmlSchemaGetComponentQName(&str
, itemType
));
15526 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1
);
15529 * 2.3.1.2 The {facets} must only contain the whiteSpace
15531 * OPTIMIZE TODO: the S4S already disallows any facet
15534 if (type
->facets
!= NULL
) {
15535 facet
= type
->facets
;
15537 if (facet
->type
!= XML_SCHEMA_FACET_WHITESPACE
) {
15538 xmlSchemaPIllegalFacetListUnionErr(pctxt
,
15539 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2
,
15541 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2
);
15543 facet
= facet
->next
;
15544 } while (facet
!= NULL
);
15547 * MAYBE TODO: (Hmm, not really) Datatypes states:
15548 * A `list` datatype can be `derived` from an `atomic` datatype
15549 * whose `lexical space` allows space (such as string or anyURI)or
15550 * a `union` datatype any of whose {member type definitions}'s
15551 * `lexical space` allows space.
15555 * This is the case if we have: <simpleType><restriction ...
15556 * I.e. the variety of "list" is inherited.
15560 * 2.3.2.1 The {base type definition} must have a {variety} of list.
15562 if (! WXS_IS_LIST(type
->baseType
)) {
15563 xmlSchemaPCustomErr(pctxt
,
15564 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1
,
15565 WXS_BASIC_CAST type
, NULL
,
15566 "The base type '%s' must be a list type",
15567 xmlSchemaGetComponentQName(&str
, type
->baseType
));
15569 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1
);
15572 * 2.3.2.2 The {final} of the {base type definition} must not
15573 * contain restriction.
15575 if (xmlSchemaTypeFinalContains(type
->baseType
,
15576 XML_SCHEMAS_TYPE_FINAL_RESTRICTION
)) {
15577 xmlSchemaPCustomErr(pctxt
,
15578 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2
,
15579 WXS_BASIC_CAST type
, NULL
,
15580 "The 'final' of the base type '%s' must not contain 'restriction'",
15581 xmlSchemaGetComponentQName(&str
, type
->baseType
));
15583 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2
);
15586 * 2.3.2.3 The {item type definition} must be validly derived
15587 * from the {base type definition}'s {item type definition} given
15588 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
15591 xmlSchemaTypePtr baseItemType
;
15593 baseItemType
= type
->baseType
->subtypes
;
15594 if ((baseItemType
== NULL
) || (! WXS_IS_SIMPLE(baseItemType
))) {
15595 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15596 "failed to eval the item type of a base type");
15599 if ((itemType
!= baseItemType
) &&
15600 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt
, itemType
,
15601 baseItemType
, 0) != 0)) {
15602 xmlChar
*strBIT
= NULL
, *strBT
= NULL
;
15603 xmlSchemaPCustomErrExt(pctxt
,
15604 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3
,
15605 WXS_BASIC_CAST type
, NULL
,
15606 "The item type '%s' is not validly derived from "
15607 "the item type '%s' of the base type '%s'",
15608 xmlSchemaGetComponentQName(&str
, itemType
),
15609 xmlSchemaGetComponentQName(&strBIT
, baseItemType
),
15610 xmlSchemaGetComponentQName(&strBT
, type
->baseType
));
15613 FREE_AND_NULL(strBIT
)
15614 FREE_AND_NULL(strBT
)
15615 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3
);
15619 if (type
->facets
!= NULL
) {
15620 xmlSchemaFacetPtr facet
;
15623 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15624 * and enumeration facet components are allowed among the {facets}.
15626 facet
= type
->facets
;
15628 switch (facet
->type
) {
15629 case XML_SCHEMA_FACET_LENGTH
:
15630 case XML_SCHEMA_FACET_MINLENGTH
:
15631 case XML_SCHEMA_FACET_MAXLENGTH
:
15632 case XML_SCHEMA_FACET_WHITESPACE
:
15634 * TODO: 2.5.1.2 List datatypes
15635 * The value of `whiteSpace` is fixed to the value collapse.
15637 case XML_SCHEMA_FACET_PATTERN
:
15638 case XML_SCHEMA_FACET_ENUMERATION
:
15641 xmlSchemaPIllegalFacetListUnionErr(pctxt
,
15642 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4
,
15645 * We could return, but it's nicer to report all
15651 facet
= facet
->next
;
15652 } while (facet
!= NULL
);
15654 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4
);
15656 * SPEC (2.3.2.5) (same as 1.3.2)
15658 * NOTE (2.3.2.5) This is currently done in
15659 * xmlSchemaDeriveAndValidateFacets()
15663 } else if (WXS_IS_UNION(type
)) {
15665 * 3.1 The {member type definitions} must all have {variety} of
15668 xmlSchemaTypeLinkPtr member
;
15670 member
= type
->memberTypes
;
15671 while (member
!= NULL
) {
15672 if (WXS_IS_TYPE_NOT_FIXED(member
->type
))
15673 xmlSchemaTypeFixup(member
->type
, ACTXT_CAST pctxt
);
15675 if ((! WXS_IS_ATOMIC(member
->type
)) &&
15676 (! WXS_IS_LIST(member
->type
))) {
15677 xmlSchemaPCustomErr(pctxt
,
15678 XML_SCHEMAP_COS_ST_RESTRICTS_3_1
,
15679 WXS_BASIC_CAST type
, NULL
,
15680 "The member type '%s' is neither an atomic, nor a list type",
15681 xmlSchemaGetComponentQName(&str
, member
->type
));
15683 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1
);
15685 member
= member
->next
;
15688 * 3.3.1 If the {base type definition} is the `simple ur-type
15691 if (type
->baseType
->builtInType
== XML_SCHEMAS_ANYSIMPLETYPE
) {
15693 * 3.3.1.1 All of the {member type definitions} must have a
15694 * {final} which does not contain union.
15696 member
= type
->memberTypes
;
15697 while (member
!= NULL
) {
15698 if (xmlSchemaTypeFinalContains(member
->type
,
15699 XML_SCHEMAS_TYPE_FINAL_UNION
)) {
15700 xmlSchemaPCustomErr(pctxt
,
15701 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1
,
15702 WXS_BASIC_CAST type
, NULL
,
15703 "The 'final' of member type '%s' contains 'union'",
15704 xmlSchemaGetComponentQName(&str
, member
->type
));
15706 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1
);
15708 member
= member
->next
;
15711 * 3.3.1.2 The {facets} must be empty.
15713 if (type
->facetSet
!= NULL
) {
15714 xmlSchemaPCustomErr(pctxt
,
15715 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2
,
15716 WXS_BASIC_CAST type
, NULL
,
15717 "No facets allowed", NULL
);
15718 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2
);
15722 * 3.3.2.1 The {base type definition} must have a {variety} of union.
15723 * I.e. the variety of "list" is inherited.
15725 if (! WXS_IS_UNION(type
->baseType
)) {
15726 xmlSchemaPCustomErr(pctxt
,
15727 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1
,
15728 WXS_BASIC_CAST type
, NULL
,
15729 "The base type '%s' is not a union type",
15730 xmlSchemaGetComponentQName(&str
, type
->baseType
));
15732 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1
);
15735 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15737 if (xmlSchemaTypeFinalContains(type
->baseType
,
15738 XML_SCHEMAS_TYPE_FINAL_RESTRICTION
)) {
15739 xmlSchemaPCustomErr(pctxt
,
15740 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2
,
15741 WXS_BASIC_CAST type
, NULL
,
15742 "The 'final' of its base type '%s' must not contain 'restriction'",
15743 xmlSchemaGetComponentQName(&str
, type
->baseType
));
15745 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2
);
15748 * 3.3.2.3 The {member type definitions}, in order, must be validly
15749 * derived from the corresponding type definitions in the {base
15750 * type definition}'s {member type definitions} given the empty set,
15751 * as defined in Type Derivation OK (Simple) ($3.14.6).
15754 xmlSchemaTypeLinkPtr baseMember
;
15757 * OPTIMIZE: if the type is restricting, it has no local defined
15758 * member types and inherits the member types of the base type;
15759 * thus a check for equality can be skipped.
15762 * Even worse: I cannot see a scenario where a restricting
15763 * union simple type can have other member types as the member
15764 * types of it's base type. This check seems not necessary with
15765 * respect to the derivation process in libxml2.
15766 * But necessary if constructing types with an API.
15768 if (type
->memberTypes
!= NULL
) {
15769 member
= type
->memberTypes
;
15770 baseMember
= xmlSchemaGetUnionSimpleTypeMemberTypes(type
->baseType
);
15771 if ((member
== NULL
) && (baseMember
!= NULL
)) {
15772 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15773 "different number of member types in base");
15775 while (member
!= NULL
) {
15776 if (baseMember
== NULL
) {
15777 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15778 "different number of member types in base");
15779 } else if ((member
->type
!= baseMember
->type
) &&
15780 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt
,
15781 member
->type
, baseMember
->type
, 0) != 0)) {
15782 xmlChar
*strBMT
= NULL
, *strBT
= NULL
;
15784 xmlSchemaPCustomErrExt(pctxt
,
15785 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3
,
15786 WXS_BASIC_CAST type
, NULL
,
15787 "The member type %s is not validly "
15788 "derived from its corresponding member "
15789 "type %s of the base type %s",
15790 xmlSchemaGetComponentQName(&str
, member
->type
),
15791 xmlSchemaGetComponentQName(&strBMT
, baseMember
->type
),
15792 xmlSchemaGetComponentQName(&strBT
, type
->baseType
));
15794 FREE_AND_NULL(strBMT
)
15795 FREE_AND_NULL(strBT
)
15796 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3
);
15798 member
= member
->next
;
15799 if (baseMember
!= NULL
)
15800 baseMember
= baseMember
->next
;
15805 * 3.3.2.4 Only pattern and enumeration facet components are
15806 * allowed among the {facets}.
15808 if (type
->facets
!= NULL
) {
15809 xmlSchemaFacetPtr facet
;
15812 facet
= type
->facets
;
15814 if ((facet
->type
!= XML_SCHEMA_FACET_PATTERN
) &&
15815 (facet
->type
!= XML_SCHEMA_FACET_ENUMERATION
)) {
15816 xmlSchemaPIllegalFacetListUnionErr(pctxt
,
15817 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4
,
15821 facet
= facet
->next
;
15822 } while (facet
!= NULL
);
15824 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4
);
15828 * SPEC (3.3.2.5) (same as 1.3.2)
15830 * NOTE (3.3.2.5) This is currently done in
15831 * xmlSchemaDeriveAndValidateFacets()
15840 * xmlSchemaCheckSRCSimpleType:
15841 * @ctxt: the schema parser context
15842 * @type: the simple type definition
15844 * Checks crc-simple-type constraints.
15846 * Returns 0 if the constraints are satisfied,
15847 * if not a positive error code and -1 on internal
15852 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt
,
15853 xmlSchemaTypePtr type
)
15856 * src-simple-type.1 The corresponding simple type definition, if any,
15857 * must satisfy the conditions set out in Constraints on Simple Type
15858 * Definition Schema Components ($3.14.6).
15860 if (WXS_IS_RESTRICTION(type
)) {
15862 * src-simple-type.2 "If the <restriction> alternative is chosen,
15863 * either it must have a base [attribute] or a <simpleType> among its
15864 * [children], but not both."
15865 * NOTE: This is checked in the parse function of <restriction>.
15870 } else if (WXS_IS_LIST(type
)) {
15871 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15872 * an itemType [attribute] or a <simpleType> among its [children],
15875 * NOTE: This is checked in the parse function of <list>.
15877 } else if (WXS_IS_UNION(type
)) {
15879 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15887 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt
)
15889 if (ctxt
->vctxt
== NULL
) {
15890 ctxt
->vctxt
= xmlSchemaNewValidCtxt(NULL
);
15891 if (ctxt
->vctxt
== NULL
) {
15892 xmlSchemaPErr(ctxt
, NULL
,
15893 XML_SCHEMAP_INTERNAL
,
15894 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15895 "failed to create a temp. validation context.\n",
15899 /* TODO: Pass user data. */
15900 xmlSchemaSetValidErrors(ctxt
->vctxt
,
15901 ctxt
->error
, ctxt
->warning
, ctxt
->errCtxt
);
15902 xmlSchemaSetValidStructuredErrors(ctxt
->vctxt
,
15903 ctxt
->serror
, ctxt
->errCtxt
);
15909 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt
,
15911 xmlSchemaTypePtr type
,
15912 const xmlChar
*value
,
15913 xmlSchemaValPtr
*retVal
,
15919 * xmlSchemaParseCheckCOSValidDefault:
15920 * @pctxt: the schema parser context
15921 * @type: the simple type definition
15922 * @value: the default value
15923 * @node: an optional node (the holder of the value)
15925 * Schema Component Constraint: Element Default Valid (Immediate)
15926 * (cos-valid-default)
15927 * This will be used by the parser only. For the validator there's
15928 * an other version.
15930 * Returns 0 if the constraints are satisfied,
15931 * if not, a positive error code and -1 on internal
15935 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt
,
15937 xmlSchemaTypePtr type
,
15938 const xmlChar
*value
,
15939 xmlSchemaValPtr
*val
)
15944 * cos-valid-default:
15945 * Schema Component Constraint: Element Default Valid (Immediate)
15946 * For a string to be a valid default with respect to a type
15947 * definition the appropriate case among the following must be true:
15949 if WXS_IS_COMPLEX(type
) {
15953 * SPEC (2.1) "its {content type} must be a simple type definition
15955 * SPEC (2.2.2) "If the {content type} is mixed, then the {content
15956 * type}'s particle must be `emptiable` as defined by
15957 * Particle Emptiable ($3.9.6)."
15959 if ((! WXS_HAS_SIMPLE_CONTENT(type
)) &&
15960 ((! WXS_HAS_MIXED_CONTENT(type
)) || (! WXS_EMPTIABLE(type
)))) {
15961 /* NOTE that this covers (2.2.2) as well. */
15962 xmlSchemaPCustomErr(pctxt
,
15963 XML_SCHEMAP_COS_VALID_DEFAULT_2_1
,
15964 WXS_BASIC_CAST type
, type
->node
,
15965 "For a string to be a valid default, the type definition "
15966 "must be a simple type or a complex type with mixed content "
15967 "and a particle emptiable", NULL
);
15968 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1
);
15972 * 1 If the type definition is a simple type definition, then the string
15973 * must be `valid` with respect to that definition as defined by String
15978 * 2.2.1 If the {content type} is a simple type definition, then the
15979 * string must be `valid` with respect to that simple type definition
15980 * as defined by String Valid ($3.14.4).
15982 if (WXS_IS_SIMPLE(type
))
15983 ret
= xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt
, node
,
15984 type
, value
, val
, 1, 1, 0);
15985 else if (WXS_HAS_SIMPLE_CONTENT(type
))
15986 ret
= xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt
, node
,
15987 type
->contentTypeDef
, value
, val
, 1, 1, 0);
15992 PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
15993 "calling xmlSchemaVCheckCVCSimpleType()");
16000 * xmlSchemaCheckCTPropsCorrect:
16001 * @ctxt: the schema parser context
16002 * @type: the complex type definition
16004 *.(4.6) Constraints on Complex Type Definition Schema Components
16005 * Schema Component Constraint:
16006 * Complex Type Definition Properties Correct (ct-props-correct)
16007 * STATUS: (seems) complete
16009 * Returns 0 if the constraints are satisfied, a positive
16010 * error code if not and -1 if an internal error occurred.
16013 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt
,
16014 xmlSchemaTypePtr type
)
16017 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
16019 * SPEC (1) "The values of the properties of a complex type definition must
16020 * be as described in the property tableau in The Complex Type Definition
16021 * Schema Component ($3.4.1), modulo the impact of Missing
16022 * Sub-components ($5.3)."
16024 if ((type
->baseType
!= NULL
) &&
16025 (WXS_IS_SIMPLE(type
->baseType
)) &&
16026 (WXS_IS_EXTENSION(type
) == 0)) {
16028 * SPEC (2) "If the {base type definition} is a simple type definition,
16029 * the {derivation method} must be extension."
16031 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
16032 XML_SCHEMAP_SRC_CT_1
,
16033 NULL
, WXS_BASIC_CAST type
,
16034 "If the base type is a simple type, the derivation method must be "
16035 "'extension'", NULL
, NULL
);
16036 return (XML_SCHEMAP_SRC_CT_1
);
16039 * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
16040 * definition`. That is, it must be possible to reach the `ur-type
16041 * definition` by repeatedly following the {base type definition}."
16043 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
16046 * NOTE that (4) and (5) need the following:
16047 * - attribute uses need to be already inherited (apply attr. prohibitions)
16048 * - attribute group references need to be expanded already
16049 * - simple types need to be typefixed already
16051 if (type
->attrUses
&&
16052 (((xmlSchemaItemListPtr
) type
->attrUses
)->nbItems
> 1))
16054 xmlSchemaItemListPtr uses
= (xmlSchemaItemListPtr
) type
->attrUses
;
16055 xmlSchemaAttributeUsePtr use
, tmp
;
16056 int i
, j
, hasId
= 0;
16058 for (i
= uses
->nbItems
-1; i
>= 0; i
--) {
16059 use
= uses
->items
[i
];
16062 * SPEC ct-props-correct
16063 * (4) "Two distinct attribute declarations in the
16064 * {attribute uses} must not have identical {name}s and
16065 * {target namespace}s."
16068 for (j
= i
-1; j
>= 0; j
--) {
16069 tmp
= uses
->items
[j
];
16070 if ((WXS_ATTRUSE_DECL_NAME(use
) ==
16071 WXS_ATTRUSE_DECL_NAME(tmp
)) &&
16072 (WXS_ATTRUSE_DECL_TNS(use
) ==
16073 WXS_ATTRUSE_DECL_TNS(tmp
)))
16075 xmlChar
*str
= NULL
;
16077 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
16078 XML_SCHEMAP_AG_PROPS_CORRECT
,
16079 NULL
, WXS_BASIC_CAST type
,
16081 xmlSchemaGetComponentDesignation(&str
, use
),
16083 FREE_AND_NULL(str
);
16085 * Remove the duplicate.
16087 if (xmlSchemaItemListRemove(uses
, i
) == -1)
16094 * SPEC ct-props-correct
16095 * (5) "Two distinct attribute declarations in the
16096 * {attribute uses} must not have {type definition}s which
16097 * are or are derived from ID."
16099 if (WXS_ATTRUSE_TYPEDEF(use
) != NULL
) {
16100 if (xmlSchemaIsDerivedFromBuiltInType(
16101 WXS_ATTRUSE_TYPEDEF(use
), XML_SCHEMAS_ID
))
16104 xmlChar
*str
= NULL
;
16106 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
16107 XML_SCHEMAP_AG_PROPS_CORRECT
,
16108 NULL
, WXS_BASIC_CAST type
,
16109 "There must not exist more than one attribute "
16110 "declaration of type 'xs:ID' "
16111 "(or derived from 'xs:ID'). The %s violates this "
16113 xmlSchemaGetComponentDesignation(&str
, use
),
16115 FREE_AND_NULL(str
);
16116 if (xmlSchemaItemListRemove(uses
, i
) == -1)
16132 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA
,
16133 xmlSchemaTypePtr typeB
)
16136 * TODO: This should implement component-identity
16139 if ((typeA
== NULL
) || (typeB
== NULL
))
16141 return (typeA
== typeB
);
16145 * xmlSchemaCheckCOSCTDerivedOK:
16146 * @ctxt: the schema parser context
16147 * @type: the to-be derived complex type definition
16148 * @baseType: the base complex type definition
16149 * @set: the given set
16151 * Schema Component Constraint:
16152 * Type Derivation OK (Complex) (cos-ct-derived-ok)
16154 * STATUS: completed
16156 * Returns 0 if the constraints are satisfied, or 1
16160 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt
,
16161 xmlSchemaTypePtr type
,
16162 xmlSchemaTypePtr baseType
,
16165 int equal
= xmlSchemaAreEqualTypes(type
, baseType
);
16166 /* TODO: Error codes. */
16168 * SPEC "For a complex type definition (call it D, for derived)
16169 * to be validly derived from a type definition (call this
16170 * B, for base) given a subset of {extension, restriction}
16171 * all of the following must be true:"
16175 * SPEC (1) "If B and D are not the same type definition, then the
16176 * {derivation method} of D must not be in the subset."
16178 if (((set
& SUBSET_EXTENSION
) && (WXS_IS_EXTENSION(type
))) ||
16179 ((set
& SUBSET_RESTRICTION
) && (WXS_IS_RESTRICTION(type
))))
16183 * SPEC (2.1) "B and D must be the same type definition."
16188 * SPEC (2.2) "B must be D's {base type definition}."
16190 if (type
->baseType
== baseType
)
16193 * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
16196 if (WXS_IS_ANYTYPE(type
->baseType
))
16199 if (WXS_IS_COMPLEX(type
->baseType
)) {
16201 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16202 * must be validly derived from B given the subset as defined by this
16205 return (xmlSchemaCheckCOSCTDerivedOK(actxt
, type
->baseType
,
16209 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16210 * must be validly derived from B given the subset as defined in Type
16211 * Derivation OK (Simple) ($3.14.6).
16213 return (xmlSchemaCheckCOSSTDerivedOK(actxt
, type
->baseType
,
16219 * xmlSchemaCheckCOSDerivedOK:
16220 * @type: the derived simple type definition
16221 * @baseType: the base type definition
16224 * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
16226 * Checks whether @type can be validly derived from @baseType.
16228 * Returns 0 on success, an positive error code otherwise.
16231 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt
,
16232 xmlSchemaTypePtr type
,
16233 xmlSchemaTypePtr baseType
,
16236 if (WXS_IS_SIMPLE(type
))
16237 return (xmlSchemaCheckCOSSTDerivedOK(actxt
, type
, baseType
, set
));
16239 return (xmlSchemaCheckCOSCTDerivedOK(actxt
, type
, baseType
, set
));
16243 * xmlSchemaCheckCOSCTExtends:
16244 * @ctxt: the schema parser context
16245 * @type: the complex type definition
16247 * (3.4.6) Constraints on Complex Type Definition Schema Components
16248 * Schema Component Constraint:
16249 * Derivation Valid (Extension) (cos-ct-extends)
16254 * (1.4.3.2.2.2) "Particle Valid (Extension)"
16256 * Returns 0 if the constraints are satisfied, a positive
16257 * error code if not and -1 if an internal error occurred.
16260 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt
,
16261 xmlSchemaTypePtr type
)
16263 xmlSchemaTypePtr base
= type
->baseType
;
16265 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16266 * temporarily only.
16269 * SPEC (1) "If the {base type definition} is a complex type definition,
16270 * then all of the following must be true:"
16272 if (WXS_IS_COMPLEX(base
)) {
16274 * SPEC (1.1) "The {final} of the {base type definition} must not
16275 * contain extension."
16277 if (base
->flags
& XML_SCHEMAS_TYPE_FINAL_EXTENSION
) {
16278 xmlSchemaPCustomErr(ctxt
,
16279 XML_SCHEMAP_COS_CT_EXTENDS_1_1
,
16280 WXS_BASIC_CAST type
, NULL
,
16281 "The 'final' of the base type definition "
16282 "contains 'extension'", NULL
);
16283 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1
);
16287 * ATTENTION: The constrains (1.2) and (1.3) are not applied,
16288 * since they are automatically satisfied through the
16289 * inheriting mechanism.
16290 * Note that even if redefining components, the inheriting mechanism
16295 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16297 * of the complex type definition itself, that is, for every attribute
16298 * use in the {attribute uses} of the {base type definition}, there
16299 * must be an attribute use in the {attribute uses} of the complex
16300 * type definition itself whose {attribute declaration} has the same
16301 * {name}, {target namespace} and {type definition} as its attribute
16304 if (base
->attrUses
!= NULL
) {
16306 xmlSchemaAttributeUsePtr use
, buse
;
16308 for (i
= 0; i
< (WXS_LIST_CAST base
->attrUses
)->nbItems
; i
++) {
16309 buse
= (WXS_LIST_CAST base
->attrUses
)->items
[i
];
16311 if (type
->attrUses
!= NULL
) {
16312 use
= (WXS_LIST_CAST type
->attrUses
)->items
[j
];
16313 for (j
= 0; j
< (WXS_LIST_CAST type
->attrUses
)->nbItems
; j
++)
16315 if ((WXS_ATTRUSE_DECL_NAME(use
) ==
16316 WXS_ATTRUSE_DECL_NAME(buse
)) &&
16317 (WXS_ATTRUSE_DECL_TNS(use
) ==
16318 WXS_ATTRUSE_DECL_TNS(buse
)) &&
16319 (WXS_ATTRUSE_TYPEDEF(use
) ==
16320 WXS_ATTRUSE_TYPEDEF(buse
))
16328 xmlChar
*str
= NULL
;
16330 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
16331 XML_SCHEMAP_COS_CT_EXTENDS_1_2
,
16332 NULL
, WXS_BASIC_CAST type
,
16334 * TODO: The report does not indicate that also the
16335 * type needs to be the same.
16337 "This type is missing a matching correspondent "
16338 "for its {base type}'s %s in its {attribute uses}",
16339 xmlSchemaGetComponentDesignation(&str
,
16347 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16348 * definition must also have one, and the base type definition's
16349 * {attribute wildcard}'s {namespace constraint} must be a subset
16350 * of the complex type definition's {attribute wildcard}'s {namespace
16351 * constraint}, as defined by Wildcard Subset ($3.10.6)."
16355 * MAYBE TODO: Enable if ever needed. But this will be needed only
16356 * if created the type via a schema construction API.
16358 if (base
->attributeWildcard
!= NULL
) {
16359 if (type
->attributeWildcard
== NULL
) {
16360 xmlChar
*str
= NULL
;
16362 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
16363 XML_SCHEMAP_COS_CT_EXTENDS_1_3
,
16365 "The base %s has an attribute wildcard, "
16366 "but this type is missing an attribute wildcard",
16367 xmlSchemaGetComponentDesignation(&str
, base
));
16370 } else if (xmlSchemaCheckCOSNSSubset(
16371 base
->attributeWildcard
, type
->attributeWildcard
))
16373 xmlChar
*str
= NULL
;
16375 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
16376 XML_SCHEMAP_COS_CT_EXTENDS_1_3
,
16378 "The attribute wildcard is not a valid "
16379 "superset of the one in the base %s",
16380 xmlSchemaGetComponentDesignation(&str
, base
));
16386 * SPEC (1.4) "One of the following must be true:"
16388 if ((type
->contentTypeDef
!= NULL
) &&
16389 (type
->contentTypeDef
== base
->contentTypeDef
)) {
16391 * SPEC (1.4.1) "The {content type} of the {base type definition}
16392 * and the {content type} of the complex type definition itself
16393 * must be the same simple type definition"
16396 } else if ((type
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) &&
16397 (base
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) ) {
16399 * SPEC (1.4.2) "The {content type} of both the {base type
16400 * definition} and the complex type definition itself must
16406 * SPEC (1.4.3) "All of the following must be true:"
16408 if (type
->subtypes
== NULL
) {
16410 * SPEC 1.4.3.1 The {content type} of the complex type
16411 * definition itself must specify a particle.
16413 xmlSchemaPCustomErr(ctxt
,
16414 XML_SCHEMAP_COS_CT_EXTENDS_1_1
,
16415 WXS_BASIC_CAST type
, NULL
,
16416 "The content type must specify a particle", NULL
);
16417 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1
);
16420 * SPEC (1.4.3.2) "One of the following must be true:"
16422 if (base
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) {
16424 * SPEC (1.4.3.2.1) "The {content type} of the {base type
16425 * definition} must be empty.
16430 * SPEC (1.4.3.2.2) "All of the following must be true:"
16432 if ((type
->contentType
!= base
->contentType
) ||
16433 ((type
->contentType
!= XML_SCHEMA_CONTENT_MIXED
) &&
16434 (type
->contentType
!= XML_SCHEMA_CONTENT_ELEMENTS
))) {
16436 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16437 * or both must be element-only."
16439 xmlSchemaPCustomErr(ctxt
,
16440 XML_SCHEMAP_COS_CT_EXTENDS_1_1
,
16441 WXS_BASIC_CAST type
, NULL
,
16442 "The content type of both, the type and its base "
16443 "type, must either 'mixed' or 'element-only'", NULL
);
16444 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1
);
16447 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16448 * complex type definition must be a `valid extension`
16449 * of the {base type definition}'s particle, as defined
16450 * in Particle Valid (Extension) ($3.9.6)."
16452 * NOTE that we won't check "Particle Valid (Extension)",
16453 * since it is ensured by the derivation process in
16454 * xmlSchemaTypeFixup(). We need to implement this when heading
16455 * for a construction API
16456 * TODO: !! This is needed to be checked if redefining a type !!
16460 * URGENT TODO (1.5)
16465 * SPEC (2) "If the {base type definition} is a simple type definition,
16466 * then all of the following must be true:"
16468 if (type
->contentTypeDef
!= base
) {
16470 * SPEC (2.1) "The {content type} must be the same simple type
16473 xmlSchemaPCustomErr(ctxt
,
16474 XML_SCHEMAP_COS_CT_EXTENDS_1_1
,
16475 WXS_BASIC_CAST type
, NULL
,
16476 "The content type must be the simple base type", NULL
);
16477 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1
);
16479 if (base
->flags
& XML_SCHEMAS_TYPE_FINAL_EXTENSION
) {
16481 * SPEC (2.2) "The {final} of the {base type definition} must not
16482 * contain extension"
16483 * NOTE that this is the same as (1.1).
16485 xmlSchemaPCustomErr(ctxt
,
16486 XML_SCHEMAP_COS_CT_EXTENDS_1_1
,
16487 WXS_BASIC_CAST type
, NULL
,
16488 "The 'final' of the base type definition "
16489 "contains 'extension'", NULL
);
16490 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1
);
16497 * xmlSchemaCheckDerivationOKRestriction:
16498 * @ctxt: the schema parser context
16499 * @type: the complex type definition
16501 * (3.4.6) Constraints on Complex Type Definition Schema Components
16502 * Schema Component Constraint:
16503 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16510 * In XML Schema 1.1 this will be:
16511 * Validation Rule: Checking complex type subsumption
16513 * Returns 0 if the constraints are satisfied, a positive
16514 * error code if not and -1 if an internal error occurred.
16517 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt
,
16518 xmlSchemaTypePtr type
)
16520 xmlSchemaTypePtr base
;
16523 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16524 * temporarily only.
16526 base
= type
->baseType
;
16527 if (! WXS_IS_COMPLEX(base
)) {
16528 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
16529 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16530 type
->node
, WXS_BASIC_CAST type
,
16531 "The base type must be a complex type", NULL
, NULL
);
16534 if (base
->flags
& XML_SCHEMAS_TYPE_FINAL_RESTRICTION
) {
16536 * SPEC (1) "The {base type definition} must be a complex type
16537 * definition whose {final} does not contain restriction."
16539 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
16540 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16541 type
->node
, WXS_BASIC_CAST type
,
16542 "The 'final' of the base type definition "
16543 "contains 'restriction'", NULL
, NULL
);
16544 return (ctxt
->err
);
16547 * SPEC (2), (3) and (4)
16548 * Those are handled in a separate function, since the
16549 * same constraints are needed for redefinition of
16550 * attribute groups as well.
16552 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt
,
16553 XML_SCHEMA_ACTION_DERIVE
,
16554 WXS_BASIC_CAST type
, WXS_BASIC_CAST base
,
16555 type
->attrUses
, base
->attrUses
,
16556 type
->attributeWildcard
,
16557 base
->attributeWildcard
) == -1)
16562 * SPEC (5) "One of the following must be true:"
16564 if (base
->builtInType
== XML_SCHEMAS_ANYTYPE
) {
16566 * SPEC (5.1) "The {base type definition} must be the
16567 * `ur-type definition`."
16570 } else if ((type
->contentType
== XML_SCHEMA_CONTENT_SIMPLE
) ||
16571 (type
->contentType
== XML_SCHEMA_CONTENT_BASIC
)) {
16573 * SPEC (5.2.1) "The {content type} of the complex type definition
16574 * must be a simple type definition"
16576 * SPEC (5.2.2) "One of the following must be true:"
16578 if ((base
->contentType
== XML_SCHEMA_CONTENT_SIMPLE
) ||
16579 (base
->contentType
== XML_SCHEMA_CONTENT_BASIC
))
16583 * SPEC (5.2.2.1) "The {content type} of the {base type
16584 * definition} must be a simple type definition from which
16585 * the {content type} is validly derived given the empty
16586 * set as defined in Type Derivation OK (Simple) ($3.14.6)."
16588 * ATTENTION TODO: This seems not needed if the type implicitly
16589 * derived from the base type.
16592 err
= xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt
,
16593 type
->contentTypeDef
, base
->contentTypeDef
, 0);
16595 xmlChar
*strA
= NULL
, *strB
= NULL
;
16599 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
16600 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16601 NULL
, WXS_BASIC_CAST type
,
16602 "The {content type} %s is not validly derived from the "
16603 "base type's {content type} %s",
16604 xmlSchemaGetComponentDesignation(&strA
,
16605 type
->contentTypeDef
),
16606 xmlSchemaGetComponentDesignation(&strB
,
16607 base
->contentTypeDef
));
16608 FREE_AND_NULL(strA
);
16609 FREE_AND_NULL(strB
);
16612 } else if ((base
->contentType
== XML_SCHEMA_CONTENT_MIXED
) &&
16613 (xmlSchemaIsParticleEmptiable(
16614 (xmlSchemaParticlePtr
) base
->subtypes
))) {
16616 * SPEC (5.2.2.2) "The {base type definition} must be mixed
16617 * and have a particle which is `emptiable` as defined in
16618 * Particle Emptiable ($3.9.6)."
16622 xmlSchemaPCustomErr(ctxt
,
16623 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16624 WXS_BASIC_CAST type
, NULL
,
16625 "The content type of the base type must be either "
16626 "a simple type or 'mixed' and an emptiable particle", NULL
);
16627 return (ctxt
->err
);
16629 } else if (type
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) {
16631 * SPEC (5.3.1) "The {content type} of the complex type itself must
16634 if (base
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) {
16636 * SPEC (5.3.2.1) "The {content type} of the {base type
16637 * definition} must also be empty."
16640 } else if (((base
->contentType
== XML_SCHEMA_CONTENT_ELEMENTS
) ||
16641 (base
->contentType
== XML_SCHEMA_CONTENT_MIXED
)) &&
16642 xmlSchemaIsParticleEmptiable(
16643 (xmlSchemaParticlePtr
) base
->subtypes
)) {
16645 * SPEC (5.3.2.2) "The {content type} of the {base type
16646 * definition} must be elementOnly or mixed and have a particle
16647 * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
16651 xmlSchemaPCustomErr(ctxt
,
16652 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16653 WXS_BASIC_CAST type
, NULL
,
16654 "The content type of the base type must be either "
16655 "empty or 'mixed' (or 'elements-only') and an emptiable "
16657 return (ctxt
->err
);
16659 } else if ((type
->contentType
== XML_SCHEMA_CONTENT_ELEMENTS
) ||
16660 WXS_HAS_MIXED_CONTENT(type
)) {
16662 * SPEC (5.4.1.1) "The {content type} of the complex type definition
16663 * itself must be element-only"
16665 if (WXS_HAS_MIXED_CONTENT(type
) && (! WXS_HAS_MIXED_CONTENT(base
))) {
16667 * SPEC (5.4.1.2) "The {content type} of the complex type
16668 * definition itself and of the {base type definition} must be
16671 xmlSchemaPCustomErr(ctxt
,
16672 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16673 WXS_BASIC_CAST type
, NULL
,
16674 "If the content type is 'mixed', then the content type of the "
16675 "base type must also be 'mixed'", NULL
);
16676 return (ctxt
->err
);
16679 * SPEC (5.4.2) "The particle of the complex type definition itself
16680 * must be a `valid restriction` of the particle of the {content
16681 * type} of the {base type definition} as defined in Particle Valid
16682 * (Restriction) ($3.9.6).
16684 * URGENT TODO: (5.4.2)
16687 xmlSchemaPCustomErr(ctxt
,
16688 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1
,
16689 WXS_BASIC_CAST type
, NULL
,
16690 "The type is not a valid restriction of its base type", NULL
);
16691 return (ctxt
->err
);
16697 * xmlSchemaCheckCTComponent:
16698 * @ctxt: the schema parser context
16699 * @type: the complex type definition
16701 * (3.4.6) Constraints on Complex Type Definition Schema Components
16703 * Returns 0 if the constraints are satisfied, a positive
16704 * error code if not and -1 if an internal error occurred.
16707 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt
,
16708 xmlSchemaTypePtr type
)
16712 * Complex Type Definition Properties Correct
16714 ret
= xmlSchemaCheckCTPropsCorrect(ctxt
, type
);
16717 if (WXS_IS_EXTENSION(type
))
16718 ret
= xmlSchemaCheckCOSCTExtends(ctxt
, type
);
16720 ret
= xmlSchemaCheckDerivationOKRestriction(ctxt
, type
);
16725 * xmlSchemaCheckSRCCT:
16726 * @ctxt: the schema parser context
16727 * @type: the complex type definition
16729 * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16730 * Schema Representation Constraint:
16731 * Complex Type Definition Representation OK (src-ct)
16733 * Returns 0 if the constraints are satisfied, a positive
16734 * error code if not and -1 if an internal error occurred.
16737 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt
,
16738 xmlSchemaTypePtr type
)
16740 xmlSchemaTypePtr base
;
16744 * TODO: Adjust the error codes here, as I used
16745 * XML_SCHEMAP_SRC_CT_1 only yet.
16747 base
= type
->baseType
;
16748 if (! WXS_HAS_SIMPLE_CONTENT(type
)) {
16750 * 1 If the <complexContent> alternative is chosen, the type definition
16751 * `resolved` to by the `actual value` of the base [attribute]
16752 * must be a complex type definition;
16754 if (! WXS_IS_COMPLEX(base
)) {
16755 xmlChar
*str
= NULL
;
16756 xmlSchemaPCustomErr(ctxt
,
16757 XML_SCHEMAP_SRC_CT_1
,
16758 WXS_BASIC_CAST type
, type
->node
,
16759 "If using <complexContent>, the base type is expected to be "
16760 "a complex type. The base type '%s' is a simple type",
16761 xmlSchemaFormatQName(&str
, base
->targetNamespace
,
16764 return (XML_SCHEMAP_SRC_CT_1
);
16769 * 2 If the <simpleContent> alternative is chosen, all of the
16770 * following must be true:
16771 * 2.1 The type definition `resolved` to by the `actual value` of the
16772 * base [attribute] must be one of the following:
16774 if (WXS_IS_SIMPLE(base
)) {
16775 if (WXS_IS_EXTENSION(type
) == 0) {
16776 xmlChar
*str
= NULL
;
16778 * 2.1.3 only if the <extension> alternative is also
16779 * chosen, a simple type definition.
16781 /* TODO: Change error code to ..._SRC_CT_2_1_3. */
16782 xmlSchemaPCustomErr(ctxt
,
16783 XML_SCHEMAP_SRC_CT_1
,
16784 WXS_BASIC_CAST type
, NULL
,
16785 "If using <simpleContent> and <restriction>, the base "
16786 "type must be a complex type. The base type '%s' is "
16788 xmlSchemaFormatQName(&str
, base
->targetNamespace
,
16791 return (XML_SCHEMAP_SRC_CT_1
);
16794 /* Base type is a complex type. */
16795 if ((base
->contentType
== XML_SCHEMA_CONTENT_SIMPLE
) ||
16796 (base
->contentType
== XML_SCHEMA_CONTENT_BASIC
)) {
16798 * 2.1.1 a complex type definition whose {content type} is a
16799 * simple type definition;
16802 if (base
->contentTypeDef
== NULL
) {
16803 xmlSchemaPCustomErr(ctxt
, XML_SCHEMAP_INTERNAL
,
16804 WXS_BASIC_CAST type
, NULL
,
16805 "Internal error: xmlSchemaCheckSRCCT, "
16806 "'%s', base type has no content type",
16810 } else if ((base
->contentType
== XML_SCHEMA_CONTENT_MIXED
) &&
16811 (WXS_IS_RESTRICTION(type
))) {
16814 * 2.1.2 only if the <restriction> alternative is also
16815 * chosen, a complex type definition whose {content type}
16816 * is mixed and a particle emptiable.
16818 if (! xmlSchemaIsParticleEmptiable(
16819 (xmlSchemaParticlePtr
) base
->subtypes
)) {
16820 ret
= XML_SCHEMAP_SRC_CT_1
;
16823 * Attention: at this point the <simpleType> child is in
16824 * ->contentTypeDef (put there during parsing).
16826 if (type
->contentTypeDef
== NULL
) {
16827 xmlChar
*str
= NULL
;
16829 * 2.2 If clause 2.1.2 above is satisfied, then there
16830 * must be a <simpleType> among the [children] of
16833 /* TODO: Change error code to ..._SRC_CT_2_2. */
16834 xmlSchemaPCustomErr(ctxt
,
16835 XML_SCHEMAP_SRC_CT_1
,
16836 WXS_BASIC_CAST type
, NULL
,
16837 "A <simpleType> is expected among the children "
16838 "of <restriction>, if <simpleContent> is used and "
16839 "the base type '%s' is a complex type",
16840 xmlSchemaFormatQName(&str
, base
->targetNamespace
,
16843 return (XML_SCHEMAP_SRC_CT_1
);
16846 ret
= XML_SCHEMAP_SRC_CT_1
;
16850 xmlChar
*str
= NULL
;
16851 if (WXS_IS_RESTRICTION(type
)) {
16852 xmlSchemaPCustomErr(ctxt
,
16853 XML_SCHEMAP_SRC_CT_1
,
16854 WXS_BASIC_CAST type
, NULL
,
16855 "If <simpleContent> and <restriction> is used, the "
16856 "base type must be a simple type or a complex type with "
16857 "mixed content and particle emptiable. The base type "
16858 "'%s' is none of those",
16859 xmlSchemaFormatQName(&str
, base
->targetNamespace
,
16862 xmlSchemaPCustomErr(ctxt
,
16863 XML_SCHEMAP_SRC_CT_1
,
16864 WXS_BASIC_CAST type
, NULL
,
16865 "If <simpleContent> and <extension> is used, the "
16866 "base type must be a simple type. The base type '%s' "
16867 "is a complex type",
16868 xmlSchemaFormatQName(&str
, base
->targetNamespace
,
16875 * SPEC (3) "The corresponding complex type definition component must
16876 * satisfy the conditions set out in Constraints on Complex Type
16877 * Definition Schema Components ($3.4.6);"
16878 * NOTE (3) will be done in xmlSchemaTypeFixup().
16881 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16882 * above for {attribute wildcard} is satisfied, the intensional
16883 * intersection must be expressible, as defined in Attribute Wildcard
16884 * Intersection ($3.10.6).
16885 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16890 #ifdef ENABLE_PARTICLE_RESTRICTION
16892 * xmlSchemaCheckParticleRangeOK:
16893 * @ctxt: the schema parser context
16894 * @type: the complex type definition
16896 * (3.9.6) Constraints on Particle Schema Components
16897 * Schema Component Constraint:
16898 * Occurrence Range OK (range-ok)
16902 * Returns 0 if the constraints are satisfied, a positive
16903 * error code if not and -1 if an internal error occurred.
16906 xmlSchemaCheckParticleRangeOK(int rmin
, int rmax
,
16907 int bmin
, int bmax
)
16911 if ((bmax
!= UNBOUNDED
) &&
16918 * xmlSchemaCheckRCaseNameAndTypeOK:
16919 * @ctxt: the schema parser context
16920 * @r: the restricting element declaration particle
16921 * @b: the base element declaration particle
16923 * (3.9.6) Constraints on Particle Schema Components
16924 * Schema Component Constraint:
16925 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16926 * (rcase-NameAndTypeOK)
16932 * Returns 0 if the constraints are satisfied, a positive
16933 * error code if not and -1 if an internal error occurred.
16936 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt
,
16937 xmlSchemaParticlePtr r
,
16938 xmlSchemaParticlePtr b
)
16940 xmlSchemaElementPtr elemR
, elemB
;
16942 /* TODO: Error codes (rcase-NameAndTypeOK). */
16943 elemR
= (xmlSchemaElementPtr
) r
->children
;
16944 elemB
= (xmlSchemaElementPtr
) b
->children
;
16946 * SPEC (1) "The declarations' {name}s and {target namespace}s are
16949 if ((elemR
!= elemB
) &&
16950 ((! xmlStrEqual(elemR
->name
, elemB
->name
)) ||
16951 (! xmlStrEqual(elemR
->targetNamespace
, elemB
->targetNamespace
))))
16954 * SPEC (2) "R's occurrence range is a valid restriction of B's
16955 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
16957 if (xmlSchemaCheckParticleRangeOK(r
->minOccurs
, r
->maxOccurs
,
16958 b
->minOccurs
, b
->maxOccurs
) != 0)
16961 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16962 * {scope} are global."
16964 if (elemR
== elemB
)
16967 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16969 if (((elemB
->flags
& XML_SCHEMAS_ELEM_NILLABLE
) == 0) &&
16970 (elemR
->flags
& XML_SCHEMAS_ELEM_NILLABLE
))
16973 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16974 * or is not fixed, or R's declaration's {value constraint} is fixed
16975 * with the same value."
16977 if ((elemB
->value
!= NULL
) && (elemB
->flags
& XML_SCHEMAS_ELEM_FIXED
) &&
16978 ((elemR
->value
== NULL
) ||
16979 ((elemR
->flags
& XML_SCHEMAS_ELEM_FIXED
) == 0) ||
16980 /* TODO: Equality of the initial value or normalized or canonical? */
16981 (! xmlStrEqual(elemR
->value
, elemB
->value
))))
16984 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16985 * definitions} is a subset of B's declaration's {identity-constraint
16986 * definitions}, if any."
16988 if (elemB
->idcs
!= NULL
) {
16992 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16993 * superset of B's declaration's {disallowed substitutions}."
16995 if (((elemB
->flags
& XML_SCHEMAS_ELEM_BLOCK_EXTENSION
) &&
16996 ((elemR
->flags
& XML_SCHEMAS_ELEM_BLOCK_EXTENSION
) == 0)) ||
16997 ((elemB
->flags
& XML_SCHEMAS_ELEM_BLOCK_RESTRICTION
) &&
16998 ((elemR
->flags
& XML_SCHEMAS_ELEM_BLOCK_RESTRICTION
) == 0)) ||
16999 ((elemB
->flags
& XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION
) &&
17000 ((elemR
->flags
& XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION
) == 0)))
17003 * SPEC (3.2.5) "R's {type definition} is validly derived given
17004 * {extension, list, union} from B's {type definition}"
17006 * BADSPEC TODO: What's the point of adding "list" and "union" to the
17007 * set, if the corresponding constraints handle "restriction" and
17008 * "extension" only?
17014 set
|= SUBSET_EXTENSION
;
17015 set
|= SUBSET_LIST
;
17016 set
|= SUBSET_UNION
;
17017 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt
, elemR
->subtypes
,
17018 elemB
->subtypes
, set
) != 0)
17025 * xmlSchemaCheckRCaseNSCompat:
17026 * @ctxt: the schema parser context
17027 * @r: the restricting element declaration particle
17028 * @b: the base wildcard particle
17030 * (3.9.6) Constraints on Particle Schema Components
17031 * Schema Component Constraint:
17032 * Particle Derivation OK (Elt:Any -- NSCompat)
17037 * Returns 0 if the constraints are satisfied, a positive
17038 * error code if not and -1 if an internal error occurred.
17041 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt
,
17042 xmlSchemaParticlePtr r
,
17043 xmlSchemaParticlePtr b
)
17045 /* TODO:Error codes (rcase-NSCompat). */
17047 * SPEC "For an element declaration particle to be a `valid restriction`
17048 * of a wildcard particle all of the following must be true:"
17050 * SPEC (1) "The element declaration's {target namespace} is `valid`
17051 * with respect to the wildcard's {namespace constraint} as defined by
17052 * Wildcard allows Namespace Name ($3.10.4)."
17054 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr
) b
->children
,
17055 ((xmlSchemaElementPtr
) r
->children
)->targetNamespace
) != 0)
17058 * SPEC (2) "R's occurrence range is a valid restriction of B's
17059 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17061 if (xmlSchemaCheckParticleRangeOK(r
->minOccurs
, r
->maxOccurs
,
17062 b
->minOccurs
, b
->maxOccurs
) != 0)
17069 * xmlSchemaCheckRCaseRecurseAsIfGroup:
17070 * @ctxt: the schema parser context
17071 * @r: the restricting element declaration particle
17072 * @b: the base model group particle
17074 * (3.9.6) Constraints on Particle Schema Components
17075 * Schema Component Constraint:
17076 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
17077 * (rcase-RecurseAsIfGroup)
17081 * Returns 0 if the constraints are satisfied, a positive
17082 * error code if not and -1 if an internal error occurred.
17085 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt
,
17086 xmlSchemaParticlePtr r
,
17087 xmlSchemaParticlePtr b
)
17089 /* TODO: Error codes (rcase-RecurseAsIfGroup). */
17095 * xmlSchemaCheckRCaseNSSubset:
17096 * @ctxt: the schema parser context
17097 * @r: the restricting wildcard particle
17098 * @b: the base wildcard particle
17100 * (3.9.6) Constraints on Particle Schema Components
17101 * Schema Component Constraint:
17102 * Particle Derivation OK (Any:Any -- NSSubset)
17107 * Returns 0 if the constraints are satisfied, a positive
17108 * error code if not and -1 if an internal error occurred.
17111 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt
,
17112 xmlSchemaParticlePtr r
,
17113 xmlSchemaParticlePtr b
,
17116 /* TODO: Error codes (rcase-NSSubset). */
17118 * SPEC (1) "R's occurrence range is a valid restriction of B's
17119 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17121 if (xmlSchemaCheckParticleRangeOK(r
->minOccurs
, r
->maxOccurs
,
17122 b
->minOccurs
, b
->maxOccurs
))
17125 * SPEC (2) "R's {namespace constraint} must be an intensional subset
17126 * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
17128 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr
) r
->children
,
17129 (xmlSchemaWildcardPtr
) b
->children
))
17132 * SPEC (3) "Unless B is the content model wildcard of the `ur-type
17133 * definition`, R's {process contents} must be identical to or stronger
17134 * than B's {process contents}, where strict is stronger than lax is
17135 * stronger than skip."
17137 if (! isAnyTypeBase
) {
17138 if ( ((xmlSchemaWildcardPtr
) r
->children
)->processContents
<
17139 ((xmlSchemaWildcardPtr
) b
->children
)->processContents
)
17147 * xmlSchemaCheckCOSParticleRestrict:
17148 * @ctxt: the schema parser context
17149 * @type: the complex type definition
17151 * (3.9.6) Constraints on Particle Schema Components
17152 * Schema Component Constraint:
17153 * Particle Valid (Restriction) (cos-particle-restrict)
17157 * Returns 0 if the constraints are satisfied, a positive
17158 * error code if not and -1 if an internal error occurred.
17161 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt
,
17162 xmlSchemaParticlePtr r
,
17163 xmlSchemaParticlePtr b
)
17167 /*part = WXS_TYPE_PARTICLE(type);
17168 basePart = WXS_TYPE_PARTICLE(base);
17174 * SPEC (1) "They are the same particle."
17185 * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
17186 * @ctxt: the schema parser context
17187 * @r: the model group particle
17188 * @b: the base wildcard particle
17190 * (3.9.6) Constraints on Particle Schema Components
17191 * Schema Component Constraint:
17192 * Particle Derivation OK (All/Choice/Sequence:Any --
17193 * NSRecurseCheckCardinality)
17194 * (rcase-NSRecurseCheckCardinality)
17196 * STATUS: TODO: subst-groups
17198 * Returns 0 if the constraints are satisfied, a positive
17199 * error code if not and -1 if an internal error occurred.
17202 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt
,
17203 xmlSchemaParticlePtr r
,
17204 xmlSchemaParticlePtr b
)
17206 xmlSchemaParticlePtr part
;
17207 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17208 if ((r
->children
== NULL
) || (r
->children
->children
== NULL
))
17211 * SPEC "For a group particle to be a `valid restriction` of a
17212 * wildcard particle..."
17214 * SPEC (1) "Every member of the {particles} of the group is a `valid
17215 * restriction` of the wildcard as defined by
17216 * Particle Valid (Restriction) ($3.9.6)."
17218 part
= (xmlSchemaParticlePtr
) r
->children
->children
;
17220 if (xmlSchemaCheckCOSParticleRestrict(ctxt
, part
, b
))
17222 part
= (xmlSchemaParticlePtr
) part
->next
;
17223 } while (part
!= NULL
);
17225 * SPEC (2) "The effective total range of the group [...] is a
17226 * valid restriction of B's occurrence range as defined by
17227 * Occurrence Range OK ($3.9.6)."
17229 if (xmlSchemaCheckParticleRangeOK(
17230 xmlSchemaGetParticleTotalRangeMin(r
),
17231 xmlSchemaGetParticleTotalRangeMax(r
),
17232 b
->minOccurs
, b
->maxOccurs
) != 0)
17239 * xmlSchemaCheckRCaseRecurse:
17240 * @ctxt: the schema parser context
17241 * @r: the <all> or <sequence> model group particle
17242 * @b: the base <all> or <sequence> model group particle
17244 * (3.9.6) Constraints on Particle Schema Components
17245 * Schema Component Constraint:
17246 * Particle Derivation OK (All:All,Sequence:Sequence --
17251 * TODO: subst-groups
17253 * Returns 0 if the constraints are satisfied, a positive
17254 * error code if not and -1 if an internal error occurred.
17257 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt
,
17258 xmlSchemaParticlePtr r
,
17259 xmlSchemaParticlePtr b
)
17261 /* xmlSchemaParticlePtr part; */
17262 /* TODO: Error codes (rcase-Recurse). */
17263 if ((r
->children
== NULL
) || (b
->children
== NULL
) ||
17264 (r
->children
->type
!= b
->children
->type
))
17267 * SPEC "For an all or sequence group particle to be a `valid
17268 * restriction` of another group particle with the same {compositor}..."
17270 * SPEC (1) "R's occurrence range is a valid restriction of B's
17271 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
17273 if (xmlSchemaCheckParticleRangeOK(r
->minOccurs
, r
->maxOccurs
,
17274 b
->minOccurs
, b
->maxOccurs
))
17283 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17284 xmlSchemaPCustomErrExt(pctxt, \
17285 XML_SCHEMAP_INVALID_FACET_VALUE, \
17286 WXS_BASIC_CAST fac1, fac1->node, \
17287 "It is an error for both '%s' and '%s' to be specified on the "\
17288 "same type definition", \
17289 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17290 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17292 #define FACET_RESTR_ERR(fac1, msg) \
17293 xmlSchemaPCustomErr(pctxt, \
17294 XML_SCHEMAP_INVALID_FACET_VALUE, \
17295 WXS_BASIC_CAST fac1, fac1->node, \
17298 #define FACET_RESTR_FIXED_ERR(fac) \
17299 xmlSchemaPCustomErr(pctxt, \
17300 XML_SCHEMAP_INVALID_FACET_VALUE, \
17301 WXS_BASIC_CAST fac, fac->node, \
17302 "The base type's facet is 'fixed', thus the value must not " \
17306 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt
,
17307 xmlSchemaFacetPtr facet1
,
17308 xmlSchemaFacetPtr facet2
,
17313 xmlChar
*msg
= NULL
;
17315 msg
= xmlStrdup(BAD_CAST
"'");
17316 msg
= xmlStrcat(msg
, xmlSchemaFacetTypeToString(facet1
->type
));
17317 msg
= xmlStrcat(msg
, BAD_CAST
"' has to be");
17318 if (lessGreater
== 0)
17319 msg
= xmlStrcat(msg
, BAD_CAST
" equal to");
17320 if (lessGreater
== 1)
17321 msg
= xmlStrcat(msg
, BAD_CAST
" greater than");
17323 msg
= xmlStrcat(msg
, BAD_CAST
" less than");
17326 msg
= xmlStrcat(msg
, BAD_CAST
" or equal to");
17327 msg
= xmlStrcat(msg
, BAD_CAST
" '");
17328 msg
= xmlStrcat(msg
, xmlSchemaFacetTypeToString(facet2
->type
));
17330 msg
= xmlStrcat(msg
, BAD_CAST
"' of the base type");
17332 msg
= xmlStrcat(msg
, BAD_CAST
"'");
17334 xmlSchemaPCustomErr(pctxt
,
17335 XML_SCHEMAP_INVALID_FACET_VALUE
,
17336 WXS_BASIC_CAST facet1
, NULL
,
17337 (const char *) msg
, NULL
);
17344 * xmlSchemaDeriveAndValidateFacets:
17346 * Schema Component Constraint: Simple Type Restriction (Facets)
17347 * (st-restrict-facets)
17350 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt
,
17351 xmlSchemaTypePtr type
)
17353 xmlSchemaTypePtr base
= type
->baseType
;
17354 xmlSchemaFacetLinkPtr link
, cur
, last
= NULL
;
17355 xmlSchemaFacetPtr facet
, bfacet
,
17356 flength
= NULL
, ftotdig
= NULL
, ffracdig
= NULL
,
17357 fmaxlen
= NULL
, fminlen
= NULL
, /* facets of the current type */
17358 fmininc
= NULL
, fmaxinc
= NULL
,
17359 fminexc
= NULL
, fmaxexc
= NULL
,
17360 bflength
= NULL
, bftotdig
= NULL
, bffracdig
= NULL
,
17361 bfmaxlen
= NULL
, bfminlen
= NULL
, /* facets of the base type */
17362 bfmininc
= NULL
, bfmaxinc
= NULL
,
17363 bfminexc
= NULL
, bfmaxexc
= NULL
;
17364 int res
; /* err = 0, fixedErr; */
17367 * SPEC st-restrict-facets 1:
17368 * "The {variety} of R is the same as that of B."
17371 * SPEC st-restrict-facets 2:
17372 * "If {variety} is atomic, the {primitive type definition}
17373 * of R is the same as that of B."
17375 * NOTE: we leave 1 & 2 out for now, since this will be
17376 * satisfied by the derivation process.
17377 * CONSTRUCTION TODO: Maybe needed if using a construction API.
17380 * SPEC st-restrict-facets 3:
17381 * "The {facets} of R are the union of S and the {facets}
17382 * of B, eliminating duplicates. To eliminate duplicates,
17383 * when a facet of the same kind occurs in both S and the
17384 * {facets} of B, the one in the {facets} of B is not
17385 * included, with the exception of enumeration and pattern
17386 * facets, for which multiple occurrences with distinct values
17390 if ((type
->facetSet
== NULL
) && (base
->facetSet
== NULL
))
17393 last
= type
->facetSet
;
17395 while (last
->next
!= NULL
)
17398 for (cur
= type
->facetSet
; cur
!= NULL
; cur
= cur
->next
) {
17399 facet
= cur
->facet
;
17400 switch (facet
->type
) {
17401 case XML_SCHEMA_FACET_LENGTH
:
17402 flength
= facet
; break;
17403 case XML_SCHEMA_FACET_MINLENGTH
:
17404 fminlen
= facet
; break;
17405 case XML_SCHEMA_FACET_MININCLUSIVE
:
17406 fmininc
= facet
; break;
17407 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
17408 fminexc
= facet
; break;
17409 case XML_SCHEMA_FACET_MAXLENGTH
:
17410 fmaxlen
= facet
; break;
17411 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
17412 fmaxinc
= facet
; break;
17413 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
17414 fmaxexc
= facet
; break;
17415 case XML_SCHEMA_FACET_TOTALDIGITS
:
17416 ftotdig
= facet
; break;
17417 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
17418 ffracdig
= facet
; break;
17423 for (cur
= base
->facetSet
; cur
!= NULL
; cur
= cur
->next
) {
17424 facet
= cur
->facet
;
17425 switch (facet
->type
) {
17426 case XML_SCHEMA_FACET_LENGTH
:
17427 bflength
= facet
; break;
17428 case XML_SCHEMA_FACET_MINLENGTH
:
17429 bfminlen
= facet
; break;
17430 case XML_SCHEMA_FACET_MININCLUSIVE
:
17431 bfmininc
= facet
; break;
17432 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
17433 bfminexc
= facet
; break;
17434 case XML_SCHEMA_FACET_MAXLENGTH
:
17435 bfmaxlen
= facet
; break;
17436 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
17437 bfmaxinc
= facet
; break;
17438 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
17439 bfmaxexc
= facet
; break;
17440 case XML_SCHEMA_FACET_TOTALDIGITS
:
17441 bftotdig
= facet
; break;
17442 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
17443 bffracdig
= facet
; break;
17449 * length and minLength or maxLength (2.2) + (3.2)
17451 if (flength
&& (fminlen
|| fmaxlen
)) {
17452 FACET_RESTR_ERR(flength
, "It is an error for both 'length' and "
17453 "either of 'minLength' or 'maxLength' to be specified on "
17454 "the same type definition")
17457 * Mutual exclusions in the same derivation step.
17459 if ((fmaxinc
) && (fmaxexc
)) {
17461 * SCC "maxInclusive and maxExclusive"
17463 FACET_RESTR_MUTUAL_ERR(fmaxinc
, fmaxexc
)
17465 if ((fmininc
) && (fminexc
)) {
17467 * SCC "minInclusive and minExclusive"
17469 FACET_RESTR_MUTUAL_ERR(fmininc
, fminexc
)
17472 if (flength
&& bflength
) {
17474 * SCC "length valid restriction"
17475 * The values have to be equal.
17477 res
= xmlSchemaCompareValues(flength
->val
, bflength
->val
);
17479 goto internal_error
;
17481 xmlSchemaDeriveFacetErr(pctxt
, flength
, bflength
, 0, 0, 1);
17482 if ((res
!= 0) && (bflength
->fixed
)) {
17483 FACET_RESTR_FIXED_ERR(flength
)
17487 if (fminlen
&& bfminlen
) {
17489 * SCC "minLength valid restriction"
17490 * minLength >= BASE minLength
17492 res
= xmlSchemaCompareValues(fminlen
->val
, bfminlen
->val
);
17494 goto internal_error
;
17496 xmlSchemaDeriveFacetErr(pctxt
, fminlen
, bfminlen
, 1, 1, 1);
17497 if ((res
!= 0) && (bfminlen
->fixed
)) {
17498 FACET_RESTR_FIXED_ERR(fminlen
)
17501 if (fmaxlen
&& bfmaxlen
) {
17503 * SCC "maxLength valid restriction"
17504 * maxLength <= BASE minLength
17506 res
= xmlSchemaCompareValues(fmaxlen
->val
, bfmaxlen
->val
);
17508 goto internal_error
;
17510 xmlSchemaDeriveFacetErr(pctxt
, fmaxlen
, bfmaxlen
, -1, 1, 1);
17511 if ((res
!= 0) && (bfmaxlen
->fixed
)) {
17512 FACET_RESTR_FIXED_ERR(fmaxlen
)
17516 * SCC "length and minLength or maxLength"
17519 flength
= bflength
;
17522 fminlen
= bfminlen
;
17524 /* (1.1) length >= minLength */
17525 res
= xmlSchemaCompareValues(flength
->val
, fminlen
->val
);
17527 goto internal_error
;
17529 xmlSchemaDeriveFacetErr(pctxt
, flength
, fminlen
, 1, 1, 0);
17532 fmaxlen
= bfmaxlen
;
17534 /* (2.1) length <= maxLength */
17535 res
= xmlSchemaCompareValues(flength
->val
, fmaxlen
->val
);
17537 goto internal_error
;
17539 xmlSchemaDeriveFacetErr(pctxt
, flength
, fmaxlen
, -1, 1, 0);
17547 /* SCC "maxInclusive >= minInclusive" */
17548 res
= xmlSchemaCompareValues(fmaxinc
->val
, fmininc
->val
);
17550 goto internal_error
;
17552 xmlSchemaDeriveFacetErr(pctxt
, fmaxinc
, fmininc
, 1, 1, 0);
17556 * SCC "maxInclusive valid restriction"
17559 /* maxInclusive <= BASE maxInclusive */
17560 res
= xmlSchemaCompareValues(fmaxinc
->val
, bfmaxinc
->val
);
17562 goto internal_error
;
17564 xmlSchemaDeriveFacetErr(pctxt
, fmaxinc
, bfmaxinc
, -1, 1, 1);
17565 if ((res
!= 0) && (bfmaxinc
->fixed
)) {
17566 FACET_RESTR_FIXED_ERR(fmaxinc
)
17570 /* maxInclusive < BASE maxExclusive */
17571 res
= xmlSchemaCompareValues(fmaxinc
->val
, bfmaxexc
->val
);
17573 goto internal_error
;
17575 xmlSchemaDeriveFacetErr(pctxt
, fmaxinc
, bfmaxexc
, -1, 0, 1);
17579 /* maxInclusive >= BASE minInclusive */
17580 res
= xmlSchemaCompareValues(fmaxinc
->val
, bfmininc
->val
);
17582 goto internal_error
;
17584 xmlSchemaDeriveFacetErr(pctxt
, fmaxinc
, bfmininc
, 1, 1, 1);
17588 /* maxInclusive > BASE minExclusive */
17589 res
= xmlSchemaCompareValues(fmaxinc
->val
, bfminexc
->val
);
17591 goto internal_error
;
17593 xmlSchemaDeriveFacetErr(pctxt
, fmaxinc
, bfminexc
, 1, 0, 1);
17599 * "maxExclusive >= minExclusive"
17602 res
= xmlSchemaCompareValues(fmaxexc
->val
, fminexc
->val
);
17604 goto internal_error
;
17606 xmlSchemaDeriveFacetErr(pctxt
, fmaxexc
, fminexc
, 1, 1, 0);
17610 * "maxExclusive valid restriction"
17613 /* maxExclusive <= BASE maxExclusive */
17614 res
= xmlSchemaCompareValues(fmaxexc
->val
, bfmaxexc
->val
);
17616 goto internal_error
;
17618 xmlSchemaDeriveFacetErr(pctxt
, fmaxexc
, bfmaxexc
, -1, 1, 1);
17620 if ((res
!= 0) && (bfmaxexc
->fixed
)) {
17621 FACET_RESTR_FIXED_ERR(fmaxexc
)
17625 /* maxExclusive <= BASE maxInclusive */
17626 res
= xmlSchemaCompareValues(fmaxexc
->val
, bfmaxinc
->val
);
17628 goto internal_error
;
17630 xmlSchemaDeriveFacetErr(pctxt
, fmaxexc
, bfmaxinc
, -1, 1, 1);
17634 /* maxExclusive > BASE minInclusive */
17635 res
= xmlSchemaCompareValues(fmaxexc
->val
, bfmininc
->val
);
17637 goto internal_error
;
17639 xmlSchemaDeriveFacetErr(pctxt
, fmaxexc
, bfmininc
, 1, 0, 1);
17643 /* maxExclusive > BASE minExclusive */
17644 res
= xmlSchemaCompareValues(fmaxexc
->val
, bfminexc
->val
);
17646 goto internal_error
;
17648 xmlSchemaDeriveFacetErr(pctxt
, fmaxexc
, bfminexc
, 1, 0, 1);
17654 * "minExclusive < maxInclusive"
17657 res
= xmlSchemaCompareValues(fminexc
->val
, fmaxinc
->val
);
17659 goto internal_error
;
17661 xmlSchemaDeriveFacetErr(pctxt
, fminexc
, fmaxinc
, -1, 0, 0);
17665 * "minExclusive valid restriction"
17668 /* minExclusive >= BASE minExclusive */
17669 res
= xmlSchemaCompareValues(fminexc
->val
, bfminexc
->val
);
17671 goto internal_error
;
17673 xmlSchemaDeriveFacetErr(pctxt
, fminexc
, bfminexc
, 1, 1, 1);
17675 if ((res
!= 0) && (bfminexc
->fixed
)) {
17676 FACET_RESTR_FIXED_ERR(fminexc
)
17680 /* minExclusive <= BASE maxInclusive */
17681 res
= xmlSchemaCompareValues(fminexc
->val
, bfmaxinc
->val
);
17683 goto internal_error
;
17685 xmlSchemaDeriveFacetErr(pctxt
, fminexc
, bfmaxinc
, -1, 1, 1);
17689 /* minExclusive >= BASE minInclusive */
17690 res
= xmlSchemaCompareValues(fminexc
->val
, bfmininc
->val
);
17692 goto internal_error
;
17694 xmlSchemaDeriveFacetErr(pctxt
, fminexc
, bfmininc
, 1, 1, 1);
17698 /* minExclusive < BASE maxExclusive */
17699 res
= xmlSchemaCompareValues(fminexc
->val
, bfmaxexc
->val
);
17701 goto internal_error
;
17703 xmlSchemaDeriveFacetErr(pctxt
, fminexc
, bfmaxexc
, -1, 0, 1);
17709 * "minInclusive < maxExclusive"
17712 res
= xmlSchemaCompareValues(fmininc
->val
, fmaxexc
->val
);
17714 goto internal_error
;
17716 xmlSchemaDeriveFacetErr(pctxt
, fmininc
, fmaxexc
, -1, 0, 0);
17720 * "minExclusive valid restriction"
17723 /* minInclusive >= BASE minInclusive */
17724 res
= xmlSchemaCompareValues(fmininc
->val
, bfmininc
->val
);
17726 goto internal_error
;
17728 xmlSchemaDeriveFacetErr(pctxt
, fmininc
, bfmininc
, 1, 1, 1);
17730 if ((res
!= 0) && (bfmininc
->fixed
)) {
17731 FACET_RESTR_FIXED_ERR(fmininc
)
17735 /* minInclusive <= BASE maxInclusive */
17736 res
= xmlSchemaCompareValues(fmininc
->val
, bfmaxinc
->val
);
17738 goto internal_error
;
17740 xmlSchemaDeriveFacetErr(pctxt
, fmininc
, bfmaxinc
, -1, 1, 1);
17744 /* minInclusive > BASE minExclusive */
17745 res
= xmlSchemaCompareValues(fmininc
->val
, bfminexc
->val
);
17747 goto internal_error
;
17749 xmlSchemaDeriveFacetErr(pctxt
, fmininc
, bfminexc
, 1, 0, 1);
17752 /* minInclusive < BASE maxExclusive */
17753 res
= xmlSchemaCompareValues(fmininc
->val
, bfmaxexc
->val
);
17755 goto internal_error
;
17757 xmlSchemaDeriveFacetErr(pctxt
, fmininc
, bfmaxexc
, -1, 0, 1);
17760 if (ftotdig
&& bftotdig
) {
17762 * SCC " totalDigits valid restriction"
17763 * totalDigits <= BASE totalDigits
17765 res
= xmlSchemaCompareValues(ftotdig
->val
, bftotdig
->val
);
17767 goto internal_error
;
17769 xmlSchemaDeriveFacetErr(pctxt
, ftotdig
, bftotdig
,
17771 if ((res
!= 0) && (bftotdig
->fixed
)) {
17772 FACET_RESTR_FIXED_ERR(ftotdig
)
17775 if (ffracdig
&& bffracdig
) {
17777 * SCC "fractionDigits valid restriction"
17778 * fractionDigits <= BASE fractionDigits
17780 res
= xmlSchemaCompareValues(ffracdig
->val
, bffracdig
->val
);
17782 goto internal_error
;
17784 xmlSchemaDeriveFacetErr(pctxt
, ffracdig
, bffracdig
,
17786 if ((res
!= 0) && (bffracdig
->fixed
)) {
17787 FACET_RESTR_FIXED_ERR(ffracdig
)
17791 * SCC "fractionDigits less than or equal to totalDigits"
17794 ftotdig
= bftotdig
;
17796 ffracdig
= bffracdig
;
17797 if (ftotdig
&& ffracdig
) {
17798 res
= xmlSchemaCompareValues(ffracdig
->val
, ftotdig
->val
);
17800 goto internal_error
;
17802 xmlSchemaDeriveFacetErr(pctxt
, ffracdig
, ftotdig
,
17806 * *Enumerations* won' be added here, since only the first set
17807 * of enumerations in the ancestor-or-self axis is used
17808 * for validation, plus we need to use the base type of those
17809 * enumerations for whitespace.
17811 * *Patterns*: won't be add here, since they are ORed at
17812 * type level and ANDed at ancestor level. This will
17813 * happen during validation by walking the base axis
17816 for (cur
= base
->facetSet
; cur
!= NULL
; cur
= cur
->next
) {
17817 bfacet
= cur
->facet
;
17819 * Special handling of enumerations and patterns.
17820 * TODO: hmm, they should not appear in the set, so remove this.
17822 if ((bfacet
->type
== XML_SCHEMA_FACET_PATTERN
) ||
17823 (bfacet
->type
== XML_SCHEMA_FACET_ENUMERATION
))
17826 * Search for a duplicate facet in the current type.
17828 link
= type
->facetSet
;
17830 /* fixedErr = 0; */
17831 while (link
!= NULL
) {
17832 facet
= link
->facet
;
17833 if (facet
->type
== bfacet
->type
) {
17834 switch (facet
->type
) {
17835 case XML_SCHEMA_FACET_WHITESPACE
:
17837 * The whitespace must be stronger.
17839 if (facet
->whitespace
< bfacet
->whitespace
) {
17840 FACET_RESTR_ERR(facet
,
17841 "The 'whitespace' value has to be equal to "
17842 "or stronger than the 'whitespace' value of "
17845 if ((bfacet
->fixed
) &&
17846 (facet
->whitespace
!= bfacet
->whitespace
)) {
17847 FACET_RESTR_FIXED_ERR(facet
)
17853 /* Duplicate found. */
17859 * If no duplicate was found: add the base types's facet
17862 if (link
== NULL
) {
17863 link
= (xmlSchemaFacetLinkPtr
)
17864 xmlMalloc(sizeof(xmlSchemaFacetLink
));
17865 if (link
== NULL
) {
17866 xmlSchemaPErrMemory(pctxt
,
17867 "deriving facets, creating a facet link", NULL
);
17870 link
->facet
= cur
->facet
;
17873 type
->facetSet
= link
;
17883 PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17884 "an error occurred");
17889 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt
,
17890 xmlSchemaTypePtr type
)
17892 xmlSchemaTypeLinkPtr link
, lastLink
, prevLink
, subLink
, newLink
;
17894 * The actual value is then formed by replacing any union type
17895 * definition in the `explicit members` with the members of their
17896 * {member type definitions}, in order.
17898 * TODO: There's a bug entry at
17899 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17900 * which indicates that we'll keep the union types the future.
17902 link
= type
->memberTypes
;
17903 while (link
!= NULL
) {
17905 if (WXS_IS_TYPE_NOT_FIXED(link
->type
))
17906 xmlSchemaTypeFixup(link
->type
, ACTXT_CAST pctxt
);
17908 if (WXS_IS_UNION(link
->type
)) {
17909 subLink
= xmlSchemaGetUnionSimpleTypeMemberTypes(link
->type
);
17910 if (subLink
!= NULL
) {
17911 link
->type
= subLink
->type
;
17912 if (subLink
->next
!= NULL
) {
17913 lastLink
= link
->next
;
17914 subLink
= subLink
->next
;
17916 while (subLink
!= NULL
) {
17917 newLink
= (xmlSchemaTypeLinkPtr
)
17918 xmlMalloc(sizeof(xmlSchemaTypeLink
));
17919 if (newLink
== NULL
) {
17920 xmlSchemaPErrMemory(pctxt
, "allocating a type link",
17924 newLink
->type
= subLink
->type
;
17925 prevLink
->next
= newLink
;
17926 prevLink
= newLink
;
17927 newLink
->next
= lastLink
;
17929 subLink
= subLink
->next
;
17940 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type
)
17942 int has
= 0, needVal
= 0, normVal
= 0;
17944 has
= (type
->baseType
->flags
& XML_SCHEMAS_TYPE_HAS_FACETS
) ? 1 : 0;
17946 needVal
= (type
->baseType
->flags
&
17947 XML_SCHEMAS_TYPE_FACETSNEEDVALUE
) ? 1 : 0;
17948 normVal
= (type
->baseType
->flags
&
17949 XML_SCHEMAS_TYPE_NORMVALUENEEDED
) ? 1 : 0;
17951 if (type
->facets
!= NULL
) {
17952 xmlSchemaFacetPtr fac
;
17954 for (fac
= type
->facets
; fac
!= NULL
; fac
= fac
->next
) {
17955 switch (fac
->type
) {
17956 case XML_SCHEMA_FACET_WHITESPACE
:
17958 case XML_SCHEMA_FACET_PATTERN
:
17962 case XML_SCHEMA_FACET_ENUMERATION
:
17974 type
->flags
|= XML_SCHEMAS_TYPE_NORMVALUENEEDED
;
17976 type
->flags
|= XML_SCHEMAS_TYPE_FACETSNEEDVALUE
;
17978 type
->flags
|= XML_SCHEMAS_TYPE_HAS_FACETS
;
17980 if (has
&& (! needVal
) && WXS_IS_ATOMIC(type
)) {
17981 xmlSchemaTypePtr prim
= xmlSchemaGetPrimitiveType(type
);
17983 * OPTIMIZE VAL TODO: Some facets need a computed value.
17985 if ((prim
->builtInType
!= XML_SCHEMAS_ANYSIMPLETYPE
) &&
17986 (prim
->builtInType
!= XML_SCHEMAS_STRING
)) {
17987 type
->flags
|= XML_SCHEMAS_TYPE_FACETSNEEDVALUE
;
17993 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type
)
17998 * Evaluate the whitespace-facet value.
18000 if (WXS_IS_LIST(type
)) {
18001 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE
;
18003 } else if (WXS_IS_UNION(type
))
18006 if (type
->facetSet
!= NULL
) {
18007 xmlSchemaFacetLinkPtr lin
;
18009 for (lin
= type
->facetSet
; lin
!= NULL
; lin
= lin
->next
) {
18010 if (lin
->facet
->type
== XML_SCHEMA_FACET_WHITESPACE
) {
18011 switch (lin
->facet
->whitespace
) {
18012 case XML_SCHEMAS_FACET_PRESERVE
:
18013 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE
;
18015 case XML_SCHEMAS_FACET_REPLACE
:
18016 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE
;
18018 case XML_SCHEMAS_FACET_COLLAPSE
:
18019 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE
;
18029 * For all `atomic` datatypes other than string (and types `derived`
18030 * by `restriction` from it) the value of whiteSpace is fixed to
18034 xmlSchemaTypePtr anc
;
18036 for (anc
= type
->baseType
; anc
!= NULL
&&
18037 anc
->builtInType
!= XML_SCHEMAS_ANYTYPE
;
18038 anc
= anc
->baseType
) {
18040 if (anc
->type
== XML_SCHEMA_TYPE_BASIC
) {
18041 if (anc
->builtInType
== XML_SCHEMAS_NORMSTRING
) {
18042 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE
;
18044 } else if ((anc
->builtInType
== XML_SCHEMAS_STRING
) ||
18045 (anc
->builtInType
== XML_SCHEMAS_ANYSIMPLETYPE
)) {
18046 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE
;
18049 type
->flags
|= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE
;
18058 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt
,
18059 xmlSchemaTypePtr type
)
18061 if (type
->type
!= XML_SCHEMA_TYPE_SIMPLE
)
18063 if (! WXS_IS_TYPE_NOT_FIXED_1(type
))
18065 type
->flags
|= XML_SCHEMAS_TYPE_FIXUP_1
;
18067 if (WXS_IS_LIST(type
)) {
18069 * Corresponds to <simpleType><list>...
18071 if (type
->subtypes
== NULL
) {
18073 * This one is really needed, so get out.
18075 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18076 "list type has no item-type assigned");
18079 } else if (WXS_IS_UNION(type
)) {
18081 * Corresponds to <simpleType><union>...
18083 if (type
->memberTypes
== NULL
) {
18085 * This one is really needed, so get out.
18087 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18088 "union type has no member-types assigned");
18093 * Corresponds to <simpleType><restriction>...
18095 if (type
->baseType
== NULL
) {
18096 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
18097 "type has no base-type assigned");
18100 if (WXS_IS_TYPE_NOT_FIXED_1(type
->baseType
))
18101 if (xmlSchemaFixupSimpleTypeStageOne(pctxt
, type
->baseType
) == -1)
18105 * If the <restriction> alternative is chosen, then the
18106 * {variety} of the {base type definition}.
18108 if (WXS_IS_ATOMIC(type
->baseType
))
18109 type
->flags
|= XML_SCHEMAS_TYPE_VARIETY_ATOMIC
;
18110 else if (WXS_IS_LIST(type
->baseType
)) {
18111 type
->flags
|= XML_SCHEMAS_TYPE_VARIETY_LIST
;
18113 * Inherit the itemType.
18115 type
->subtypes
= type
->baseType
->subtypes
;
18116 } else if (WXS_IS_UNION(type
->baseType
)) {
18117 type
->flags
|= XML_SCHEMAS_TYPE_VARIETY_UNION
;
18119 * NOTE that we won't assign the memberTypes of the base,
18120 * since this will make trouble when freeing them; we will
18121 * use a lookup function to access them instead.
18130 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt
,
18131 xmlSchemaTypePtr type
)
18133 if (type
->node
!= NULL
) {
18134 xmlGenericError(xmlGenericErrorContext
,
18135 "Type of %s : %s:%d :", name
,
18136 type
->node
->doc
->URL
,
18137 xmlGetLineNo(type
->node
));
18139 xmlGenericError(xmlGenericErrorContext
, "Type of %s :", name
);
18141 if ((WXS_IS_SIMPLE(type
)) || (WXS_IS_COMPLEX(type
))) {
18142 switch (type
->contentType
) {
18143 case XML_SCHEMA_CONTENT_SIMPLE
:
18144 xmlGenericError(xmlGenericErrorContext
, "simple\n");
18146 case XML_SCHEMA_CONTENT_ELEMENTS
:
18147 xmlGenericError(xmlGenericErrorContext
, "elements\n");
18149 case XML_SCHEMA_CONTENT_UNKNOWN
:
18150 xmlGenericError(xmlGenericErrorContext
, "unknown !!!\n");
18152 case XML_SCHEMA_CONTENT_EMPTY
:
18153 xmlGenericError(xmlGenericErrorContext
, "empty\n");
18155 case XML_SCHEMA_CONTENT_MIXED
:
18156 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr
)
18158 xmlGenericError(xmlGenericErrorContext
,
18159 "mixed as emptiable particle\n");
18161 xmlGenericError(xmlGenericErrorContext
, "mixed\n");
18163 /* Removed, since not used. */
18165 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
18166 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
18169 case XML_SCHEMA_CONTENT_BASIC
:
18170 xmlGenericError(xmlGenericErrorContext
, "basic\n");
18173 xmlGenericError(xmlGenericErrorContext
,
18174 "not registered !!!\n");
18182 * 3.14.6 Constraints on Simple Type Definition Schema Components
18185 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt
,
18186 xmlSchemaTypePtr type
)
18188 int res
, olderrs
= pctxt
->nberrors
;
18190 if (type
->type
!= XML_SCHEMA_TYPE_SIMPLE
)
18193 if (! WXS_IS_TYPE_NOT_FIXED(type
))
18196 type
->flags
|= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED
;
18197 type
->contentType
= XML_SCHEMA_CONTENT_SIMPLE
;
18199 if (type
->baseType
== NULL
) {
18200 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
18201 "missing baseType");
18204 if (WXS_IS_TYPE_NOT_FIXED(type
->baseType
))
18205 xmlSchemaTypeFixup(type
->baseType
, ACTXT_CAST pctxt
);
18207 * If a member type of a union is a union itself, we need to substitute
18208 * that member type for its member types.
18209 * NOTE that this might change in WXS 1.1; i.e. we will keep the union
18210 * types in WXS 1.1.
18212 if ((type
->memberTypes
!= NULL
) &&
18213 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt
, type
) == -1))
18216 * SPEC src-simple-type 1
18217 * "The corresponding simple type definition, if any, must satisfy
18218 * the conditions set out in Constraints on Simple Type Definition
18219 * Schema Components ($3.14.6)."
18222 * Schema Component Constraint: Simple Type Definition Properties Correct
18223 * (st-props-correct)
18225 res
= xmlSchemaCheckSTPropsCorrect(pctxt
, type
);
18228 * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18229 * (cos-st-restricts)
18231 res
= xmlSchemaCheckCOSSTRestricts(pctxt
, type
);
18234 * TODO: Removed the error report, since it got annoying to get an
18235 * extra error report, if anything failed until now.
18236 * Enable this if needed.
18238 * xmlSchemaPErr(ctxt, type->node,
18239 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18240 * "Simple type '%s' does not satisfy the constraints "
18241 * "on simple type definitions.\n",
18242 * type->name, NULL);
18245 * Schema Component Constraint: Simple Type Restriction (Facets)
18246 * (st-restrict-facets)
18248 res
= xmlSchemaCheckFacetValues(type
, pctxt
);
18250 if ((type
->facetSet
!= NULL
) ||
18251 (type
->baseType
->facetSet
!= NULL
)) {
18252 res
= xmlSchemaDeriveAndValidateFacets(pctxt
, type
);
18256 * Whitespace value.
18258 res
= xmlSchemaTypeFixupWhitespace(type
);
18260 xmlSchemaTypeFixupOptimFacets(type
);
18264 xmlSchemaDebugFixedType(pctxt
, type
);
18266 if (olderrs
!= pctxt
->nberrors
)
18267 return(pctxt
->err
);
18272 xmlSchemaDebugFixedType(pctxt
, type
);
18278 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt
,
18279 xmlSchemaTypePtr type
)
18281 int res
= 0, olderrs
= pctxt
->nberrors
;
18282 xmlSchemaTypePtr baseType
= type
->baseType
;
18284 if (! WXS_IS_TYPE_NOT_FIXED(type
))
18286 type
->flags
|= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED
;
18287 if (baseType
== NULL
) {
18288 PERROR_INT("xmlSchemaFixupComplexType",
18289 "missing baseType");
18293 * Fixup the base type.
18295 if (WXS_IS_TYPE_NOT_FIXED(baseType
))
18296 xmlSchemaTypeFixup(baseType
, ACTXT_CAST pctxt
);
18297 if (baseType
->flags
& XML_SCHEMAS_TYPE_INTERNAL_INVALID
) {
18299 * Skip fixup if the base type is invalid.
18300 * TODO: Generate a warning!
18305 * This basically checks if the base type can be derived.
18307 res
= xmlSchemaCheckSRCCT(pctxt
, type
);
18310 * Fixup the content type.
18312 if (type
->contentType
== XML_SCHEMA_CONTENT_SIMPLE
) {
18314 * Corresponds to <complexType><simpleContent>...
18316 if ((WXS_IS_COMPLEX(baseType
)) &&
18317 (baseType
->contentTypeDef
!= NULL
) &&
18318 (WXS_IS_RESTRICTION(type
))) {
18319 xmlSchemaTypePtr contentBase
, content
;
18320 #ifdef ENABLE_NAMED_LOCALS
18322 const xmlChar
*tmpname
;
18325 * SPEC (1) If <restriction> + base type is <complexType>,
18326 * "whose own {content type} is a simple type..."
18328 if (type
->contentTypeDef
!= NULL
) {
18330 * SPEC (1.1) "the simple type definition corresponding to the
18331 * <simpleType> among the [children] of <restriction> if there
18333 * Note that this "<simpleType> among the [children]" was put
18334 * into ->contentTypeDef during parsing.
18336 contentBase
= type
->contentTypeDef
;
18337 type
->contentTypeDef
= NULL
;
18340 * (1.2) "...otherwise (<restriction> has no <simpleType>
18341 * among its [children]), the simple type definition which
18342 * is the {content type} of the ... base type."
18344 contentBase
= baseType
->contentTypeDef
;
18348 * "... a simple type definition which restricts the simple
18349 * type definition identified in clause 1.1 or clause 1.2
18350 * with a set of facet components"
18352 * Create the anonymous simple type, which will be the content
18353 * type of the complex type.
18355 #ifdef ENABLE_NAMED_LOCALS
18356 snprintf(buf
, 29, "#scST%d", ++(pctxt
->counter
));
18357 tmpname
= xmlDictLookup(pctxt
->dict
, BAD_CAST buf
, -1);
18358 content
= xmlSchemaAddType(pctxt
, pctxt
->schema
,
18359 XML_SCHEMA_TYPE_SIMPLE
, tmpname
, type
->targetNamespace
,
18362 content
= xmlSchemaAddType(pctxt
, pctxt
->schema
,
18363 XML_SCHEMA_TYPE_SIMPLE
, NULL
, type
->targetNamespace
,
18366 if (content
== NULL
)
18369 * We will use the same node as for the <complexType>
18370 * to have it somehow anchored in the schema doc.
18372 content
->type
= XML_SCHEMA_TYPE_SIMPLE
;
18373 content
->baseType
= contentBase
;
18375 * Move the facets, previously anchored on the
18376 * complexType during parsing.
18378 content
->facets
= type
->facets
;
18379 type
->facets
= NULL
;
18380 content
->facetSet
= type
->facetSet
;
18381 type
->facetSet
= NULL
;
18383 type
->contentTypeDef
= content
;
18384 if (WXS_IS_TYPE_NOT_FIXED(contentBase
))
18385 xmlSchemaTypeFixup(contentBase
, ACTXT_CAST pctxt
);
18387 * Fixup the newly created type. We don't need to check
18388 * for circularity here.
18390 res
= xmlSchemaFixupSimpleTypeStageOne(pctxt
, content
);
18392 res
= xmlSchemaFixupSimpleTypeStageTwo(pctxt
, content
);
18395 } else if ((WXS_IS_COMPLEX(baseType
)) &&
18396 (baseType
->contentType
== XML_SCHEMA_CONTENT_MIXED
) &&
18397 (WXS_IS_RESTRICTION(type
))) {
18399 * SPEC (2) If <restriction> + base is a mixed <complexType> with
18400 * an emptiable particle, then a simple type definition which
18401 * restricts the <restriction>'s <simpleType> child.
18403 if ((type
->contentTypeDef
== NULL
) ||
18404 (type
->contentTypeDef
->baseType
== NULL
)) {
18406 * TODO: Check if this ever happens.
18408 xmlSchemaPCustomErr(pctxt
,
18409 XML_SCHEMAP_INTERNAL
,
18410 WXS_BASIC_CAST type
, NULL
,
18411 "Internal error: xmlSchemaTypeFixup, "
18412 "complex type '%s': the <simpleContent><restriction> "
18413 "is missing a <simpleType> child, but was not caught "
18414 "by xmlSchemaCheckSRCCT()", type
->name
);
18417 } else if ((WXS_IS_COMPLEX(baseType
)) && WXS_IS_EXTENSION(type
)) {
18419 * SPEC (3) If <extension> + base is <complexType> with
18420 * <simpleType> content, "...then the {content type} of that
18421 * complex type definition"
18423 if (baseType
->contentTypeDef
== NULL
) {
18425 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18426 * should have caught this already.
18428 xmlSchemaPCustomErr(pctxt
,
18429 XML_SCHEMAP_INTERNAL
,
18430 WXS_BASIC_CAST type
, NULL
,
18431 "Internal error: xmlSchemaTypeFixup, "
18432 "complex type '%s': the <extension>ed base type is "
18433 "a complex type with no simple content type",
18437 type
->contentTypeDef
= baseType
->contentTypeDef
;
18438 } else if ((WXS_IS_SIMPLE(baseType
)) && WXS_IS_EXTENSION(type
)) {
18440 * SPEC (4) <extension> + base is <simpleType>
18441 * "... then that simple type definition"
18443 type
->contentTypeDef
= baseType
;
18446 * TODO: Check if this ever happens.
18448 xmlSchemaPCustomErr(pctxt
,
18449 XML_SCHEMAP_INTERNAL
,
18450 WXS_BASIC_CAST type
, NULL
,
18451 "Internal error: xmlSchemaTypeFixup, "
18452 "complex type '%s' with <simpleContent>: unhandled "
18453 "derivation case", type
->name
);
18457 int dummySequence
= 0;
18458 xmlSchemaParticlePtr particle
=
18459 (xmlSchemaParticlePtr
) type
->subtypes
;
18461 * Corresponds to <complexType><complexContent>...
18463 * NOTE that the effective mixed was already set during parsing of
18464 * <complexType> and <complexContent>; its flag value is
18465 * XML_SCHEMAS_TYPE_MIXED.
18467 * Compute the "effective content":
18468 * (2.1.1) + (2.1.2) + (2.1.3)
18470 if ((particle
== NULL
) ||
18471 ((particle
->type
== XML_SCHEMA_TYPE_PARTICLE
) &&
18472 ((particle
->children
->type
== XML_SCHEMA_TYPE_ALL
) ||
18473 (particle
->children
->type
== XML_SCHEMA_TYPE_SEQUENCE
) ||
18474 ((particle
->children
->type
== XML_SCHEMA_TYPE_CHOICE
) &&
18475 (particle
->minOccurs
== 0))) &&
18476 ( ((xmlSchemaTreeItemPtr
) particle
->children
)->children
== NULL
))) {
18477 if (type
->flags
& XML_SCHEMAS_TYPE_MIXED
) {
18479 * SPEC (2.1.4) "If the `effective mixed` is true, then
18480 * a particle whose properties are as follows:..."
18482 * Empty sequence model group with
18483 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18484 * NOTE that we sill assign it the <complexType> node to
18485 * somehow anchor it in the doc.
18487 if ((particle
== NULL
) ||
18488 (particle
->children
->type
!= XML_SCHEMA_TYPE_SEQUENCE
)) {
18490 * Create the particle.
18492 particle
= xmlSchemaAddParticle(pctxt
,
18494 if (particle
== NULL
)
18497 * Create the model group.
18498 */ /* URGENT TODO: avoid adding to pending items. */
18499 particle
->children
= (xmlSchemaTreeItemPtr
)
18500 xmlSchemaAddModelGroup(pctxt
, pctxt
->schema
,
18501 XML_SCHEMA_TYPE_SEQUENCE
, type
->node
);
18502 if (particle
->children
== NULL
)
18505 type
->subtypes
= (xmlSchemaTypePtr
) particle
;
18508 type
->contentType
= XML_SCHEMA_CONTENT_ELEMENTS
;
18511 * SPEC (2.1.5) "otherwise empty"
18513 type
->contentType
= XML_SCHEMA_CONTENT_EMPTY
;
18517 * SPEC (2.2) "otherwise the particle corresponding to the
18518 * <all>, <choice>, <group> or <sequence> among the
18521 type
->contentType
= XML_SCHEMA_CONTENT_ELEMENTS
;
18524 * Compute the "content type".
18526 if (WXS_IS_RESTRICTION(type
)) {
18528 * SPEC (3.1) "If <restriction>..."
18529 * (3.1.1) + (3.1.2) */
18530 if (type
->contentType
!= XML_SCHEMA_CONTENT_EMPTY
) {
18531 if (type
->flags
& XML_SCHEMAS_TYPE_MIXED
)
18532 type
->contentType
= XML_SCHEMA_CONTENT_MIXED
;
18536 * SPEC (3.2) "If <extension>..."
18538 if (type
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) {
18541 * "If the `effective content` is empty, then the
18542 * {content type} of the [...] base ..."
18544 type
->contentType
= baseType
->contentType
;
18545 type
->subtypes
= baseType
->subtypes
;
18547 * Fixes bug #347316:
18548 * This is the case when the base type has a simple
18549 * type definition as content.
18551 type
->contentTypeDef
= baseType
->contentTypeDef
;
18553 * NOTE that the effective mixed is ignored here.
18555 } else if (baseType
->contentType
== XML_SCHEMA_CONTENT_EMPTY
) {
18559 if (type
->flags
& XML_SCHEMAS_TYPE_MIXED
)
18560 type
->contentType
= XML_SCHEMA_CONTENT_MIXED
;
18565 if (type
->flags
& XML_SCHEMAS_TYPE_MIXED
)
18566 type
->contentType
= XML_SCHEMA_CONTENT_MIXED
;
18568 * "A model group whose {compositor} is sequence and whose
18569 * {particles} are..."
18571 if ((WXS_TYPE_PARTICLE(type
) != NULL
) &&
18572 (WXS_TYPE_PARTICLE_TERM(type
) != NULL
) &&
18573 ((WXS_TYPE_PARTICLE_TERM(type
))->type
==
18574 XML_SCHEMA_TYPE_ALL
))
18577 * SPEC cos-all-limited (1)
18579 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
18580 /* TODO: error code */
18581 XML_SCHEMAP_COS_ALL_LIMITED
,
18582 WXS_ITEM_NODE(type
), NULL
,
18583 "The type has an 'all' model group in its "
18584 "{content type} and thus cannot be derived from "
18585 "a non-empty type, since this would produce a "
18586 "'sequence' model group containing the 'all' "
18587 "model group; 'all' model groups are not "
18588 "allowed to appear inside other model groups",
18591 } else if ((WXS_TYPE_PARTICLE(baseType
) != NULL
) &&
18592 (WXS_TYPE_PARTICLE_TERM(baseType
) != NULL
) &&
18593 ((WXS_TYPE_PARTICLE_TERM(baseType
))->type
==
18594 XML_SCHEMA_TYPE_ALL
))
18597 * SPEC cos-all-limited (1)
18599 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
18600 /* TODO: error code */
18601 XML_SCHEMAP_COS_ALL_LIMITED
,
18602 WXS_ITEM_NODE(type
), NULL
,
18603 "A type cannot be derived by extension from a type "
18604 "which has an 'all' model group in its "
18605 "{content type}, since this would produce a "
18606 "'sequence' model group containing the 'all' "
18607 "model group; 'all' model groups are not "
18608 "allowed to appear inside other model groups",
18611 } else if (! dummySequence
) {
18612 xmlSchemaTreeItemPtr effectiveContent
=
18613 (xmlSchemaTreeItemPtr
) type
->subtypes
;
18615 * Create the particle.
18617 particle
= xmlSchemaAddParticle(pctxt
,
18619 if (particle
== NULL
)
18622 * Create the "sequence" model group.
18624 particle
->children
= (xmlSchemaTreeItemPtr
)
18625 xmlSchemaAddModelGroup(pctxt
, pctxt
->schema
,
18626 XML_SCHEMA_TYPE_SEQUENCE
, type
->node
);
18627 if (particle
->children
== NULL
)
18629 WXS_TYPE_CONTENTTYPE(type
) = (xmlSchemaTypePtr
) particle
;
18631 * SPEC "the particle of the {content type} of
18632 * the ... base ..."
18633 * Create a duplicate of the base type's particle
18634 * and assign its "term" to it.
18636 particle
->children
->children
=
18637 (xmlSchemaTreeItemPtr
) xmlSchemaAddParticle(pctxt
,
18639 ((xmlSchemaParticlePtr
) baseType
->subtypes
)->minOccurs
,
18640 ((xmlSchemaParticlePtr
) baseType
->subtypes
)->maxOccurs
);
18641 if (particle
->children
->children
== NULL
)
18643 particle
= (xmlSchemaParticlePtr
)
18644 particle
->children
->children
;
18645 particle
->children
=
18646 ((xmlSchemaParticlePtr
) baseType
->subtypes
)->children
;
18648 * SPEC "followed by the `effective content`."
18650 particle
->next
= effectiveContent
;
18652 * This all will result in:
18654 * --> new-sequence(
18663 * This is the case when there is already an empty
18664 * <sequence> with minOccurs==maxOccurs==1.
18665 * Just add the base types's content type.
18666 * NOTE that, although we miss to add an intermediate
18667 * <sequence>, this should produce no difference to
18668 * neither the regex compilation of the content model,
18669 * nor to the complex type constraints.
18671 particle
->children
->children
=
18672 (xmlSchemaTreeItemPtr
) baseType
->subtypes
;
18678 * Now fixup attribute uses:
18679 * - expand attr. group references
18680 * - intersect attribute wildcards
18681 * - inherit attribute uses of the base type
18682 * - inherit or union attr. wildcards if extending
18683 * - apply attr. use prohibitions if restricting
18685 res
= xmlSchemaFixupTypeAttributeUses(pctxt
, type
);
18688 * Apply the complex type component constraints; this will not
18689 * check attributes, since this is done in
18690 * xmlSchemaFixupTypeAttributeUses().
18692 res
= xmlSchemaCheckCTComponent(pctxt
, type
);
18696 xmlSchemaDebugFixedType(pctxt
, type
);
18698 if (olderrs
!= pctxt
->nberrors
)
18699 return(pctxt
->err
);
18704 type
->flags
|= XML_SCHEMAS_TYPE_INTERNAL_INVALID
;
18706 xmlSchemaDebugFixedType(pctxt
, type
);
18708 return(pctxt
->err
);
18711 type
->flags
|= XML_SCHEMAS_TYPE_INTERNAL_INVALID
;
18713 xmlSchemaDebugFixedType(pctxt
, type
);
18720 * xmlSchemaTypeFixup:
18721 * @typeDecl: the schema type definition
18722 * @ctxt: the schema parser context
18724 * Fixes the content model of the type.
18725 * URGENT TODO: We need an int result!
18728 xmlSchemaTypeFixup(xmlSchemaTypePtr type
,
18729 xmlSchemaAbstractCtxtPtr actxt
)
18733 if (actxt
->type
!= XML_SCHEMA_CTXT_PARSER
) {
18734 AERROR_INT("xmlSchemaTypeFixup",
18735 "this function needs a parser context");
18738 if (! WXS_IS_TYPE_NOT_FIXED(type
))
18740 if (type
->type
== XML_SCHEMA_TYPE_COMPLEX
)
18741 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt
, type
));
18742 else if (type
->type
== XML_SCHEMA_TYPE_SIMPLE
)
18743 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt
, type
));
18748 * xmlSchemaCheckFacet:
18749 * @facet: the facet
18750 * @typeDecl: the schema type definition
18751 * @pctxt: the schema parser context or NULL
18752 * @name: the optional name of the type
18754 * Checks and computes the values of facets.
18756 * Returns 0 if valid, a positive error code if not valid and
18757 * -1 in case of an internal or API error.
18760 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet
,
18761 xmlSchemaTypePtr typeDecl
,
18762 xmlSchemaParserCtxtPtr pctxt
,
18763 const xmlChar
* name ATTRIBUTE_UNUSED
)
18765 int ret
= 0, ctxtGiven
;
18767 if ((facet
== NULL
) || (typeDecl
== NULL
))
18770 * TODO: will the parser context be given if used from
18771 * the relaxNG module?
18778 switch (facet
->type
) {
18779 case XML_SCHEMA_FACET_MININCLUSIVE
:
18780 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
18781 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
18782 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
18783 case XML_SCHEMA_FACET_ENUMERATION
: {
18785 * Okay we need to validate the value
18788 xmlSchemaTypePtr base
;
18790 /* 4.3.5.5 Constraints on enumeration Schema Components
18791 * Schema Component Constraint: enumeration valid restriction
18792 * It is an `error` if any member of {value} is not in the
18793 * `value space` of {base type definition}.
18795 * minInclusive, maxInclusive, minExclusive, maxExclusive:
18796 * The value `must` be in the
18797 * `value space` of the `base type`.
18800 * This function is intended to deliver a compiled value
18801 * on the facet. In this implementation of XML Schemata the
18802 * type holding a facet, won't be a built-in type.
18803 * Thus to ensure that other API
18804 * calls (relaxng) do work, if the given type is a built-in
18805 * type, we will assume that the given built-in type *is
18806 * already* the base type.
18808 if (typeDecl
->type
!= XML_SCHEMA_TYPE_BASIC
) {
18809 base
= typeDecl
->baseType
;
18810 if (base
== NULL
) {
18811 PERROR_INT("xmlSchemaCheckFacet",
18812 "a type user derived type has no base type");
18820 * A context is needed if called from RelaxNG.
18822 pctxt
= xmlSchemaNewParserCtxt("*");
18827 * NOTE: This call does not check the content nodes,
18828 * since they are not available:
18829 * facet->node is just the node holding the facet
18830 * definition, *not* the attribute holding the *value*
18833 ret
= xmlSchemaVCheckCVCSimpleType(
18834 ACTXT_CAST pctxt
, facet
->node
, base
,
18835 facet
->value
, &(facet
->val
), 1, 1, 0);
18838 /* No error message for RelaxNG. */
18840 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
18841 XML_SCHEMAP_INTERNAL
, facet
->node
, NULL
,
18842 "Internal error: xmlSchemaCheckFacet, "
18843 "failed to validate the value '%s' of the "
18844 "facet '%s' against the base type",
18845 facet
->value
, xmlSchemaFacetTypeToString(facet
->type
));
18847 goto internal_error
;
18849 ret
= XML_SCHEMAP_INVALID_FACET_VALUE
;
18850 /* No error message for RelaxNG. */
18852 xmlChar
*str
= NULL
;
18854 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
18855 ret
, facet
->node
, WXS_BASIC_CAST facet
,
18856 "The value '%s' of the facet does not validate "
18857 "against the base type '%s'",
18859 xmlSchemaFormatQName(&str
,
18860 base
->targetNamespace
, base
->name
));
18861 FREE_AND_NULL(str
);
18864 } else if (facet
->val
== NULL
) {
18866 PERROR_INT("xmlSchemaCheckFacet",
18867 "value was not computed");
18873 case XML_SCHEMA_FACET_PATTERN
:
18874 facet
->regexp
= xmlRegexpCompile(facet
->value
);
18875 if (facet
->regexp
== NULL
) {
18876 ret
= XML_SCHEMAP_REGEXP_INVALID
;
18877 /* No error message for RelaxNG. */
18879 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
18880 ret
, facet
->node
, WXS_BASIC_CAST typeDecl
,
18881 "The value '%s' of the facet 'pattern' is not a "
18882 "valid regular expression",
18883 facet
->value
, NULL
);
18887 case XML_SCHEMA_FACET_TOTALDIGITS
:
18888 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
18889 case XML_SCHEMA_FACET_LENGTH
:
18890 case XML_SCHEMA_FACET_MAXLENGTH
:
18891 case XML_SCHEMA_FACET_MINLENGTH
:
18893 if (facet
->type
== XML_SCHEMA_FACET_TOTALDIGITS
) {
18894 ret
= xmlSchemaValidatePredefinedType(
18895 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER
),
18896 facet
->value
, &(facet
->val
));
18898 ret
= xmlSchemaValidatePredefinedType(
18899 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER
),
18900 facet
->value
, &(facet
->val
));
18904 /* No error message for RelaxNG. */
18906 PERROR_INT("xmlSchemaCheckFacet",
18907 "validating facet value");
18909 goto internal_error
;
18911 ret
= XML_SCHEMAP_INVALID_FACET_VALUE
;
18912 /* No error message for RelaxNG. */
18915 xmlSchemaCustomErr4(ACTXT_CAST pctxt
,
18916 ret
, facet
->node
, WXS_BASIC_CAST typeDecl
,
18917 "The value '%s' of the facet '%s' is not a valid '%s'",
18919 xmlSchemaFacetTypeToString(facet
->type
),
18920 (facet
->type
!= XML_SCHEMA_FACET_TOTALDIGITS
) ?
18921 BAD_CAST
"nonNegativeInteger" :
18922 BAD_CAST
"positiveInteger",
18928 case XML_SCHEMA_FACET_WHITESPACE
:{
18929 if (xmlStrEqual(facet
->value
, BAD_CAST
"preserve")) {
18930 facet
->whitespace
= XML_SCHEMAS_FACET_PRESERVE
;
18931 } else if (xmlStrEqual(facet
->value
, BAD_CAST
"replace")) {
18932 facet
->whitespace
= XML_SCHEMAS_FACET_REPLACE
;
18933 } else if (xmlStrEqual(facet
->value
, BAD_CAST
"collapse")) {
18934 facet
->whitespace
= XML_SCHEMAS_FACET_COLLAPSE
;
18936 ret
= XML_SCHEMAP_INVALID_FACET_VALUE
;
18937 /* No error message for RelaxNG. */
18939 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18940 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
18941 ret
, facet
->node
, WXS_BASIC_CAST typeDecl
,
18942 "The value '%s' of the facet 'whitespace' is not "
18943 "valid", facet
->value
, NULL
);
18951 if ((! ctxtGiven
) && (pctxt
!= NULL
))
18952 xmlSchemaFreeParserCtxt(pctxt
);
18955 if ((! ctxtGiven
) && (pctxt
!= NULL
))
18956 xmlSchemaFreeParserCtxt(pctxt
);
18961 * xmlSchemaCheckFacetValues:
18962 * @typeDecl: the schema type definition
18963 * @ctxt: the schema parser context
18965 * Checks the default values types, especially for facets
18968 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl
,
18969 xmlSchemaParserCtxtPtr pctxt
)
18971 int res
, olderrs
= pctxt
->nberrors
;
18972 const xmlChar
*name
= typeDecl
->name
;
18974 * NOTE: It is intended to use the facets list, instead
18977 if (typeDecl
->facets
!= NULL
) {
18978 xmlSchemaFacetPtr facet
= typeDecl
->facets
;
18981 * Temporarily assign the "schema" to the validation context
18982 * of the parser context. This is needed for NOTATION validation.
18984 if (pctxt
->vctxt
== NULL
) {
18985 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt
) == -1)
18988 pctxt
->vctxt
->schema
= pctxt
->schema
;
18989 while (facet
!= NULL
) {
18990 res
= xmlSchemaCheckFacet(facet
, typeDecl
, pctxt
, name
);
18992 facet
= facet
->next
;
18994 pctxt
->vctxt
->schema
= NULL
;
18996 if (olderrs
!= pctxt
->nberrors
)
18997 return(pctxt
->err
);
19004 * xmlSchemaGetCircModelGrDefRef:
19005 * @ctxtMGroup: the searched model group
19006 * @selfMGroup: the second searched model group
19007 * @particle: the first particle
19009 * This one is intended to be used by
19010 * xmlSchemaCheckGroupDefCircular only.
19012 * Returns the particle with the circular model group definition reference,
19015 static xmlSchemaTreeItemPtr
19016 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef
,
19017 xmlSchemaTreeItemPtr particle
)
19019 xmlSchemaTreeItemPtr circ
= NULL
;
19020 xmlSchemaTreeItemPtr term
;
19021 xmlSchemaModelGroupDefPtr gdef
;
19023 for (; particle
!= NULL
; particle
= particle
->next
) {
19024 term
= particle
->children
;
19027 switch (term
->type
) {
19028 case XML_SCHEMA_TYPE_GROUP
:
19029 gdef
= (xmlSchemaModelGroupDefPtr
) term
;
19030 if (gdef
== groupDef
)
19033 * Mark this model group definition to avoid infinite
19034 * recursion on circular references not yet examined.
19036 if (gdef
->flags
& XML_SCHEMA_MODEL_GROUP_DEF_MARKED
)
19038 if (gdef
->children
!= NULL
) {
19039 gdef
->flags
|= XML_SCHEMA_MODEL_GROUP_DEF_MARKED
;
19040 circ
= xmlSchemaGetCircModelGrDefRef(groupDef
,
19041 gdef
->children
->children
);
19042 gdef
->flags
^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED
;
19047 case XML_SCHEMA_TYPE_SEQUENCE
:
19048 case XML_SCHEMA_TYPE_CHOICE
:
19049 case XML_SCHEMA_TYPE_ALL
:
19050 circ
= xmlSchemaGetCircModelGrDefRef(groupDef
, term
->children
);
19062 * xmlSchemaCheckGroupDefCircular:
19063 * @item: the model group definition
19064 * @ctxt: the parser context
19067 * Checks for circular references to model group definitions.
19070 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item
,
19071 xmlSchemaParserCtxtPtr ctxt
)
19074 * Schema Component Constraint: Model Group Correct
19075 * 2 Circular groups are disallowed. That is, within the {particles}
19076 * of a group there must not be at any depth a particle whose {term}
19077 * is the group itself.
19079 if ((item
== NULL
) ||
19080 (item
->type
!= XML_SCHEMA_TYPE_GROUP
) ||
19081 (item
->children
== NULL
))
19084 xmlSchemaTreeItemPtr circ
;
19086 circ
= xmlSchemaGetCircModelGrDefRef(item
, item
->children
->children
);
19087 if (circ
!= NULL
) {
19088 xmlChar
*str
= NULL
;
19090 * TODO: The error report is not adequate: this constraint
19091 * is defined for model groups but not definitions, but since
19092 * there cannot be any circular model groups without a model group
19093 * definition (if not using a construction API), we check those
19094 * definitions only.
19096 xmlSchemaPCustomErr(ctxt
,
19097 XML_SCHEMAP_MG_PROPS_CORRECT_2
,
19098 NULL
, WXS_ITEM_NODE(circ
),
19099 "Circular reference to the model group definition '%s' "
19100 "defined", xmlSchemaFormatQName(&str
,
19101 item
->targetNamespace
, item
->name
));
19104 * NOTE: We will cut the reference to avoid further
19105 * confusion of the processor. This is a fatal error.
19107 circ
->children
= NULL
;
19113 * xmlSchemaModelGroupToModelGroupDefFixup:
19114 * @ctxt: the parser context
19115 * @mg: the model group
19117 * Assigns the model group of model group definitions to the "term"
19118 * of the referencing particle.
19119 * In xmlSchemaResolveModelGroupParticleReferences the model group
19120 * definitions were assigned to the "term", since needed for the
19121 * circularity check.
19123 * Schema Component Constraint:
19124 * All Group Limited (cos-all-limited) (1.2)
19127 xmlSchemaModelGroupToModelGroupDefFixup(
19128 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED
,
19129 xmlSchemaModelGroupPtr mg
)
19131 xmlSchemaParticlePtr particle
= WXS_MODELGROUP_PARTICLE(mg
);
19133 while (particle
!= NULL
) {
19134 if ((WXS_PARTICLE_TERM(particle
) == NULL
) ||
19135 ((WXS_PARTICLE_TERM(particle
))->type
!=
19136 XML_SCHEMA_TYPE_GROUP
))
19138 particle
= WXS_PTC_CAST particle
->next
;
19141 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle
)) == NULL
) {
19143 * TODO: Remove the particle.
19145 WXS_PARTICLE_TERM(particle
) = NULL
;
19146 particle
= WXS_PTC_CAST particle
->next
;
19150 * Assign the model group to the {term} of the particle.
19152 WXS_PARTICLE_TERM(particle
) =
19153 WXS_TREE_CAST
WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle
));
19155 particle
= WXS_PTC_CAST particle
->next
;
19160 * xmlSchemaCheckAttrGroupCircularRecur:
19161 * @ctxtGr: the searched attribute group
19162 * @attr: the current attribute list to be processed
19164 * This one is intended to be used by
19165 * xmlSchemaCheckAttrGroupCircular only.
19167 * Returns the circular attribute group reference, otherwise NULL.
19169 static xmlSchemaQNameRefPtr
19170 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr
,
19171 xmlSchemaItemListPtr list
)
19173 xmlSchemaAttributeGroupPtr gr
;
19174 xmlSchemaQNameRefPtr ref
, circ
;
19177 * We will search for an attribute group reference which
19178 * references the context attribute group.
19180 for (i
= 0; i
< list
->nbItems
; i
++) {
19181 ref
= list
->items
[i
];
19182 if ((ref
->type
== XML_SCHEMA_EXTRA_QNAMEREF
) &&
19183 (ref
->itemType
== XML_SCHEMA_TYPE_ATTRIBUTEGROUP
) &&
19184 (ref
->item
!= NULL
))
19186 gr
= WXS_ATTR_GROUP_CAST ref
->item
;
19189 if (gr
->flags
& XML_SCHEMAS_ATTRGROUP_MARKED
)
19192 * Mark as visited to avoid infinite recursion on
19193 * circular references not yet examined.
19195 if ((gr
->attrUses
) &&
19196 (gr
->flags
& XML_SCHEMAS_ATTRGROUP_HAS_REFS
))
19198 gr
->flags
|= XML_SCHEMAS_ATTRGROUP_MARKED
;
19199 circ
= xmlSchemaCheckAttrGroupCircularRecur(ctxtGr
,
19200 (xmlSchemaItemListPtr
) gr
->attrUses
);
19201 gr
->flags
^= XML_SCHEMAS_ATTRGROUP_MARKED
;
19212 * xmlSchemaCheckAttrGroupCircular:
19213 * attrGr: the attribute group definition
19214 * @ctxt: the parser context
19217 * Checks for circular references of attribute groups.
19220 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr
,
19221 xmlSchemaParserCtxtPtr ctxt
)
19224 * Schema Representation Constraint:
19225 * Attribute Group Definition Representation OK
19226 * 3 Circular group reference is disallowed outside <redefine>.
19227 * That is, unless this element information item's parent is
19228 * <redefine>, then among the [children], if any, there must
19229 * not be an <attributeGroup> with ref [attribute] which resolves
19230 * to the component corresponding to this <attributeGroup>. Indirect
19231 * circularity is also ruled out. That is, when QName resolution
19232 * (Schema Document) ($3.15.3) is applied to a `QName` arising from
19233 * any <attributeGroup>s with a ref [attribute] among the [children],
19234 * it must not be the case that a `QName` is encountered at any depth
19235 * which resolves to the component corresponding to this <attributeGroup>.
19237 if (attrGr
->attrUses
== NULL
)
19239 else if ((attrGr
->flags
& XML_SCHEMAS_ATTRGROUP_HAS_REFS
) == 0)
19242 xmlSchemaQNameRefPtr circ
;
19244 circ
= xmlSchemaCheckAttrGroupCircularRecur(attrGr
,
19245 (xmlSchemaItemListPtr
) attrGr
->attrUses
);
19246 if (circ
!= NULL
) {
19247 xmlChar
*str
= NULL
;
19249 * TODO: Report the referenced attr group as QName.
19251 xmlSchemaPCustomErr(ctxt
,
19252 XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3
,
19253 NULL
, WXS_ITEM_NODE(WXS_BASIC_CAST circ
),
19254 "Circular reference to the attribute group '%s' "
19255 "defined", xmlSchemaGetComponentQName(&str
, attrGr
));
19256 FREE_AND_NULL(str
);
19258 * NOTE: We will cut the reference to avoid further
19259 * confusion of the processor.
19260 * BADSPEC TODO: The spec should define how to process in this case.
19270 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt
,
19271 xmlSchemaAttributeGroupPtr attrGr
);
19274 * xmlSchemaExpandAttributeGroupRefs:
19275 * @pctxt: the parser context
19276 * @node: the node of the component holding the attribute uses
19277 * @completeWild: the intersected wildcard to be returned
19278 * @list: the attribute uses
19280 * Substitutes contained attribute group references
19281 * for their attribute uses. Wildcards are intersected.
19282 * Attribute use prohibitions are removed from the list
19283 * and returned via the @prohibs list.
19284 * Pointlessness of attr. prohibs, if a matching attr. decl
19285 * is existent a well, are checked.
19288 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt
,
19289 xmlSchemaBasicItemPtr item
,
19290 xmlSchemaWildcardPtr
*completeWild
,
19291 xmlSchemaItemListPtr list
,
19292 xmlSchemaItemListPtr prohibs
)
19294 xmlSchemaAttributeGroupPtr gr
;
19295 xmlSchemaAttributeUsePtr use
;
19296 xmlSchemaItemListPtr sublist
;
19298 int created
= (*completeWild
== NULL
) ? 0 : 1;
19301 prohibs
->nbItems
= 0;
19303 for (i
= 0; i
< list
->nbItems
; i
++) {
19304 use
= list
->items
[i
];
19306 if (use
->type
== XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
) {
19307 if (prohibs
== NULL
) {
19308 PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19309 "unexpected attr prohibition found");
19313 * Remove from attribute uses.
19315 if (xmlSchemaItemListRemove(list
, i
) == -1)
19319 * Note that duplicate prohibitions were already
19320 * handled at parsing time.
19323 * Add to list of prohibitions.
19325 xmlSchemaItemListAddSize(prohibs
, 2, use
);
19328 if ((use
->type
== XML_SCHEMA_EXTRA_QNAMEREF
) &&
19329 ((WXS_QNAME_CAST use
)->itemType
== XML_SCHEMA_TYPE_ATTRIBUTEGROUP
))
19331 if ((WXS_QNAME_CAST use
)->item
== NULL
)
19333 gr
= WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use
)->item
;
19335 * Expand the referenced attr. group.
19336 * TODO: remove this, this is done in a previous step, so
19337 * already done here.
19339 if ((gr
->flags
& XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED
) == 0) {
19340 if (xmlSchemaAttributeGroupExpandRefs(pctxt
, gr
) == -1)
19344 * Build the 'complete' wildcard; i.e. intersect multiple
19347 if (gr
->attributeWildcard
!= NULL
) {
19348 if (*completeWild
== NULL
) {
19349 *completeWild
= gr
->attributeWildcard
;
19352 xmlSchemaWildcardPtr tmpWild
;
19355 * Copy the first encountered wildcard as context,
19356 * except for the annotation.
19358 * Although the complete wildcard might not correspond
19359 * to any node in the schema, we will anchor it on
19360 * the node of the owner component.
19362 tmpWild
= xmlSchemaAddWildcard(pctxt
, pctxt
->schema
,
19363 XML_SCHEMA_TYPE_ANY_ATTRIBUTE
,
19364 WXS_ITEM_NODE(item
));
19365 if (tmpWild
== NULL
)
19367 if (xmlSchemaCloneWildcardNsConstraints(pctxt
,
19368 tmpWild
, *completeWild
) == -1)
19370 tmpWild
->processContents
= (*completeWild
)->processContents
;
19371 *completeWild
= tmpWild
;
19375 if (xmlSchemaIntersectWildcards(pctxt
, *completeWild
,
19376 gr
->attributeWildcard
) == -1)
19381 * Just remove the reference if the referenced group does not
19382 * contain any attribute uses.
19384 sublist
= ((xmlSchemaItemListPtr
) gr
->attrUses
);
19385 if ((sublist
== NULL
) || sublist
->nbItems
== 0) {
19386 if (xmlSchemaItemListRemove(list
, i
) == -1)
19392 * Add the attribute uses.
19394 list
->items
[i
] = sublist
->items
[0];
19395 if (sublist
->nbItems
!= 1) {
19396 for (j
= 1; j
< sublist
->nbItems
; j
++) {
19398 if (xmlSchemaItemListInsert(list
,
19399 sublist
->items
[j
], i
) == -1)
19407 * Handle pointless prohibitions of declared attributes.
19409 if (prohibs
&& (prohibs
->nbItems
!= 0) && (list
->nbItems
!= 0)) {
19410 xmlSchemaAttributeUseProhibPtr prohib
;
19412 for (i
= prohibs
->nbItems
-1; i
>= 0; i
--) {
19413 prohib
= prohibs
->items
[i
];
19414 for (j
= 0; j
< list
->nbItems
; j
++) {
19415 use
= list
->items
[j
];
19417 if ((prohib
->name
== WXS_ATTRUSE_DECL_NAME(use
)) &&
19418 (prohib
->targetNamespace
== WXS_ATTRUSE_DECL_TNS(use
)))
19420 xmlChar
*str
= NULL
;
19422 xmlSchemaCustomWarning(ACTXT_CAST pctxt
,
19423 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH
,
19424 prohib
->node
, NULL
,
19425 "Skipping pointless attribute use prohibition "
19426 "'%s', since a corresponding attribute use "
19427 "exists already in the type definition",
19428 xmlSchemaFormatQName(&str
,
19429 prohib
->targetNamespace
, prohib
->name
),
19431 FREE_AND_NULL(str
);
19433 * Remove the prohibition.
19435 if (xmlSchemaItemListRemove(prohibs
, i
) == -1)
19446 * xmlSchemaAttributeGroupExpandRefs:
19447 * @pctxt: the parser context
19448 * @attrGr: the attribute group definition
19451 * {attribute uses} property
19452 * {attribute wildcard} property
19454 * Substitutes contained attribute group references
19455 * for their attribute uses. Wildcards are intersected.
19458 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt
,
19459 xmlSchemaAttributeGroupPtr attrGr
)
19461 if ((attrGr
->attrUses
== NULL
) ||
19462 (attrGr
->flags
& XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED
))
19465 attrGr
->flags
|= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED
;
19466 if (xmlSchemaExpandAttributeGroupRefs(pctxt
, WXS_BASIC_CAST attrGr
,
19467 &(attrGr
->attributeWildcard
), attrGr
->attrUses
, NULL
) == -1)
19473 * xmlSchemaAttributeGroupExpandRefs:
19474 * @pctxt: the parser context
19475 * @attrGr: the attribute group definition
19477 * Substitutes contained attribute group references
19478 * for their attribute uses. Wildcards are intersected.
19480 * Schema Component Constraint:
19481 * Attribute Group Definition Properties Correct (ag-props-correct)
19484 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt
,
19485 xmlSchemaAttributeGroupPtr attrGr
)
19488 * SPEC ag-props-correct
19489 * (1) "The values of the properties of an attribute group definition
19490 * must be as described in the property tableau in The Attribute
19491 * Group Definition Schema Component ($3.6.1), modulo the impact of
19492 * Missing Sub-components ($5.3);"
19495 if ((attrGr
->attrUses
!= NULL
) &&
19496 (WXS_LIST_CAST attrGr
->attrUses
)->nbItems
> 1)
19498 xmlSchemaItemListPtr uses
= WXS_LIST_CAST attrGr
->attrUses
;
19499 xmlSchemaAttributeUsePtr use
, tmp
;
19500 int i
, j
, hasId
= 0;
19502 for (i
= uses
->nbItems
-1; i
>= 0; i
--) {
19503 use
= uses
->items
[i
];
19505 * SPEC ag-props-correct
19506 * (2) "Two distinct members of the {attribute uses} must not have
19507 * {attribute declaration}s both of whose {name}s match and whose
19508 * {target namespace}s are identical."
19511 for (j
= i
-1; j
>= 0; j
--) {
19512 tmp
= uses
->items
[j
];
19513 if ((WXS_ATTRUSE_DECL_NAME(use
) ==
19514 WXS_ATTRUSE_DECL_NAME(tmp
)) &&
19515 (WXS_ATTRUSE_DECL_TNS(use
) ==
19516 WXS_ATTRUSE_DECL_TNS(tmp
)))
19518 xmlChar
*str
= NULL
;
19520 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
19521 XML_SCHEMAP_AG_PROPS_CORRECT
,
19522 attrGr
->node
, WXS_BASIC_CAST attrGr
,
19524 xmlSchemaGetComponentDesignation(&str
, use
),
19526 FREE_AND_NULL(str
);
19528 * Remove the duplicate.
19530 if (xmlSchemaItemListRemove(uses
, i
) == -1)
19537 * SPEC ag-props-correct
19538 * (3) "Two distinct members of the {attribute uses} must not have
19539 * {attribute declaration}s both of whose {type definition}s are or
19540 * are derived from ID."
19541 * TODO: Does 'derived' include member-types of unions?
19543 if (WXS_ATTRUSE_TYPEDEF(use
) != NULL
) {
19544 if (xmlSchemaIsDerivedFromBuiltInType(
19545 WXS_ATTRUSE_TYPEDEF(use
), XML_SCHEMAS_ID
))
19548 xmlChar
*str
= NULL
;
19550 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
19551 XML_SCHEMAP_AG_PROPS_CORRECT
,
19552 attrGr
->node
, WXS_BASIC_CAST attrGr
,
19553 "There must not exist more than one attribute "
19554 "declaration of type 'xs:ID' "
19555 "(or derived from 'xs:ID'). The %s violates this "
19557 xmlSchemaGetComponentDesignation(&str
, use
),
19559 FREE_AND_NULL(str
);
19560 if (xmlSchemaItemListRemove(uses
, i
) == -1)
19573 * xmlSchemaResolveAttrGroupReferences:
19574 * @attrgrpDecl: the schema attribute definition
19575 * @ctxt: the schema parser context
19576 * @name: the attribute name
19578 * Resolves references to attribute group definitions.
19581 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref
,
19582 xmlSchemaParserCtxtPtr ctxt
)
19584 xmlSchemaAttributeGroupPtr group
;
19586 if (ref
->item
!= NULL
)
19588 group
= xmlSchemaGetAttributeGroup(ctxt
->schema
,
19590 ref
->targetNamespace
);
19591 if (group
== NULL
) {
19592 xmlSchemaPResCompAttrErr(ctxt
,
19593 XML_SCHEMAP_SRC_RESOLVE
,
19595 "ref", ref
->name
, ref
->targetNamespace
,
19596 ref
->itemType
, NULL
);
19599 ref
->item
= WXS_BASIC_CAST group
;
19604 * xmlSchemaCheckAttrPropsCorrect:
19605 * @item: an schema attribute declaration/use
19606 * @ctxt: a schema parser context
19607 * @name: the name of the attribute
19610 * Schema Component Constraint:
19611 * Attribute Declaration Properties Correct (a-props-correct)
19613 * Validates the value constraints of an attribute declaration/use.
19614 * NOTE that this needs the simple type definitions to be already
19615 * built and checked.
19618 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt
,
19619 xmlSchemaAttributePtr attr
)
19623 * SPEC a-props-correct (1)
19624 * "The values of the properties of an attribute declaration must
19625 * be as described in the property tableau in The Attribute
19626 * Declaration Schema Component ($3.2.1), modulo the impact of
19627 * Missing Sub-components ($5.3)."
19630 if (WXS_ATTR_TYPEDEF(attr
) == NULL
)
19633 if (attr
->defValue
!= NULL
) {
19637 * SPEC a-props-correct (3)
19638 * "If the {type definition} is or is derived from ID then there
19639 * must not be a {value constraint}."
19641 if (xmlSchemaIsDerivedFromBuiltInType(
19642 WXS_ATTR_TYPEDEF(attr
), XML_SCHEMAS_ID
))
19644 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
19645 XML_SCHEMAP_A_PROPS_CORRECT_3
,
19646 NULL
, WXS_BASIC_CAST attr
,
19647 "Value constraints are not allowed if the type definition "
19648 "is or is derived from xs:ID",
19650 return(pctxt
->err
);
19653 * SPEC a-props-correct (2)
19654 * "if there is a {value constraint}, the canonical lexical
19655 * representation of its value must be `valid` with respect
19656 * to the {type definition} as defined in String Valid ($3.14.4)."
19657 * TODO: Don't care about the *canonical* stuff here, this requirement
19658 * will be removed in WXS 1.1 anyway.
19660 ret
= xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt
,
19661 attr
->node
, WXS_ATTR_TYPEDEF(attr
),
19662 attr
->defValue
, &(attr
->defVal
),
19666 PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19667 "calling xmlSchemaVCheckCVCSimpleType()");
19670 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
19671 XML_SCHEMAP_A_PROPS_CORRECT_2
,
19672 NULL
, WXS_BASIC_CAST attr
,
19673 "The value of the value constraint is not valid",
19675 return(pctxt
->err
);
19682 static xmlSchemaElementPtr
19683 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl
,
19684 xmlSchemaElementPtr ancestor
)
19686 xmlSchemaElementPtr ret
;
19688 if (WXS_SUBST_HEAD(ancestor
) == NULL
)
19690 if (WXS_SUBST_HEAD(ancestor
) == elemDecl
)
19693 if (WXS_SUBST_HEAD(ancestor
)->flags
& XML_SCHEMAS_ELEM_CIRCULAR
)
19695 WXS_SUBST_HEAD(ancestor
)->flags
|= XML_SCHEMAS_ELEM_CIRCULAR
;
19696 ret
= xmlSchemaCheckSubstGroupCircular(elemDecl
,
19697 WXS_SUBST_HEAD(ancestor
));
19698 WXS_SUBST_HEAD(ancestor
)->flags
^= XML_SCHEMAS_ELEM_CIRCULAR
;
19704 * xmlSchemaCheckElemPropsCorrect:
19705 * @ctxt: a schema parser context
19706 * @decl: the element declaration
19707 * @name: the name of the attribute
19709 * Schema Component Constraint:
19710 * Element Declaration Properties Correct (e-props-correct)
19716 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt
,
19717 xmlSchemaElementPtr elemDecl
)
19720 xmlSchemaTypePtr typeDef
= WXS_ELEM_TYPEDEF(elemDecl
);
19722 * SPEC (1) "The values of the properties of an element declaration
19723 * must be as described in the property tableau in The Element
19724 * Declaration Schema Component ($3.3.1), modulo the impact of Missing
19725 * Sub-components ($5.3)."
19727 if (WXS_SUBST_HEAD(elemDecl
) != NULL
) {
19728 xmlSchemaElementPtr head
= WXS_SUBST_HEAD(elemDecl
), circ
;
19730 xmlSchemaCheckElementDeclComponent(head
, pctxt
);
19732 * SPEC (3) "If there is a non-`absent` {substitution group
19733 * affiliation}, then {scope} must be global."
19735 if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_GLOBAL
) == 0) {
19736 xmlSchemaPCustomErr(pctxt
,
19737 XML_SCHEMAP_E_PROPS_CORRECT_3
,
19738 WXS_BASIC_CAST elemDecl
, NULL
,
19739 "Only global element declarations can have a "
19740 "substitution group affiliation", NULL
);
19741 ret
= XML_SCHEMAP_E_PROPS_CORRECT_3
;
19744 * TODO: SPEC (6) "Circular substitution groups are disallowed.
19745 * That is, it must not be possible to return to an element declaration
19746 * by repeatedly following the {substitution group affiliation}
19749 if (head
== elemDecl
)
19751 else if (WXS_SUBST_HEAD(head
) != NULL
)
19752 circ
= xmlSchemaCheckSubstGroupCircular(head
, head
);
19755 if (circ
!= NULL
) {
19756 xmlChar
*strA
= NULL
, *strB
= NULL
;
19758 xmlSchemaPCustomErrExt(pctxt
,
19759 XML_SCHEMAP_E_PROPS_CORRECT_6
,
19760 WXS_BASIC_CAST circ
, NULL
,
19761 "The element declaration '%s' defines a circular "
19762 "substitution group to element declaration '%s'",
19763 xmlSchemaGetComponentQName(&strA
, circ
),
19764 xmlSchemaGetComponentQName(&strB
, head
),
19766 FREE_AND_NULL(strA
)
19767 FREE_AND_NULL(strB
)
19768 ret
= XML_SCHEMAP_E_PROPS_CORRECT_6
;
19771 * SPEC (4) "If there is a {substitution group affiliation},
19772 * the {type definition}
19773 * of the element declaration must be validly derived from the {type
19774 * definition} of the {substitution group affiliation}, given the value
19775 * of the {substitution group exclusions} of the {substitution group
19776 * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
19777 * (if the {type definition} is complex) or as defined in
19778 * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
19781 * NOTE: {substitution group exclusions} means the values of the
19782 * attribute "final".
19785 if (typeDef
!= WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl
))) {
19788 if (head
->flags
& XML_SCHEMAS_ELEM_FINAL_EXTENSION
)
19789 set
|= SUBSET_EXTENSION
;
19790 if (head
->flags
& XML_SCHEMAS_ELEM_FINAL_RESTRICTION
)
19791 set
|= SUBSET_RESTRICTION
;
19793 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt
, typeDef
,
19794 WXS_ELEM_TYPEDEF(head
), set
) != 0) {
19795 xmlChar
*strA
= NULL
, *strB
= NULL
, *strC
= NULL
;
19797 ret
= XML_SCHEMAP_E_PROPS_CORRECT_4
;
19798 xmlSchemaPCustomErrExt(pctxt
,
19799 XML_SCHEMAP_E_PROPS_CORRECT_4
,
19800 WXS_BASIC_CAST elemDecl
, NULL
,
19801 "The type definition '%s' was "
19802 "either rejected by the substitution group "
19803 "affiliation '%s', or not validly derived from its type "
19805 xmlSchemaGetComponentQName(&strA
, typeDef
),
19806 xmlSchemaGetComponentQName(&strB
, head
),
19807 xmlSchemaGetComponentQName(&strC
, WXS_ELEM_TYPEDEF(head
)));
19808 FREE_AND_NULL(strA
)
19809 FREE_AND_NULL(strB
)
19810 FREE_AND_NULL(strC
)
19815 * SPEC (5) "If the {type definition} or {type definition}'s
19817 * is or is derived from ID then there must not be a {value constraint}.
19818 * Note: The use of ID as a type definition for elements goes beyond
19819 * XML 1.0, and should be avoided if backwards compatibility is desired"
19821 if ((elemDecl
->value
!= NULL
) &&
19822 ((WXS_IS_SIMPLE(typeDef
) &&
19823 xmlSchemaIsDerivedFromBuiltInType(typeDef
, XML_SCHEMAS_ID
)) ||
19824 (WXS_IS_COMPLEX(typeDef
) &&
19825 WXS_HAS_SIMPLE_CONTENT(typeDef
) &&
19826 xmlSchemaIsDerivedFromBuiltInType(typeDef
->contentTypeDef
,
19827 XML_SCHEMAS_ID
)))) {
19829 ret
= XML_SCHEMAP_E_PROPS_CORRECT_5
;
19830 xmlSchemaPCustomErr(pctxt
,
19831 XML_SCHEMAP_E_PROPS_CORRECT_5
,
19832 WXS_BASIC_CAST elemDecl
, NULL
,
19833 "The type definition (or type definition's content type) is or "
19834 "is derived from ID; value constraints are not allowed in "
19835 "conjunction with such a type definition", NULL
);
19836 } else if (elemDecl
->value
!= NULL
) {
19838 xmlNodePtr node
= NULL
;
19841 * SPEC (2) "If there is a {value constraint}, the canonical lexical
19842 * representation of its value must be `valid` with respect to the
19843 * {type definition} as defined in Element Default Valid (Immediate)
19846 if (typeDef
== NULL
) {
19847 xmlSchemaPErr(pctxt
, elemDecl
->node
,
19848 XML_SCHEMAP_INTERNAL
,
19849 "Internal error: xmlSchemaCheckElemPropsCorrect, "
19850 "type is missing... skipping validation of "
19851 "the value constraint", NULL
, NULL
);
19854 if (elemDecl
->node
!= NULL
) {
19855 if (elemDecl
->flags
& XML_SCHEMAS_ELEM_FIXED
)
19856 node
= (xmlNodePtr
) xmlHasProp(elemDecl
->node
,
19859 node
= (xmlNodePtr
) xmlHasProp(elemDecl
->node
,
19860 BAD_CAST
"default");
19862 vcret
= xmlSchemaParseCheckCOSValidDefault(pctxt
, node
,
19863 typeDef
, elemDecl
->value
, &(elemDecl
->defVal
));
19866 PERROR_INT("xmlSchemaElemCheckValConstr",
19867 "failed to validate the value constraint of an "
19868 "element declaration");
19879 * xmlSchemaCheckElemSubstGroup:
19880 * @ctxt: a schema parser context
19881 * @decl: the element declaration
19882 * @name: the name of the attribute
19884 * Schema Component Constraint:
19885 * Substitution Group (cos-equiv-class)
19887 * In Libxml2 the subst. groups will be precomputed, in terms of that
19888 * a list will be built for each subst. group head, holding all direct
19889 * referents to this head.
19890 * NOTE that this function needs:
19891 * 1. circular subst. groups to be checked beforehand
19892 * 2. the declaration's type to be derived from the head's type
19898 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt
,
19899 xmlSchemaElementPtr elemDecl
)
19901 if ((WXS_SUBST_HEAD(elemDecl
) == NULL
) ||
19902 /* SPEC (1) "Its {abstract} is false." */
19903 (elemDecl
->flags
& XML_SCHEMAS_ELEM_ABSTRACT
))
19906 xmlSchemaElementPtr head
;
19907 xmlSchemaTypePtr headType
, type
;
19910 * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19911 * {disallowed substitutions} as the blocking constraint, as defined in
19912 * Substitution Group OK (Transitive) ($3.3.6)."
19914 for (head
= WXS_SUBST_HEAD(elemDecl
); head
!= NULL
;
19915 head
= WXS_SUBST_HEAD(head
)) {
19919 * The blocking constraints.
19921 if (head
->flags
& XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION
)
19923 headType
= head
->subtypes
;
19924 type
= elemDecl
->subtypes
;
19925 if (headType
== type
)
19927 if (head
->flags
& XML_SCHEMAS_ELEM_BLOCK_RESTRICTION
)
19928 set
|= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
;
19929 if (head
->flags
& XML_SCHEMAS_ELEM_BLOCK_EXTENSION
)
19930 set
|= XML_SCHEMAS_TYPE_BLOCK_EXTENSION
;
19932 * SPEC: Substitution Group OK (Transitive) (2.3)
19933 * "The set of all {derivation method}s involved in the
19934 * derivation of D's {type definition} from C's {type definition}
19935 * does not intersect with the union of the blocking constraint,
19936 * C's {prohibited substitutions} (if C is complex, otherwise the
19937 * empty set) and the {prohibited substitutions} (respectively the
19938 * empty set) of any intermediate {type definition}s in the
19939 * derivation of D's {type definition} from C's {type definition}."
19942 * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19943 * subst.head axis, the methSet does not need to be computed for
19944 * the full depth over and over.
19947 * The set of all {derivation method}s involved in the derivation
19949 while ((type
!= NULL
) && (type
!= headType
)) {
19950 if ((WXS_IS_EXTENSION(type
)) &&
19951 ((methSet
& XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
) == 0))
19952 methSet
|= XML_SCHEMAS_TYPE_BLOCK_EXTENSION
;
19954 if (WXS_IS_RESTRICTION(type
) &&
19955 ((methSet
& XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
) == 0))
19956 methSet
|= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
;
19958 type
= type
->baseType
;
19961 * The {prohibited substitutions} of all intermediate types +
19964 type
= elemDecl
->subtypes
->baseType
;
19965 while (type
!= NULL
) {
19966 if (WXS_IS_COMPLEX(type
)) {
19968 XML_SCHEMAS_TYPE_BLOCK_EXTENSION
) &&
19969 ((set
& XML_SCHEMAS_TYPE_BLOCK_EXTENSION
) == 0))
19970 set
|= XML_SCHEMAS_TYPE_BLOCK_EXTENSION
;
19972 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
) &&
19973 ((set
& XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
) == 0))
19974 set
|= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
;
19977 if (type
== headType
)
19979 type
= type
->baseType
;
19982 (((set
& XML_SCHEMAS_TYPE_BLOCK_EXTENSION
) &&
19983 (methSet
& XML_SCHEMAS_TYPE_BLOCK_EXTENSION
)) ||
19984 ((set
& XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
) &&
19985 (methSet
& XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
)))) {
19989 xmlSchemaAddElementSubstitutionMember(ctxt
, head
, elemDecl
);
19990 if ((head
->flags
& XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD
) == 0)
19991 head
->flags
|= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD
;
19996 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
19998 * xmlSchemaCheckElementDeclComponent
19999 * @pctxt: the schema parser context
20000 * @ctxtComponent: the context component (an element declaration)
20001 * @ctxtParticle: the first particle of the context component
20002 * @searchParticle: the element declaration particle to be analysed
20004 * Schema Component Constraint: Element Declarations Consistent
20007 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt
,
20008 xmlSchemaBasicItemPtr ctxtComponent
,
20009 xmlSchemaParticlePtr ctxtParticle
,
20010 xmlSchemaParticlePtr searchParticle
,
20011 xmlSchemaParticlePtr curParticle
,
20017 xmlSchemaParticlePtr cur
= curParticle
;
20018 if (curParticle
== NULL
) {
20021 if (WXS_PARTICLE_TERM(curParticle
) == NULL
) {
20023 * Just return in this case. A missing "term" of the particle
20024 * might arise due to an invalid "term" component.
20028 while (cur
!= NULL
) {
20029 switch (WXS_PARTICLE_TERM(cur
)->type
) {
20030 case XML_SCHEMA_TYPE_ANY
:
20032 case XML_SCHEMA_TYPE_ELEMENT
:
20034 ret
= xmlSchemaCheckElementDeclConsistent(pctxt
,
20035 ctxtComponent
, ctxtParticle
, cur
, ctxtParticle
, 1);
20039 xmlSchemaElementPtr elem
=
20040 WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur
));
20042 * SPEC Element Declarations Consistent:
20043 * "If the {particles} contains, either directly,
20044 * indirectly (that is, within the {particles} of a
20045 * contained model group, recursively) or `implicitly`
20046 * two or more element declaration particles with
20047 * the same {name} and {target namespace}, then
20048 * all their type definitions must be the same
20049 * top-level definition [...]"
20051 if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur
)->name
,
20052 WXS_PARTICLE_TERM_AS_ELEM(searchParticle
)->name
) &&
20053 xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur
)->targetNamespace
,
20054 WXS_PARTICLE_TERM_AS_ELEM(searchParticle
)->targetNamespace
))
20056 xmlChar
*strA
= NULL
, *strB
= NULL
;
20058 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
20059 /* TODO: error code */
20060 XML_SCHEMAP_COS_NONAMBIG
,
20061 WXS_ITEM_NODE(cur
), NULL
,
20062 "In the content model of %s, there are multiple "
20063 "element declarations for '%s' with different "
20064 "type definitions",
20065 xmlSchemaGetComponentDesignation(&strA
,
20067 xmlSchemaFormatQName(&strB
,
20068 WXS_PARTICLE_TERM_AS_ELEM(cur
)->targetNamespace
,
20069 WXS_PARTICLE_TERM_AS_ELEM(cur
)->name
));
20070 FREE_AND_NULL(strA
);
20071 FREE_AND_NULL(strB
);
20072 return(XML_SCHEMAP_COS_NONAMBIG
);
20076 case XML_SCHEMA_TYPE_SEQUENCE
: {
20079 case XML_SCHEMA_TYPE_CHOICE
:{
20081 xmlSchemaTreeItemPtr sub;
20083 sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr)
20084 while (sub != NULL) {
20085 ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
20086 ctxtParticle, ctxtElem);
20094 case XML_SCHEMA_TYPE_ALL
:
20096 case XML_SCHEMA_TYPE_GROUP
:
20099 xmlSchemaInternalErr2(ACTXT_CAST pctxt
,
20100 "xmlSchemaCheckElementDeclConsistent",
20101 "found unexpected term of type '%s' in content model",
20102 WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur
)), NULL
);
20105 cur
= (xmlSchemaParticlePtr
) cur
->next
;
20114 * xmlSchemaCheckElementDeclComponent
20115 * @item: an schema element declaration/particle
20116 * @ctxt: a schema parser context
20117 * @name: the name of the attribute
20119 * Validates the value constraints of an element declaration.
20120 * Adds substitution group members.
20123 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl
,
20124 xmlSchemaParserCtxtPtr ctxt
)
20126 if (elemDecl
== NULL
)
20128 if (elemDecl
->flags
& XML_SCHEMAS_ELEM_INTERNAL_CHECKED
)
20130 elemDecl
->flags
|= XML_SCHEMAS_ELEM_INTERNAL_CHECKED
;
20131 if (xmlSchemaCheckElemPropsCorrect(ctxt
, elemDecl
) == 0) {
20133 * Adds substitution group members.
20135 xmlSchemaCheckElemSubstGroup(ctxt
, elemDecl
);
20140 * xmlSchemaResolveModelGroupParticleReferences:
20141 * @particle: a particle component
20142 * @ctxt: a parser context
20144 * Resolves references of a model group's {particles} to
20145 * model group definitions and to element declarations.
20148 xmlSchemaResolveModelGroupParticleReferences(
20149 xmlSchemaParserCtxtPtr ctxt
,
20150 xmlSchemaModelGroupPtr mg
)
20152 xmlSchemaParticlePtr particle
= WXS_MODELGROUP_PARTICLE(mg
);
20153 xmlSchemaQNameRefPtr ref
;
20154 xmlSchemaBasicItemPtr refItem
;
20157 * URGENT TODO: Test this.
20159 while (particle
!= NULL
) {
20160 if ((WXS_PARTICLE_TERM(particle
) == NULL
) ||
20161 ((WXS_PARTICLE_TERM(particle
))->type
!=
20162 XML_SCHEMA_EXTRA_QNAMEREF
))
20164 goto next_particle
;
20166 ref
= WXS_QNAME_CAST
WXS_PARTICLE_TERM(particle
);
20168 * Resolve the reference.
20169 * NULL the {term} by default.
20171 particle
->children
= NULL
;
20173 refItem
= xmlSchemaGetNamedComponent(ctxt
->schema
,
20174 ref
->itemType
, ref
->name
, ref
->targetNamespace
);
20175 if (refItem
== NULL
) {
20176 xmlSchemaPResCompAttrErr(ctxt
, XML_SCHEMAP_SRC_RESOLVE
,
20177 NULL
, WXS_ITEM_NODE(particle
), "ref", ref
->name
,
20178 ref
->targetNamespace
, ref
->itemType
, NULL
);
20179 /* TODO: remove the particle. */
20180 goto next_particle
;
20182 if (refItem
->type
== XML_SCHEMA_TYPE_GROUP
) {
20183 if (WXS_MODELGROUPDEF_MODEL(refItem
) == NULL
)
20184 /* TODO: remove the particle. */
20185 goto next_particle
;
20187 * NOTE that we will assign the model group definition
20188 * itself to the "term" of the particle. This will ease
20189 * the check for circular model group definitions. After
20190 * that the "term" will be assigned the model group of the
20191 * model group definition.
20193 if ((WXS_MODELGROUPDEF_MODEL(refItem
))->type
==
20194 XML_SCHEMA_TYPE_ALL
) {
20196 * SPEC cos-all-limited (1)
20197 * SPEC cos-all-limited (1.2)
20198 * "It appears only as the value of one or both of the
20199 * following properties:"
20200 * (1.1) "the {model group} property of a model group
20202 * (1.2) "the {term} property of a particle [... of] the "
20203 * {content type} of a complex type definition."
20205 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
20206 /* TODO: error code */
20207 XML_SCHEMAP_COS_ALL_LIMITED
,
20208 WXS_ITEM_NODE(particle
), NULL
,
20209 "A model group definition is referenced, but "
20210 "it contains an 'all' model group, which "
20211 "cannot be contained by model groups",
20213 /* TODO: remove the particle. */
20214 goto next_particle
;
20216 particle
->children
= (xmlSchemaTreeItemPtr
) refItem
;
20219 * TODO: Are referenced element declarations the only
20220 * other components we expect here?
20222 particle
->children
= (xmlSchemaTreeItemPtr
) refItem
;
20225 particle
= WXS_PTC_CAST particle
->next
;
20230 xmlSchemaAreValuesEqual(xmlSchemaValPtr x
,
20233 xmlSchemaTypePtr tx
, ty
, ptx
, pty
;
20236 while (x
!= NULL
) {
20238 tx
= xmlSchemaGetBuiltInType(xmlSchemaGetValType(x
));
20239 ty
= xmlSchemaGetBuiltInType(xmlSchemaGetValType(y
));
20240 ptx
= xmlSchemaGetPrimitiveType(tx
);
20241 pty
= xmlSchemaGetPrimitiveType(ty
);
20243 * (1) if a datatype T' is `derived` by `restriction` from an
20244 * atomic datatype T then the `value space` of T' is a subset of
20245 * the `value space` of T. */
20247 * (2) if datatypes T' and T'' are `derived` by `restriction`
20248 * from a common atomic ancestor T then the `value space`s of T'
20249 * and T'' may overlap.
20254 * We assume computed values to be normalized, so do a fast
20255 * string comparison for string based types.
20257 if ((ptx
->builtInType
== XML_SCHEMAS_STRING
) ||
20258 WXS_IS_ANY_SIMPLE_TYPE(ptx
)) {
20260 xmlSchemaValueGetAsString(x
),
20261 xmlSchemaValueGetAsString(y
)))
20264 ret
= xmlSchemaCompareValuesWhtsp(
20265 x
, XML_SCHEMA_WHITESPACE_PRESERVE
,
20266 y
, XML_SCHEMA_WHITESPACE_PRESERVE
);
20275 x
= xmlSchemaValueGetNext(x
);
20277 y
= xmlSchemaValueGetNext(y
);
20280 } else if (xmlSchemaValueGetNext(y
) != NULL
)
20289 * xmlSchemaResolveAttrUseReferences:
20290 * @item: an attribute use
20291 * @ctxt: a parser context
20293 * Resolves the referenced attribute declaration.
20296 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause
,
20297 xmlSchemaParserCtxtPtr ctxt
)
20299 if ((ctxt
== NULL
) || (ause
== NULL
))
20301 if ((ause
->attrDecl
== NULL
) ||
20302 (ause
->attrDecl
->type
!= XML_SCHEMA_EXTRA_QNAMEREF
))
20306 xmlSchemaQNameRefPtr ref
= WXS_QNAME_CAST ause
->attrDecl
;
20309 * TODO: Evaluate, what errors could occur if the declaration is not
20312 ause
->attrDecl
= xmlSchemaGetAttributeDecl(ctxt
->schema
,
20313 ref
->name
, ref
->targetNamespace
);
20314 if (ause
->attrDecl
== NULL
) {
20315 xmlSchemaPResCompAttrErr(ctxt
,
20316 XML_SCHEMAP_SRC_RESOLVE
,
20317 WXS_BASIC_CAST ause
, ause
->node
,
20318 "ref", ref
->name
, ref
->targetNamespace
,
20319 XML_SCHEMA_TYPE_ATTRIBUTE
, NULL
);
20320 return(ctxt
->err
);;
20327 * xmlSchemaCheckAttrUsePropsCorrect:
20328 * @ctxt: a parser context
20329 * @use: an attribute use
20331 * Schema Component Constraint:
20332 * Attribute Use Correct (au-props-correct)
20336 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt
,
20337 xmlSchemaAttributeUsePtr use
)
20339 if ((ctxt
== NULL
) || (use
== NULL
))
20341 if ((use
->defValue
== NULL
) || (WXS_ATTRUSE_DECL(use
) == NULL
) ||
20342 ((WXS_ATTRUSE_DECL(use
))->type
!= XML_SCHEMA_TYPE_ATTRIBUTE
))
20346 * SPEC au-props-correct (1)
20347 * "The values of the properties of an attribute use must be as
20348 * described in the property tableau in The Attribute Use Schema
20349 * Component ($3.5.1), modulo the impact of Missing
20350 * Sub-components ($5.3)."
20353 if (((WXS_ATTRUSE_DECL(use
))->defValue
!= NULL
) &&
20354 ((WXS_ATTRUSE_DECL(use
))->flags
& XML_SCHEMAS_ATTR_FIXED
) &&
20355 ((use
->flags
& XML_SCHEMA_ATTR_USE_FIXED
) == 0))
20357 xmlSchemaPCustomErr(ctxt
,
20358 XML_SCHEMAP_AU_PROPS_CORRECT_2
,
20359 WXS_BASIC_CAST use
, NULL
,
20360 "The attribute declaration has a 'fixed' value constraint "
20361 ", thus the attribute use must also have a 'fixed' value "
20367 * Compute and check the value constraint's value.
20369 if ((use
->defVal
!= NULL
) && (WXS_ATTRUSE_TYPEDEF(use
) != NULL
)) {
20372 * TODO: The spec seems to be missing a check of the
20373 * value constraint of the attribute use. We will do it here.
20376 * SPEC a-props-correct (3)
20378 if (xmlSchemaIsDerivedFromBuiltInType(
20379 WXS_ATTRUSE_TYPEDEF(use
), XML_SCHEMAS_ID
))
20381 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
20382 XML_SCHEMAP_AU_PROPS_CORRECT
,
20383 NULL
, WXS_BASIC_CAST use
,
20384 "Value constraints are not allowed if the type definition "
20385 "is or is derived from xs:ID",
20390 ret
= xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt
,
20391 use
->node
, WXS_ATTRUSE_TYPEDEF(use
),
20392 use
->defValue
, &(use
->defVal
),
20396 PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20397 "calling xmlSchemaVCheckCVCSimpleType()");
20400 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
20401 XML_SCHEMAP_AU_PROPS_CORRECT
,
20402 NULL
, WXS_BASIC_CAST use
,
20403 "The value of the value constraint is not valid",
20409 * SPEC au-props-correct (2)
20410 * "If the {attribute declaration} has a fixed
20411 * {value constraint}, then if the attribute use itself has a
20412 * {value constraint}, it must also be fixed and its value must match
20413 * that of the {attribute declaration}'s {value constraint}."
20415 if (((WXS_ATTRUSE_DECL(use
))->defVal
!= NULL
) &&
20416 (((WXS_ATTRUSE_DECL(use
))->flags
& XML_SCHEMA_ATTR_USE_FIXED
) == 0))
20418 if (! xmlSchemaAreValuesEqual(use
->defVal
,
20419 (WXS_ATTRUSE_DECL(use
))->defVal
))
20421 xmlSchemaPCustomErr(ctxt
,
20422 XML_SCHEMAP_AU_PROPS_CORRECT_2
,
20423 WXS_BASIC_CAST use
, NULL
,
20424 "The 'fixed' value constraint of the attribute use "
20425 "must match the attribute declaration's value "
20427 (WXS_ATTRUSE_DECL(use
))->defValue
);
20438 * xmlSchemaResolveAttrTypeReferences:
20439 * @item: an attribute declaration
20440 * @ctxt: a parser context
20442 * Resolves the referenced type definition component.
20445 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item
,
20446 xmlSchemaParserCtxtPtr ctxt
)
20449 * The simple type definition corresponding to the <simpleType> element
20450 * information item in the [children], if present, otherwise the simple
20451 * type definition `resolved` to by the `actual value` of the type
20452 * [attribute], if present, otherwise the `simple ur-type definition`.
20454 if (item
->flags
& XML_SCHEMAS_ATTR_INTERNAL_RESOLVED
)
20456 item
->flags
|= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED
;
20457 if (item
->subtypes
!= NULL
)
20459 if (item
->typeName
!= NULL
) {
20460 xmlSchemaTypePtr type
;
20462 type
= xmlSchemaGetType(ctxt
->schema
, item
->typeName
,
20464 if ((type
== NULL
) || (! WXS_IS_SIMPLE(type
))) {
20465 xmlSchemaPResCompAttrErr(ctxt
,
20466 XML_SCHEMAP_SRC_RESOLVE
,
20467 WXS_BASIC_CAST item
, item
->node
,
20468 "type", item
->typeName
, item
->typeNs
,
20469 XML_SCHEMA_TYPE_SIMPLE
, NULL
);
20472 item
->subtypes
= type
;
20476 * The type defaults to the xs:anySimpleType.
20478 item
->subtypes
= xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE
);
20484 * xmlSchemaResolveIDCKeyReferences:
20485 * @idc: the identity-constraint definition
20486 * @ctxt: the schema parser context
20487 * @name: the attribute name
20489 * Resolve keyRef references to key/unique IDCs.
20490 * Schema Component Constraint:
20491 * Identity-constraint Definition Properties Correct (c-props-correct)
20494 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc
,
20495 xmlSchemaParserCtxtPtr pctxt
)
20497 if (idc
->type
!= XML_SCHEMA_TYPE_IDC_KEYREF
)
20499 if (idc
->ref
->name
!= NULL
) {
20500 idc
->ref
->item
= (xmlSchemaBasicItemPtr
)
20501 xmlSchemaGetIDC(pctxt
->schema
, idc
->ref
->name
,
20502 idc
->ref
->targetNamespace
);
20503 if (idc
->ref
->item
== NULL
) {
20505 * TODO: It is actually not an error to fail to resolve
20506 * at this stage. BUT we need to be that strict!
20508 xmlSchemaPResCompAttrErr(pctxt
,
20509 XML_SCHEMAP_SRC_RESOLVE
,
20510 WXS_BASIC_CAST idc
, idc
->node
,
20511 "refer", idc
->ref
->name
,
20512 idc
->ref
->targetNamespace
,
20513 XML_SCHEMA_TYPE_IDC_KEY
, NULL
);
20514 return(pctxt
->err
);
20515 } else if (idc
->ref
->item
->type
== XML_SCHEMA_TYPE_IDC_KEYREF
) {
20517 * SPEC c-props-correct (1)
20519 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
20520 XML_SCHEMAP_C_PROPS_CORRECT
,
20521 NULL
, WXS_BASIC_CAST idc
,
20522 "The keyref references a keyref",
20524 idc
->ref
->item
= NULL
;
20525 return(pctxt
->err
);
20527 if (idc
->nbFields
!=
20528 ((xmlSchemaIDCPtr
) idc
->ref
->item
)->nbFields
) {
20529 xmlChar
*str
= NULL
;
20530 xmlSchemaIDCPtr refer
;
20532 refer
= (xmlSchemaIDCPtr
) idc
->ref
->item
;
20534 * SPEC c-props-correct(2)
20535 * "If the {identity-constraint category} is keyref,
20536 * the cardinality of the {fields} must equal that of
20537 * the {fields} of the {referenced key}.
20539 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
20540 XML_SCHEMAP_C_PROPS_CORRECT
,
20541 NULL
, WXS_BASIC_CAST idc
,
20542 "The cardinality of the keyref differs from the "
20543 "cardinality of the referenced key/unique '%s'",
20544 xmlSchemaFormatQName(&str
, refer
->targetNamespace
,
20548 return(pctxt
->err
);
20556 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib
,
20557 xmlSchemaParserCtxtPtr pctxt
)
20559 if (xmlSchemaGetAttributeDecl(pctxt
->schema
, prohib
->name
,
20560 prohib
->targetNamespace
) == NULL
) {
20562 xmlSchemaPResCompAttrErr(pctxt
,
20563 XML_SCHEMAP_SRC_RESOLVE
,
20564 NULL
, prohib
->node
,
20565 "ref", prohib
->name
, prohib
->targetNamespace
,
20566 XML_SCHEMA_TYPE_ATTRIBUTE
, NULL
);
20567 return(XML_SCHEMAP_SRC_RESOLVE
);
20572 #define WXS_REDEFINED_TYPE(c) \
20573 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20575 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20576 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20578 #define WXS_REDEFINED_ATTR_GROUP(c) \
20579 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20582 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt
)
20585 xmlSchemaRedefPtr redef
= WXS_CONSTRUCTOR(pctxt
)->redefs
;
20586 xmlSchemaBasicItemPtr prev
, item
;
20593 item
= redef
->item
;
20595 * First try to locate the redefined component in the
20596 * schema graph starting with the redefined schema.
20597 * NOTE: According to this schema bug entry:
20598 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20599 * it's not clear if the referenced component needs to originate
20600 * from the <redefine>d schema _document_ or the schema; the latter
20601 * would include all imported and included sub-schemas of the
20602 * <redefine>d schema. Currently the latter approach is used.
20603 * SUPPLEMENT: It seems that the WG moves towards the latter
20604 * approach, so we are doing it right.
20607 prev
= xmlSchemaFindRedefCompInGraph(
20608 redef
->targetBucket
, item
->type
,
20609 redef
->refName
, redef
->refTargetNs
);
20610 if (prev
== NULL
) {
20611 xmlChar
*str
= NULL
;
20615 * SPEC src-redefine:
20616 * (6.2.1) "The `actual value` of its own name attribute plus
20617 * target namespace must successfully `resolve` to a model
20618 * group definition in I."
20619 * (7.2.1) "The `actual value` of its own name attribute plus
20620 * target namespace must successfully `resolve` to an attribute
20621 * group definition in I."
20624 * Note that, if we are redefining with the use of references
20625 * to components, the spec assumes the src-resolve to be used;
20626 * but this won't assure that we search only *inside* the
20627 * redefined schema.
20629 if (redef
->reference
)
20630 node
= WXS_ITEM_NODE(redef
->reference
);
20632 node
= WXS_ITEM_NODE(item
);
20633 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
20635 * TODO: error code.
20636 * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20639 XML_SCHEMAP_SRC_REDEFINE
, node
, NULL
,
20640 "The %s '%s' to be redefined could not be found in "
20641 "the redefined schema",
20642 WXS_ITEM_TYPE_NAME(item
),
20643 xmlSchemaFormatQName(&str
, redef
->refTargetNs
,
20645 FREE_AND_NULL(str
);
20647 redef
= redef
->next
;
20651 * TODO: Obtaining and setting the redefinition state is really
20655 switch (item
->type
) {
20656 case XML_SCHEMA_TYPE_COMPLEX
:
20657 case XML_SCHEMA_TYPE_SIMPLE
:
20658 if ((WXS_TYPE_CAST prev
)->flags
&
20659 XML_SCHEMAS_TYPE_REDEFINED
)
20664 /* Mark it as redefined. */
20665 (WXS_TYPE_CAST prev
)->flags
|= XML_SCHEMAS_TYPE_REDEFINED
;
20667 * Assign the redefined type to the
20668 * base type of the redefining type.
20671 ((xmlSchemaTypePtr
) item
)->baseType
=
20672 (xmlSchemaTypePtr
) prev
;
20674 case XML_SCHEMA_TYPE_GROUP
:
20675 if ((WXS_MODEL_GROUPDEF_CAST prev
)->flags
&
20676 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED
)
20681 /* Mark it as redefined. */
20682 (WXS_MODEL_GROUPDEF_CAST prev
)->flags
|=
20683 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED
;
20684 if (redef
->reference
!= NULL
) {
20686 * Overwrite the QName-reference with the
20687 * referenced model group def.
20689 (WXS_PTC_CAST redef
->reference
)->children
=
20690 WXS_TREE_CAST prev
;
20692 redef
->target
= prev
;
20694 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
20695 if ((WXS_ATTR_GROUP_CAST prev
)->flags
&
20696 XML_SCHEMAS_ATTRGROUP_REDEFINED
)
20701 (WXS_ATTR_GROUP_CAST prev
)->flags
|=
20702 XML_SCHEMAS_ATTRGROUP_REDEFINED
;
20703 if (redef
->reference
!= NULL
) {
20705 * Assign the redefined attribute group to the
20706 * QName-reference component.
20707 * This is the easy case, since we will just
20708 * expand the redefined group.
20710 (WXS_QNAME_CAST redef
->reference
)->item
= prev
;
20711 redef
->target
= NULL
;
20714 * This is the complicated case: we need
20715 * to apply src-redefine (7.2.2) at a later
20716 * stage, i.e. when attribute group references
20717 * have been expanded and simple types have
20720 redef
->target
= prev
;
20724 PERROR_INT("xmlSchemaResolveRedefReferences",
20725 "Unexpected redefined component type");
20728 if (wasRedefined
) {
20729 xmlChar
*str
= NULL
;
20732 if (redef
->reference
)
20733 node
= WXS_ITEM_NODE(redef
->reference
);
20735 node
= WXS_ITEM_NODE(redef
->item
);
20737 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
20738 /* TODO: error code. */
20739 XML_SCHEMAP_SRC_REDEFINE
,
20741 "The referenced %s was already redefined. Multiple "
20742 "redefinition of the same component is not supported",
20743 xmlSchemaGetComponentDesignation(&str
, prev
),
20747 redef
= redef
->next
;
20750 redef
= redef
->next
;
20751 } while (redef
!= NULL
);
20757 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt
)
20760 xmlSchemaRedefPtr redef
= WXS_CONSTRUCTOR(pctxt
)->redefs
;
20761 xmlSchemaBasicItemPtr item
;
20767 if (redef
->target
== NULL
) {
20768 redef
= redef
->next
;
20771 item
= redef
->item
;
20773 switch (item
->type
) {
20774 case XML_SCHEMA_TYPE_SIMPLE
:
20775 case XML_SCHEMA_TYPE_COMPLEX
:
20777 * Since the spec wants the {name} of the redefined
20778 * type to be 'absent', we'll NULL it.
20780 (WXS_TYPE_CAST redef
->target
)->name
= NULL
;
20783 * TODO: Seems like there's nothing more to do. The normal
20784 * inheritance mechanism is used. But not 100% sure.
20787 case XML_SCHEMA_TYPE_GROUP
:
20790 * SPEC src-redefine:
20791 * (6.2.2) "The {model group} of the model group definition
20792 * which corresponds to it per XML Representation of Model
20793 * Group Definition Schema Components ($3.7.2) must be a
20794 * `valid restriction` of the {model group} of that model
20795 * group definition in I, as defined in Particle Valid
20796 * (Restriction) ($3.9.6)."
20799 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
20801 * SPEC src-redefine:
20802 * (7.2.2) "The {attribute uses} and {attribute wildcard} of
20803 * the attribute group definition which corresponds to it
20804 * per XML Representation of Attribute Group Definition Schema
20805 * Components ($3.6.2) must be `valid restrictions` of the
20806 * {attribute uses} and {attribute wildcard} of that attribute
20807 * group definition in I, as defined in clause 2, clause 3 and
20808 * clause 4 of Derivation Valid (Restriction, Complex)
20809 * ($3.4.6) (where references to the base type definition are
20810 * understood as references to the attribute group definition
20813 err
= xmlSchemaCheckDerivationOKRestriction2to4(pctxt
,
20814 XML_SCHEMA_ACTION_REDEFINE
,
20815 item
, redef
->target
,
20816 (WXS_ATTR_GROUP_CAST item
)->attrUses
,
20817 (WXS_ATTR_GROUP_CAST redef
->target
)->attrUses
,
20818 (WXS_ATTR_GROUP_CAST item
)->attributeWildcard
,
20819 (WXS_ATTR_GROUP_CAST redef
->target
)->attributeWildcard
);
20826 redef
= redef
->next
;
20827 } while (redef
!= NULL
);
20833 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt
,
20834 xmlSchemaBucketPtr bucket
)
20836 xmlSchemaBasicItemPtr item
;
20838 xmlHashTablePtr
*table
;
20839 const xmlChar
*name
;
20842 #define WXS_GET_GLOBAL_HASH(c, slot) { \
20843 if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20844 table = &(WXS_IMPBUCKET((c))->schema->slot); \
20846 table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20849 * Add global components to the schema's hash tables.
20850 * This is the place where duplicate components will be
20852 * TODO: I think normally we should support imports of the
20853 * same namespace from multiple locations. We don't do currently,
20854 * but if we do then according to:
20855 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20856 * we would need, if imported directly, to import redefined
20857 * components as well to be able to catch clashing components.
20858 * (I hope I'll still know what this means after some months :-()
20860 if (bucket
== NULL
)
20862 if (bucket
->flags
& XML_SCHEMA_BUCKET_COMPS_ADDED
)
20864 bucket
->flags
|= XML_SCHEMA_BUCKET_COMPS_ADDED
;
20866 for (i
= 0; i
< bucket
->globals
->nbItems
; i
++) {
20867 item
= bucket
->globals
->items
[i
];
20869 switch (item
->type
) {
20870 case XML_SCHEMA_TYPE_COMPLEX
:
20871 case XML_SCHEMA_TYPE_SIMPLE
:
20872 if (WXS_REDEFINED_TYPE(item
))
20874 name
= (WXS_TYPE_CAST item
)->name
;
20875 WXS_GET_GLOBAL_HASH(bucket
, typeDecl
)
20877 case XML_SCHEMA_TYPE_ELEMENT
:
20878 name
= (WXS_ELEM_CAST item
)->name
;
20879 WXS_GET_GLOBAL_HASH(bucket
, elemDecl
)
20881 case XML_SCHEMA_TYPE_ATTRIBUTE
:
20882 name
= (WXS_ATTR_CAST item
)->name
;
20883 WXS_GET_GLOBAL_HASH(bucket
, attrDecl
)
20885 case XML_SCHEMA_TYPE_GROUP
:
20886 if (WXS_REDEFINED_MODEL_GROUP_DEF(item
))
20888 name
= (WXS_MODEL_GROUPDEF_CAST item
)->name
;
20889 WXS_GET_GLOBAL_HASH(bucket
, groupDecl
)
20891 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
20892 if (WXS_REDEFINED_ATTR_GROUP(item
))
20894 name
= (WXS_ATTR_GROUP_CAST item
)->name
;
20895 WXS_GET_GLOBAL_HASH(bucket
, attrgrpDecl
)
20897 case XML_SCHEMA_TYPE_IDC_KEY
:
20898 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
20899 case XML_SCHEMA_TYPE_IDC_KEYREF
:
20900 name
= (WXS_IDC_CAST item
)->name
;
20901 WXS_GET_GLOBAL_HASH(bucket
, idcDef
)
20903 case XML_SCHEMA_TYPE_NOTATION
:
20904 name
= ((xmlSchemaNotationPtr
) item
)->name
;
20905 WXS_GET_GLOBAL_HASH(bucket
, notaDecl
)
20908 PERROR_INT("xmlSchemaAddComponents",
20909 "Unexpected global component type");
20912 if (*table
== NULL
) {
20913 *table
= xmlHashCreateDict(10, pctxt
->dict
);
20914 if (*table
== NULL
) {
20915 PERROR_INT("xmlSchemaAddComponents",
20916 "failed to create a component hash table");
20920 err
= xmlHashAddEntry(*table
, name
, item
);
20922 xmlChar
*str
= NULL
;
20924 xmlSchemaCustomErr(ACTXT_CAST pctxt
,
20925 XML_SCHEMAP_REDEFINED_TYPE
,
20926 WXS_ITEM_NODE(item
),
20927 WXS_BASIC_CAST item
,
20928 "A global %s '%s' does already exist",
20929 WXS_ITEM_TYPE_NAME(item
),
20930 xmlSchemaGetComponentQName(&str
, item
));
20931 FREE_AND_NULL(str
);
20935 * Process imported/included schemas.
20937 if (bucket
->relations
!= NULL
) {
20938 xmlSchemaSchemaRelationPtr rel
= bucket
->relations
;
20940 if ((rel
->bucket
!= NULL
) &&
20941 ((rel
->bucket
->flags
& XML_SCHEMA_BUCKET_COMPS_ADDED
) == 0)) {
20942 if (xmlSchemaAddComponents(pctxt
, rel
->bucket
) == -1)
20946 } while (rel
!= NULL
);
20952 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt
,
20953 xmlSchemaBucketPtr rootBucket
)
20955 xmlSchemaConstructionCtxtPtr con
= pctxt
->constructor
;
20956 xmlSchemaTreeItemPtr item
, *items
;
20957 int nbItems
, i
, ret
= 0;
20958 xmlSchemaBucketPtr oldbucket
= con
->bucket
;
20959 xmlSchemaElementPtr elemDecl
;
20961 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20963 if ((con
->pending
== NULL
) ||
20964 (con
->pending
->nbItems
== 0))
20968 * Since xmlSchemaFixupComplexType() will create new particles
20969 * (local components), and those particle components need a bucket
20970 * on the constructor, we'll assure here that the constructor has
20972 * TODO: Think about storing locals _only_ on the main bucket.
20974 if (con
->bucket
== NULL
)
20975 con
->bucket
= rootBucket
;
20978 * SPEC (src-redefine):
20979 * (6.2) "If it has no such self-reference, then all of the
20980 * following must be true:"
20982 * (6.2.2) The {model group} of the model group definition which
20983 * corresponds to it per XML Representation of Model Group
20984 * Definition Schema Components ($3.7.2) must be a `valid
20985 * restriction` of the {model group} of that model group definition
20986 * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
20988 xmlSchemaCheckSRCRedefineFirst(pctxt
);
20991 * Add global components to the schemata's hash tables.
20993 xmlSchemaAddComponents(pctxt
, rootBucket
);
20995 pctxt
->ctxtType
= NULL
;
20996 items
= (xmlSchemaTreeItemPtr
*) con
->pending
->items
;
20997 nbItems
= con
->pending
->nbItems
;
20999 * Now that we have parsed *all* the schema document(s) and converted
21000 * them to schema components, we can resolve references, apply component
21001 * constraints, create the FSA from the content model, etc.
21004 * Resolve references of..
21006 * 1. element declarations:
21007 * - the type definition
21008 * - the substitution group affiliation
21009 * 2. simple/complex types:
21010 * - the base type definition
21011 * - the memberTypes of union types
21012 * - the itemType of list types
21013 * 3. attributes declarations and attribute uses:
21014 * - the type definition
21015 * - if an attribute use, then the attribute declaration
21016 * 4. attribute group references:
21017 * - the attribute group definition
21019 * - the term of the particle (e.g. a model group)
21020 * 6. IDC key-references:
21021 * - the referenced IDC 'key' or 'unique' definition
21022 * 7. Attribute prohibitions which had a "ref" attribute.
21024 for (i
= 0; i
< nbItems
; i
++) {
21026 switch (item
->type
) {
21027 case XML_SCHEMA_TYPE_ELEMENT
:
21028 xmlSchemaResolveElementReferences(
21029 (xmlSchemaElementPtr
) item
, pctxt
);
21032 case XML_SCHEMA_TYPE_COMPLEX
:
21033 case XML_SCHEMA_TYPE_SIMPLE
:
21034 xmlSchemaResolveTypeReferences(
21035 (xmlSchemaTypePtr
) item
, pctxt
);
21038 case XML_SCHEMA_TYPE_ATTRIBUTE
:
21039 xmlSchemaResolveAttrTypeReferences(
21040 (xmlSchemaAttributePtr
) item
, pctxt
);
21043 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
21044 xmlSchemaResolveAttrUseReferences(
21045 (xmlSchemaAttributeUsePtr
) item
, pctxt
);
21048 case XML_SCHEMA_EXTRA_QNAMEREF
:
21049 if ((WXS_QNAME_CAST item
)->itemType
==
21050 XML_SCHEMA_TYPE_ATTRIBUTEGROUP
)
21052 xmlSchemaResolveAttrGroupReferences(
21053 WXS_QNAME_CAST item
, pctxt
);
21057 case XML_SCHEMA_TYPE_SEQUENCE
:
21058 case XML_SCHEMA_TYPE_CHOICE
:
21059 case XML_SCHEMA_TYPE_ALL
:
21060 xmlSchemaResolveModelGroupParticleReferences(pctxt
,
21061 WXS_MODEL_GROUP_CAST item
);
21064 case XML_SCHEMA_TYPE_IDC_KEY
:
21065 case XML_SCHEMA_TYPE_IDC_UNIQUE
:
21066 case XML_SCHEMA_TYPE_IDC_KEYREF
:
21067 xmlSchemaResolveIDCKeyReferences(
21068 (xmlSchemaIDCPtr
) item
, pctxt
);
21071 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB
:
21073 * Handle attribute prohibition which had a
21076 xmlSchemaResolveAttrUseProhibReferences(
21077 WXS_ATTR_PROHIB_CAST item
, pctxt
);
21084 if (pctxt
->nberrors
!= 0)
21088 * Now that all references are resolved we
21089 * can check for circularity of...
21090 * 1. the base axis of type definitions
21091 * 2. nested model group definitions
21092 * 3. nested attribute group definitions
21093 * TODO: check for circular substitution groups.
21095 for (i
= 0; i
< nbItems
; i
++) {
21098 * Let's better stop on the first error here.
21100 switch (item
->type
) {
21101 case XML_SCHEMA_TYPE_COMPLEX
:
21102 case XML_SCHEMA_TYPE_SIMPLE
:
21103 xmlSchemaCheckTypeDefCircular(
21104 (xmlSchemaTypePtr
) item
, pctxt
);
21106 if (pctxt
->nberrors
!= 0)
21109 case XML_SCHEMA_TYPE_GROUP
:
21110 xmlSchemaCheckGroupDefCircular(
21111 (xmlSchemaModelGroupDefPtr
) item
, pctxt
);
21113 if (pctxt
->nberrors
!= 0)
21116 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
21117 xmlSchemaCheckAttrGroupCircular(
21118 (xmlSchemaAttributeGroupPtr
) item
, pctxt
);
21120 if (pctxt
->nberrors
!= 0)
21127 if (pctxt
->nberrors
!= 0)
21130 * Model group definition references:
21131 * Such a reference is reflected by a particle at the component
21132 * level. Until now the 'term' of such particles pointed
21133 * to the model group definition; this was done, in order to
21134 * ease circularity checks. Now we need to set the 'term' of
21135 * such particles to the model group of the model group definition.
21137 for (i
= 0; i
< nbItems
; i
++) {
21139 switch (item
->type
) {
21140 case XML_SCHEMA_TYPE_SEQUENCE
:
21141 case XML_SCHEMA_TYPE_CHOICE
:
21142 xmlSchemaModelGroupToModelGroupDefFixup(pctxt
,
21143 WXS_MODEL_GROUP_CAST item
);
21149 if (pctxt
->nberrors
!= 0)
21152 * Expand attribute group references of attribute group definitions.
21154 for (i
= 0; i
< nbItems
; i
++) {
21156 switch (item
->type
) {
21157 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
21158 if ((! WXS_ATTR_GROUP_EXPANDED(item
)) &&
21159 WXS_ATTR_GROUP_HAS_REFS(item
))
21161 xmlSchemaAttributeGroupExpandRefs(pctxt
,
21162 WXS_ATTR_GROUP_CAST item
);
21170 if (pctxt
->nberrors
!= 0)
21173 * First compute the variety of simple types. This is needed as
21174 * a separate step, since otherwise we won't be able to detect
21175 * circular union types in all cases.
21177 for (i
= 0; i
< nbItems
; i
++) {
21179 switch (item
->type
) {
21180 case XML_SCHEMA_TYPE_SIMPLE
:
21181 if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr
) item
)) {
21182 xmlSchemaFixupSimpleTypeStageOne(pctxt
,
21183 (xmlSchemaTypePtr
) item
);
21191 if (pctxt
->nberrors
!= 0)
21194 * Detect circular union types. Note that this needs the variety to
21195 * be already computed.
21197 for (i
= 0; i
< nbItems
; i
++) {
21199 switch (item
->type
) {
21200 case XML_SCHEMA_TYPE_SIMPLE
:
21201 if (((xmlSchemaTypePtr
) item
)->memberTypes
!= NULL
) {
21202 xmlSchemaCheckUnionTypeDefCircular(pctxt
,
21203 (xmlSchemaTypePtr
) item
);
21211 if (pctxt
->nberrors
!= 0)
21215 * Do the complete type fixup for simple types.
21217 for (i
= 0; i
< nbItems
; i
++) {
21219 switch (item
->type
) {
21220 case XML_SCHEMA_TYPE_SIMPLE
:
21221 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item
)) {
21222 xmlSchemaFixupSimpleTypeStageTwo(pctxt
, WXS_TYPE_CAST item
);
21230 if (pctxt
->nberrors
!= 0)
21233 * At this point we need build and check all simple types.
21236 * Apply constraints for attribute declarations.
21238 for (i
= 0; i
< nbItems
; i
++) {
21240 switch (item
->type
) {
21241 case XML_SCHEMA_TYPE_ATTRIBUTE
:
21242 xmlSchemaCheckAttrPropsCorrect(pctxt
, WXS_ATTR_CAST item
);
21249 if (pctxt
->nberrors
!= 0)
21252 * Apply constraints for attribute uses.
21254 for (i
= 0; i
< nbItems
; i
++) {
21256 switch (item
->type
) {
21257 case XML_SCHEMA_TYPE_ATTRIBUTE_USE
:
21258 if (((xmlSchemaAttributeUsePtr
)item
)->defValue
!= NULL
) {
21259 xmlSchemaCheckAttrUsePropsCorrect(pctxt
,
21260 WXS_ATTR_USE_CAST item
);
21268 if (pctxt
->nberrors
!= 0)
21272 * Apply constraints for attribute group definitions.
21274 for (i
= 0; i
< nbItems
; i
++) {
21276 switch (item
->type
) {
21277 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP
:
21278 if (( (WXS_ATTR_GROUP_CAST item
)->attrUses
!= NULL
) &&
21279 ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item
)->attrUses
)->nbItems
> 1))
21281 xmlSchemaCheckAGPropsCorrect(pctxt
, WXS_ATTR_GROUP_CAST item
);
21289 if (pctxt
->nberrors
!= 0)
21293 * Apply constraints for redefinitions.
21295 if (WXS_CONSTRUCTOR(pctxt
)->redefs
!= NULL
)
21296 xmlSchemaCheckSRCRedefineSecond(pctxt
);
21297 if (pctxt
->nberrors
!= 0)
21301 * Complex types are built and checked.
21303 for (i
= 0; i
< nbItems
; i
++) {
21304 item
= con
->pending
->items
[i
];
21305 switch (item
->type
) {
21306 case XML_SCHEMA_TYPE_COMPLEX
:
21307 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item
)) {
21308 xmlSchemaFixupComplexType(pctxt
, WXS_TYPE_CAST item
);
21316 if (pctxt
->nberrors
!= 0)
21320 * The list could have changed, since xmlSchemaFixupComplexType()
21321 * will create particles and model groups in some cases.
21323 items
= (xmlSchemaTreeItemPtr
*) con
->pending
->items
;
21324 nbItems
= con
->pending
->nbItems
;
21327 * Apply some constraints for element declarations.
21329 for (i
= 0; i
< nbItems
; i
++) {
21331 switch (item
->type
) {
21332 case XML_SCHEMA_TYPE_ELEMENT
:
21333 elemDecl
= (xmlSchemaElementPtr
) item
;
21335 if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_INTERNAL_CHECKED
) == 0)
21337 xmlSchemaCheckElementDeclComponent(
21338 (xmlSchemaElementPtr
) elemDecl
, pctxt
);
21342 #ifdef WXS_ELEM_DECL_CONS_ENABLED
21344 * Schema Component Constraint: Element Declarations Consistent
21345 * Apply this constraint to local types of element declarations.
21347 if ((WXS_ELEM_TYPEDEF(elemDecl
) != NULL
) &&
21348 (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl
))) &&
21349 (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl
))))
21351 xmlSchemaCheckElementDeclConsistent(pctxt
,
21352 WXS_BASIC_CAST elemDecl
,
21353 WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl
)),
21362 if (pctxt
->nberrors
!= 0)
21366 * Finally we can build the automaton from the content model of
21370 for (i
= 0; i
< nbItems
; i
++) {
21372 switch (item
->type
) {
21373 case XML_SCHEMA_TYPE_COMPLEX
:
21374 xmlSchemaBuildContentModel((xmlSchemaTypePtr
) item
, pctxt
);
21381 if (pctxt
->nberrors
!= 0)
21384 * URGENT TODO: cos-element-consistent
21397 * Reset the constructor. This is needed for XSI acquisition, since
21398 * those items will be processed over and over again for every XSI
21399 * if not cleared here.
21401 con
->bucket
= oldbucket
;
21402 con
->pending
->nbItems
= 0;
21403 if (con
->substGroups
!= NULL
) {
21404 xmlHashFree(con
->substGroups
, xmlSchemaSubstGroupFreeEntry
);
21405 con
->substGroups
= NULL
;
21407 if (con
->redefs
!= NULL
) {
21408 xmlSchemaRedefListFree(con
->redefs
);
21409 con
->redefs
= NULL
;
21415 * @ctxt: a schema validation context
21417 * parse a schema definition resource and build an internal
21418 * XML Schema structure which can be used to validate instances.
21420 * Returns the internal XML Schema structure built from the resource or
21421 * NULL in case of error
21424 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt
)
21426 xmlSchemaPtr mainSchema
= NULL
;
21427 xmlSchemaBucketPtr bucket
= NULL
;
21431 * This one is used if the schema to be parsed was specified via
21432 * the API; i.e. not automatically by the validated instance document.
21435 xmlSchemaInitTypes();
21440 /* TODO: Init the context. Is this all we need?*/
21441 ctxt
->nberrors
= 0;
21445 /* Create the *main* schema. */
21446 mainSchema
= xmlSchemaNewSchema(ctxt
);
21447 if (mainSchema
== NULL
)
21450 * Create the schema constructor.
21452 if (ctxt
->constructor
== NULL
) {
21453 ctxt
->constructor
= xmlSchemaConstructionCtxtCreate(ctxt
->dict
);
21454 if (ctxt
->constructor
== NULL
)
21456 /* Take ownership of the constructor to be able to free it. */
21457 ctxt
->ownsConstructor
= 1;
21459 ctxt
->constructor
->mainSchema
= mainSchema
;
21461 * Locate and add the schema document.
21463 res
= xmlSchemaAddSchemaDoc(ctxt
, XML_SCHEMA_SCHEMA_MAIN
,
21464 ctxt
->URL
, ctxt
->doc
, ctxt
->buffer
, ctxt
->size
, NULL
,
21465 NULL
, NULL
, &bucket
);
21471 if (bucket
== NULL
) {
21472 /* TODO: Error code, actually we failed to *locate* the schema. */
21474 xmlSchemaCustomErr(ACTXT_CAST ctxt
, XML_SCHEMAP_FAILED_LOAD
,
21476 "Failed to locate the main schema resource at '%s'",
21479 xmlSchemaCustomErr(ACTXT_CAST ctxt
, XML_SCHEMAP_FAILED_LOAD
,
21481 "Failed to locate the main schema resource",
21485 /* Then do the parsing for good. */
21486 if (xmlSchemaParseNewDocWithContext(ctxt
, mainSchema
, bucket
) == -1)
21488 if (ctxt
->nberrors
!= 0)
21491 mainSchema
->doc
= bucket
->doc
;
21492 mainSchema
->preserve
= ctxt
->preserve
;
21494 ctxt
->schema
= mainSchema
;
21496 if (xmlSchemaFixupComponents(ctxt
, WXS_CONSTRUCTOR(ctxt
)->mainBucket
) == -1)
21500 * TODO: This is not nice, since we cannot distinguish from the
21501 * result if there was an internal error or not.
21504 if (ctxt
->nberrors
!= 0) {
21506 xmlSchemaFree(mainSchema
);
21509 if (ctxt
->constructor
) {
21510 xmlSchemaConstructionCtxtFree(ctxt
->constructor
);
21511 ctxt
->constructor
= NULL
;
21512 ctxt
->ownsConstructor
= 0;
21515 ctxt
->schema
= NULL
;
21516 return(mainSchema
);
21519 * Quite verbose, but should catch internal errors, which were
21520 * not communicated.
21523 xmlSchemaFree(mainSchema
);
21526 if (ctxt
->constructor
) {
21527 xmlSchemaConstructionCtxtFree(ctxt
->constructor
);
21528 ctxt
->constructor
= NULL
;
21529 ctxt
->ownsConstructor
= 0;
21531 PERROR_INT2("xmlSchemaParse",
21532 "An internal error occurred");
21533 ctxt
->schema
= NULL
;
21538 * xmlSchemaSetParserErrors:
21539 * @ctxt: a schema validation context
21540 * @err: the error callback
21541 * @warn: the warning callback
21542 * @ctx: contextual data for the callbacks
21544 * Set the callback functions used to handle errors for a validation context
21547 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt
,
21548 xmlSchemaValidityErrorFunc err
,
21549 xmlSchemaValidityWarningFunc warn
, void *ctx
)
21554 ctxt
->warning
= warn
;
21555 ctxt
->errCtxt
= ctx
;
21556 if (ctxt
->vctxt
!= NULL
)
21557 xmlSchemaSetValidErrors(ctxt
->vctxt
, err
, warn
, ctx
);
21561 * xmlSchemaSetParserStructuredErrors:
21562 * @ctxt: a schema parser context
21563 * @serror: the structured error function
21564 * @ctx: the functions context
21566 * Set the structured error callback
21569 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt
,
21570 xmlStructuredErrorFunc serror
,
21575 ctxt
->serror
= serror
;
21576 ctxt
->errCtxt
= ctx
;
21577 if (ctxt
->vctxt
!= NULL
)
21578 xmlSchemaSetValidStructuredErrors(ctxt
->vctxt
, serror
, ctx
);
21582 * xmlSchemaGetParserErrors:
21583 * @ctxt: a XMl-Schema parser context
21584 * @err: the error callback result
21585 * @warn: the warning callback result
21586 * @ctx: contextual data for the callbacks result
21588 * Get the callback information used to handle errors for a parser context
21590 * Returns -1 in case of failure, 0 otherwise
21593 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt
,
21594 xmlSchemaValidityErrorFunc
* err
,
21595 xmlSchemaValidityWarningFunc
* warn
, void **ctx
)
21600 *err
= ctxt
->error
;
21602 *warn
= ctxt
->warning
;
21604 *ctx
= ctxt
->errCtxt
;
21609 * xmlSchemaFacetTypeToString:
21610 * @type: the facet type
21612 * Convert the xmlSchemaTypeType to a char string.
21614 * Returns the char string representation of the facet type if the
21615 * type is a facet and an "Internal Error" string otherwise.
21617 static const xmlChar
*
21618 xmlSchemaFacetTypeToString(xmlSchemaTypeType type
)
21621 case XML_SCHEMA_FACET_PATTERN
:
21622 return (BAD_CAST
"pattern");
21623 case XML_SCHEMA_FACET_MAXEXCLUSIVE
:
21624 return (BAD_CAST
"maxExclusive");
21625 case XML_SCHEMA_FACET_MAXINCLUSIVE
:
21626 return (BAD_CAST
"maxInclusive");
21627 case XML_SCHEMA_FACET_MINEXCLUSIVE
:
21628 return (BAD_CAST
"minExclusive");
21629 case XML_SCHEMA_FACET_MININCLUSIVE
:
21630 return (BAD_CAST
"minInclusive");
21631 case XML_SCHEMA_FACET_WHITESPACE
:
21632 return (BAD_CAST
"whiteSpace");
21633 case XML_SCHEMA_FACET_ENUMERATION
:
21634 return (BAD_CAST
"enumeration");
21635 case XML_SCHEMA_FACET_LENGTH
:
21636 return (BAD_CAST
"length");
21637 case XML_SCHEMA_FACET_MAXLENGTH
:
21638 return (BAD_CAST
"maxLength");
21639 case XML_SCHEMA_FACET_MINLENGTH
:
21640 return (BAD_CAST
"minLength");
21641 case XML_SCHEMA_FACET_TOTALDIGITS
:
21642 return (BAD_CAST
"totalDigits");
21643 case XML_SCHEMA_FACET_FRACTIONDIGITS
:
21644 return (BAD_CAST
"fractionDigits");
21648 return (BAD_CAST
"Internal Error");
21651 static xmlSchemaWhitespaceValueType
21652 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type
)
21655 * The normalization type can be changed only for types which are derived
21658 if (type
->type
== XML_SCHEMA_TYPE_BASIC
) {
21660 * Note that we assume a whitespace of preserve for anySimpleType.
21662 if ((type
->builtInType
== XML_SCHEMAS_STRING
) ||
21663 (type
->builtInType
== XML_SCHEMAS_ANYSIMPLETYPE
))
21664 return(XML_SCHEMA_WHITESPACE_PRESERVE
);
21665 else if (type
->builtInType
== XML_SCHEMAS_NORMSTRING
)
21666 return(XML_SCHEMA_WHITESPACE_REPLACE
);
21669 * For all `atomic` datatypes other than string (and types `derived`
21670 * by `restriction` from it) the value of whiteSpace is fixed to
21672 * Note that this includes built-in list datatypes.
21674 return(XML_SCHEMA_WHITESPACE_COLLAPSE
);
21676 } else if (WXS_IS_LIST(type
)) {
21678 * For list types the facet "whiteSpace" is fixed to "collapse".
21680 return (XML_SCHEMA_WHITESPACE_COLLAPSE
);
21681 } else if (WXS_IS_UNION(type
)) {
21682 return (XML_SCHEMA_WHITESPACE_UNKNOWN
);
21683 } else if (WXS_IS_ATOMIC(type
)) {
21684 if (type
->flags
& XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE
)
21685 return (XML_SCHEMA_WHITESPACE_PRESERVE
);
21686 else if (type
->flags
& XML_SCHEMAS_TYPE_WHITESPACE_REPLACE
)
21687 return (XML_SCHEMA_WHITESPACE_REPLACE
);
21689 return (XML_SCHEMA_WHITESPACE_COLLAPSE
);
21694 /************************************************************************
21696 * Simple type validation *
21698 ************************************************************************/
21701 /************************************************************************
21703 * DOM Validation code *
21705 ************************************************************************/
21708 * xmlSchemaAssembleByLocation:
21709 * @pctxt: a schema parser context
21710 * @vctxt: a schema validation context
21711 * @schema: the existing schema
21712 * @node: the node that fired the assembling
21713 * @nsName: the namespace name of the new schema
21714 * @location: the location of the schema
21716 * Expands an existing schema by an additional schema.
21718 * Returns 0 if the new schema is correct, a positive error code
21719 * number otherwise and -1 in case of an internal or API error.
21722 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt
,
21723 xmlSchemaPtr schema
,
21725 const xmlChar
*nsName
,
21726 const xmlChar
*location
)
21729 xmlSchemaParserCtxtPtr pctxt
;
21730 xmlSchemaBucketPtr bucket
= NULL
;
21732 if ((vctxt
== NULL
) || (schema
== NULL
))
21735 if (vctxt
->pctxt
== NULL
) {
21736 VERROR_INT("xmlSchemaAssembleByLocation",
21737 "no parser context available");
21740 pctxt
= vctxt
->pctxt
;
21741 if (pctxt
->constructor
== NULL
) {
21742 PERROR_INT("xmlSchemaAssembleByLocation",
21747 * Acquire the schema document.
21749 location
= xmlSchemaBuildAbsoluteURI(pctxt
->dict
,
21752 * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21753 * the process will automatically change this to
21754 * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21756 ret
= xmlSchemaAddSchemaDoc(pctxt
, XML_SCHEMA_SCHEMA_IMPORT
,
21757 location
, NULL
, NULL
, 0, node
, NULL
, nsName
,
21761 if (bucket
== NULL
) {
21763 * Generate a warning that the document could not be located.
21765 xmlSchemaCustomWarning(ACTXT_CAST vctxt
, XML_SCHEMAV_MISC
,
21767 "The document at location '%s' could not be acquired",
21768 location
, NULL
, NULL
);
21772 * The first located schema will be handled as if all other
21773 * schemas imported by XSI were imported by this first schema.
21775 if ((bucket
!= NULL
) &&
21776 (WXS_CONSTRUCTOR(pctxt
)->bucket
== NULL
))
21777 WXS_CONSTRUCTOR(pctxt
)->bucket
= bucket
;
21779 * TODO: Is this handled like an import? I.e. is it not an error
21780 * if the schema cannot be located?
21782 if ((bucket
== NULL
) || (! CAN_PARSE_SCHEMA(bucket
)))
21785 * We will reuse the parser context for every schema imported
21786 * directly via XSI. So reset the context.
21788 pctxt
->nberrors
= 0;
21790 pctxt
->doc
= bucket
->doc
;
21792 ret
= xmlSchemaParseNewDocWithContext(pctxt
, schema
, bucket
);
21797 /* Paranoid error channelling. */
21798 if ((ret
== 0) && (pctxt
->nberrors
!= 0))
21800 if (pctxt
->nberrors
== 0) {
21802 * Only bother to fixup pending components, if there was
21804 * For every XSI acquired schema (and its sub-schemata) we will
21805 * fixup the components.
21807 xmlSchemaFixupComponents(pctxt
, bucket
);
21810 * Not nice, but we need somehow to channel the schema parser
21811 * error to the validation context.
21813 if ((ret
!= 0) && (vctxt
->err
== 0))
21815 vctxt
->nberrors
+= pctxt
->nberrors
;
21817 /* Add to validation error sum. */
21818 vctxt
->nberrors
+= pctxt
->nberrors
;
21827 static xmlSchemaAttrInfoPtr
21828 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt
,
21831 if (vctxt
->nbAttrInfos
== 0)
21835 xmlSchemaAttrInfoPtr iattr
;
21837 for (i
= 0; i
< vctxt
->nbAttrInfos
; i
++) {
21838 iattr
= vctxt
->attrInfos
[i
];
21839 if (iattr
->metaType
== metaType
)
21848 * xmlSchemaAssembleByXSI:
21849 * @vctxt: a schema validation context
21851 * Expands an existing schema by an additional schema using
21852 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21853 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21854 * must be set to 1.
21856 * Returns 0 if the new schema is correct, a positive error code
21857 * number otherwise and -1 in case of an internal or API error.
21860 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt
)
21862 const xmlChar
*cur
, *end
;
21863 const xmlChar
*nsname
= NULL
, *location
;
21866 xmlSchemaAttrInfoPtr iattr
;
21869 * Parse the value; we will assume an even number of values
21870 * to be given (this is how Xerces and XSV work).
21872 * URGENT TODO: !! This needs to work for both
21873 * @noNamespaceSchemaLocation AND @schemaLocation on the same
21876 iattr
= xmlSchemaGetMetaAttrInfo(vctxt
,
21877 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC
);
21879 iattr
= xmlSchemaGetMetaAttrInfo(vctxt
,
21880 XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC
);
21883 cur
= iattr
->value
;
21886 * TODO: Move the string parsing mechanism away from here.
21888 if (iattr
->metaType
== XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC
) {
21890 * Get the namespace name.
21892 while (IS_BLANK_CH(*cur
))
21895 while ((*end
!= 0) && (!(IS_BLANK_CH(*end
))))
21899 count
++; /* TODO: Don't use the schema's dict. */
21900 nsname
= xmlDictLookup(vctxt
->schema
->dict
, cur
, end
- cur
);
21906 while (IS_BLANK_CH(*cur
))
21909 while ((*end
!= 0) && (!(IS_BLANK_CH(*end
))))
21912 if (iattr
->metaType
==
21913 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC
)
21916 * If using @schemaLocation then tuples are expected.
21917 * I.e. the namespace name *and* the document's URI.
21919 xmlSchemaCustomWarning(ACTXT_CAST vctxt
, XML_SCHEMAV_MISC
,
21921 "The value must consist of tuples: the target namespace "
21922 "name and the document's URI", NULL
, NULL
, NULL
);
21926 count
++; /* TODO: Don't use the schema's dict. */
21927 location
= xmlDictLookup(vctxt
->schema
->dict
, cur
, end
- cur
);
21929 ret
= xmlSchemaAssembleByLocation(vctxt
, vctxt
->schema
,
21930 iattr
->node
, nsname
, location
);
21932 VERROR_INT("xmlSchemaAssembleByXSI",
21933 "assembling schemata");
21936 } while (*cur
!= 0);
21940 static const xmlChar
*
21941 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt
,
21942 const xmlChar
*prefix
)
21944 if (vctxt
->sax
!= NULL
) {
21946 xmlSchemaNodeInfoPtr inode
;
21948 for (i
= vctxt
->depth
; i
>= 0; i
--) {
21949 if (vctxt
->elemInfos
[i
]->nbNsBindings
!= 0) {
21950 inode
= vctxt
->elemInfos
[i
];
21951 for (j
= 0; j
< inode
->nbNsBindings
* 2; j
+= 2) {
21952 if (((prefix
== NULL
) &&
21953 (inode
->nsBindings
[j
] == NULL
)) ||
21954 ((prefix
!= NULL
) && xmlStrEqual(prefix
,
21955 inode
->nsBindings
[j
]))) {
21958 * Note that the namespace bindings are already
21959 * in a string dict.
21961 return (inode
->nsBindings
[j
+1]);
21967 #ifdef LIBXML_READER_ENABLED
21968 } else if (vctxt
->reader
!= NULL
) {
21971 nsName
= xmlTextReaderLookupNamespace(vctxt
->reader
, prefix
);
21972 if (nsName
!= NULL
) {
21973 const xmlChar
*ret
;
21975 ret
= xmlDictLookup(vctxt
->dict
, nsName
, -1);
21984 if ((vctxt
->inode
->node
== NULL
) ||
21985 (vctxt
->inode
->node
->doc
== NULL
)) {
21986 VERROR_INT("xmlSchemaLookupNamespace",
21987 "no node or node's doc available");
21990 ns
= xmlSearchNs(vctxt
->inode
->node
->doc
,
21991 vctxt
->inode
->node
, prefix
);
21999 * This one works on the schema of the validation context.
22002 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt
,
22003 xmlSchemaPtr schema
,
22005 const xmlChar
*value
,
22006 xmlSchemaValPtr
*val
,
22011 if (vctxt
&& (vctxt
->schema
== NULL
)) {
22012 VERROR_INT("xmlSchemaValidateNotation",
22013 "a schema is needed on the validation context");
22016 ret
= xmlValidateQName(value
, 1);
22020 xmlChar
*localName
= NULL
;
22021 xmlChar
*prefix
= NULL
;
22023 localName
= xmlSplitQName2(value
, &prefix
);
22024 if (prefix
!= NULL
) {
22025 const xmlChar
*nsName
= NULL
;
22028 nsName
= xmlSchemaLookupNamespace(vctxt
, BAD_CAST prefix
);
22029 else if (node
!= NULL
) {
22030 xmlNsPtr ns
= xmlSearchNs(node
->doc
, node
, prefix
);
22035 xmlFree(localName
);
22038 if (nsName
== NULL
) {
22040 xmlFree(localName
);
22043 if (xmlSchemaGetNotation(schema
, localName
, nsName
) != NULL
) {
22044 if ((valNeeded
) && (val
!= NULL
)) {
22045 (*val
) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName
),
22046 xmlStrdup(nsName
));
22053 xmlFree(localName
);
22055 if (xmlSchemaGetNotation(schema
, value
, NULL
) != NULL
) {
22056 if (valNeeded
&& (val
!= NULL
)) {
22057 (*val
) = xmlSchemaNewNOTATIONValue(
22058 BAD_CAST
xmlStrdup(value
), NULL
);
22070 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt
,
22071 const xmlChar
* lname
,
22072 const xmlChar
* nsname
)
22076 lname
= xmlDictLookup(vctxt
->dict
, lname
, -1);
22079 if (nsname
!= NULL
) {
22080 nsname
= xmlDictLookup(vctxt
->dict
, nsname
, -1);
22081 if (nsname
== NULL
)
22084 for (i
= 0; i
< vctxt
->nodeQNames
->nbItems
; i
+= 2) {
22085 if ((vctxt
->nodeQNames
->items
[i
] == lname
) &&
22086 (vctxt
->nodeQNames
->items
[i
+1] == nsname
))
22087 /* Already there */
22090 /* Add new entry. */
22091 i
= vctxt
->nodeQNames
->nbItems
;
22092 xmlSchemaItemListAdd(vctxt
->nodeQNames
, (void *) lname
);
22093 xmlSchemaItemListAdd(vctxt
->nodeQNames
, (void *) nsname
);
22097 /************************************************************************
22099 * Validation of identity-constraints (IDC) *
22101 ************************************************************************/
22104 * xmlSchemaAugmentIDC:
22105 * @idcDef: the IDC definition
22107 * Creates an augmented IDC definition item.
22109 * Returns the item, or NULL on internal errors.
22112 xmlSchemaAugmentIDC(void *payload
, void *data
,
22113 const xmlChar
*name ATTRIBUTE_UNUSED
)
22115 xmlSchemaIDCPtr idcDef
= (xmlSchemaIDCPtr
) payload
;
22116 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) data
;
22117 xmlSchemaIDCAugPtr aidc
;
22119 aidc
= (xmlSchemaIDCAugPtr
) xmlMalloc(sizeof(xmlSchemaIDCAug
));
22120 if (aidc
== NULL
) {
22121 xmlSchemaVErrMemory(vctxt
,
22122 "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
22126 aidc
->keyrefDepth
= -1;
22127 aidc
->def
= idcDef
;
22129 if (vctxt
->aidcs
== NULL
)
22130 vctxt
->aidcs
= aidc
;
22132 aidc
->next
= vctxt
->aidcs
;
22133 vctxt
->aidcs
= aidc
;
22136 * Save if we have keyrefs at all.
22138 if ((vctxt
->hasKeyrefs
== 0) &&
22139 (idcDef
->type
== XML_SCHEMA_TYPE_IDC_KEYREF
))
22140 vctxt
->hasKeyrefs
= 1;
22144 * xmlSchemaAugmentImportedIDC:
22145 * @imported: the imported schema
22147 * Creates an augmented IDC definition for the imported schema.
22150 xmlSchemaAugmentImportedIDC(void *payload
, void *data
,
22151 const xmlChar
*name ATTRIBUTE_UNUSED
) {
22152 xmlSchemaImportPtr imported
= (xmlSchemaImportPtr
) payload
;
22153 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) data
;
22154 if (imported
->schema
->idcDef
!= NULL
) {
22155 xmlHashScan(imported
->schema
->idcDef
, xmlSchemaAugmentIDC
, vctxt
);
22160 * xmlSchemaIDCNewBinding:
22161 * @idcDef: the IDC definition of this binding
22163 * Creates a new IDC binding.
22165 * Returns the new IDC binding, NULL on internal errors.
22167 static xmlSchemaPSVIIDCBindingPtr
22168 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef
)
22170 xmlSchemaPSVIIDCBindingPtr ret
;
22172 ret
= (xmlSchemaPSVIIDCBindingPtr
) xmlMalloc(
22173 sizeof(xmlSchemaPSVIIDCBinding
));
22175 xmlSchemaVErrMemory(NULL
,
22176 "allocating a PSVI IDC binding item", NULL
);
22179 memset(ret
, 0, sizeof(xmlSchemaPSVIIDCBinding
));
22180 ret
->definition
= idcDef
;
22185 * xmlSchemaIDCStoreNodeTableItem:
22186 * @vctxt: the WXS validation context
22187 * @item: the IDC node table item
22189 * The validation context is used to store IDC node table items.
22190 * They are stored to avoid copying them if IDC node-tables are merged
22191 * with corresponding parent IDC node-tables (bubbling).
22193 * Returns 0 if succeeded, -1 on internal errors.
22196 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt
,
22197 xmlSchemaPSVIIDCNodePtr item
)
22200 * Add to global list.
22202 if (vctxt
->idcNodes
== NULL
) {
22203 vctxt
->idcNodes
= (xmlSchemaPSVIIDCNodePtr
*)
22204 xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr
));
22205 if (vctxt
->idcNodes
== NULL
) {
22206 xmlSchemaVErrMemory(vctxt
,
22207 "allocating the IDC node table item list", NULL
);
22210 vctxt
->sizeIdcNodes
= 20;
22211 } else if (vctxt
->sizeIdcNodes
<= vctxt
->nbIdcNodes
) {
22212 vctxt
->sizeIdcNodes
*= 2;
22213 vctxt
->idcNodes
= (xmlSchemaPSVIIDCNodePtr
*)
22214 xmlRealloc(vctxt
->idcNodes
, vctxt
->sizeIdcNodes
*
22215 sizeof(xmlSchemaPSVIIDCNodePtr
));
22216 if (vctxt
->idcNodes
== NULL
) {
22217 xmlSchemaVErrMemory(vctxt
,
22218 "re-allocating the IDC node table item list", NULL
);
22222 vctxt
->idcNodes
[vctxt
->nbIdcNodes
++] = item
;
22228 * xmlSchemaIDCStoreKey:
22229 * @vctxt: the WXS validation context
22230 * @item: the IDC key
22232 * The validation context is used to store an IDC key.
22234 * Returns 0 if succeeded, -1 on internal errors.
22237 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt
,
22238 xmlSchemaPSVIIDCKeyPtr key
)
22241 * Add to global list.
22243 if (vctxt
->idcKeys
== NULL
) {
22244 vctxt
->idcKeys
= (xmlSchemaPSVIIDCKeyPtr
*)
22245 xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr
));
22246 if (vctxt
->idcKeys
== NULL
) {
22247 xmlSchemaVErrMemory(vctxt
,
22248 "allocating the IDC key storage list", NULL
);
22251 vctxt
->sizeIdcKeys
= 40;
22252 } else if (vctxt
->sizeIdcKeys
<= vctxt
->nbIdcKeys
) {
22253 vctxt
->sizeIdcKeys
*= 2;
22254 vctxt
->idcKeys
= (xmlSchemaPSVIIDCKeyPtr
*)
22255 xmlRealloc(vctxt
->idcKeys
, vctxt
->sizeIdcKeys
*
22256 sizeof(xmlSchemaPSVIIDCKeyPtr
));
22257 if (vctxt
->idcKeys
== NULL
) {
22258 xmlSchemaVErrMemory(vctxt
,
22259 "re-allocating the IDC key storage list", NULL
);
22263 vctxt
->idcKeys
[vctxt
->nbIdcKeys
++] = key
;
22269 * xmlSchemaIDCAppendNodeTableItem:
22270 * @bind: the IDC binding
22271 * @ntItem: the node-table item
22273 * Appends the IDC node-table item to the binding.
22275 * Returns 0 on success and -1 on internal errors.
22278 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind
,
22279 xmlSchemaPSVIIDCNodePtr ntItem
)
22281 if (bind
->nodeTable
== NULL
) {
22282 bind
->sizeNodes
= 10;
22283 bind
->nodeTable
= (xmlSchemaPSVIIDCNodePtr
*)
22284 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr
));
22285 if (bind
->nodeTable
== NULL
) {
22286 xmlSchemaVErrMemory(NULL
,
22287 "allocating an array of IDC node-table items", NULL
);
22290 } else if (bind
->sizeNodes
<= bind
->nbNodes
) {
22291 bind
->sizeNodes
*= 2;
22292 bind
->nodeTable
= (xmlSchemaPSVIIDCNodePtr
*)
22293 xmlRealloc(bind
->nodeTable
, bind
->sizeNodes
*
22294 sizeof(xmlSchemaPSVIIDCNodePtr
));
22295 if (bind
->nodeTable
== NULL
) {
22296 xmlSchemaVErrMemory(NULL
,
22297 "re-allocating an array of IDC node-table items", NULL
);
22301 bind
->nodeTable
[bind
->nbNodes
++] = ntItem
;
22306 * xmlSchemaIDCAcquireBinding:
22307 * @vctxt: the WXS validation context
22308 * @matcher: the IDC matcher
22310 * Looks up an PSVI IDC binding, for the IDC definition and
22311 * of the given matcher. If none found, a new one is created
22312 * and added to the IDC table.
22314 * Returns an IDC binding or NULL on internal errors.
22316 static xmlSchemaPSVIIDCBindingPtr
22317 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt
,
22318 xmlSchemaIDCMatcherPtr matcher
)
22320 xmlSchemaNodeInfoPtr ielem
;
22322 ielem
= vctxt
->elemInfos
[matcher
->depth
];
22324 if (ielem
->idcTable
== NULL
) {
22325 ielem
->idcTable
= xmlSchemaIDCNewBinding(matcher
->aidc
->def
);
22326 if (ielem
->idcTable
== NULL
)
22328 return(ielem
->idcTable
);
22330 xmlSchemaPSVIIDCBindingPtr bind
= NULL
;
22332 bind
= ielem
->idcTable
;
22334 if (bind
->definition
== matcher
->aidc
->def
)
22336 if (bind
->next
== NULL
) {
22337 bind
->next
= xmlSchemaIDCNewBinding(matcher
->aidc
->def
);
22338 if (bind
->next
== NULL
)
22340 return(bind
->next
);
22343 } while (bind
!= NULL
);
22348 static xmlSchemaItemListPtr
22349 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED
,
22350 xmlSchemaIDCMatcherPtr matcher
)
22352 if (matcher
->targets
== NULL
)
22353 matcher
->targets
= xmlSchemaItemListCreate();
22354 return(matcher
->targets
);
22358 * xmlSchemaIDCFreeKey:
22359 * @key: the IDC key
22361 * Frees an IDC key together with its compiled value.
22364 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key
)
22366 if (key
->val
!= NULL
)
22367 xmlSchemaFreeValue(key
->val
);
22372 * xmlSchemaIDCFreeBinding:
22374 * Frees an IDC binding. Note that the node table-items
22378 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind
)
22380 if (bind
->nodeTable
!= NULL
)
22381 xmlFree(bind
->nodeTable
);
22382 if (bind
->dupls
!= NULL
)
22383 xmlSchemaItemListFree(bind
->dupls
);
22388 * xmlSchemaIDCFreeIDCTable:
22389 * @bind: the first IDC binding in the list
22391 * Frees an IDC table, i.e. all the IDC bindings in the list.
22394 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind
)
22396 xmlSchemaPSVIIDCBindingPtr prev
;
22398 while (bind
!= NULL
) {
22401 xmlSchemaIDCFreeBinding(prev
);
22406 xmlFreeIDCHashEntry (void *payload
, const xmlChar
*name ATTRIBUTE_UNUSED
)
22408 xmlIDCHashEntryPtr e
= payload
, n
;
22417 * xmlSchemaIDCFreeMatcherList:
22418 * @matcher: the first IDC matcher in the list
22420 * Frees a list of IDC matchers.
22423 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher
)
22425 xmlSchemaIDCMatcherPtr next
;
22427 while (matcher
!= NULL
) {
22428 next
= matcher
->next
;
22429 if (matcher
->keySeqs
!= NULL
) {
22431 for (i
= 0; i
< matcher
->sizeKeySeqs
; i
++)
22432 if (matcher
->keySeqs
[i
] != NULL
)
22433 xmlFree(matcher
->keySeqs
[i
]);
22434 xmlFree(matcher
->keySeqs
);
22436 if (matcher
->targets
!= NULL
) {
22437 if (matcher
->idcType
== XML_SCHEMA_TYPE_IDC_KEYREF
) {
22439 xmlSchemaPSVIIDCNodePtr idcNode
;
22441 * Node-table items for keyrefs are not stored globally
22442 * to the validation context, since they are not bubbled.
22443 * We need to free them here.
22445 for (i
= 0; i
< matcher
->targets
->nbItems
; i
++) {
22447 (xmlSchemaPSVIIDCNodePtr
) matcher
->targets
->items
[i
];
22448 xmlFree(idcNode
->keys
);
22452 xmlSchemaItemListFree(matcher
->targets
);
22454 if (matcher
->htab
!= NULL
)
22455 xmlHashFree(matcher
->htab
, xmlFreeIDCHashEntry
);
22462 * xmlSchemaIDCReleaseMatcherList:
22463 * @vctxt: the WXS validation context
22464 * @matcher: the first IDC matcher in the list
22466 * Caches a list of IDC matchers for reuse.
22469 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt
,
22470 xmlSchemaIDCMatcherPtr matcher
)
22472 xmlSchemaIDCMatcherPtr next
;
22474 while (matcher
!= NULL
) {
22475 next
= matcher
->next
;
22476 if (matcher
->keySeqs
!= NULL
) {
22479 * Don't free the array, but only the content.
22481 for (i
= 0; i
< matcher
->sizeKeySeqs
; i
++)
22482 if (matcher
->keySeqs
[i
] != NULL
) {
22483 xmlFree(matcher
->keySeqs
[i
]);
22484 matcher
->keySeqs
[i
] = NULL
;
22487 if (matcher
->targets
) {
22488 if (matcher
->idcType
== XML_SCHEMA_TYPE_IDC_KEYREF
) {
22490 xmlSchemaPSVIIDCNodePtr idcNode
;
22492 * Node-table items for keyrefs are not stored globally
22493 * to the validation context, since they are not bubbled.
22494 * We need to free them here.
22496 for (i
= 0; i
< matcher
->targets
->nbItems
; i
++) {
22498 (xmlSchemaPSVIIDCNodePtr
) matcher
->targets
->items
[i
];
22499 xmlFree(idcNode
->keys
);
22503 xmlSchemaItemListFree(matcher
->targets
);
22504 matcher
->targets
= NULL
;
22506 if (matcher
->htab
!= NULL
) {
22507 xmlHashFree(matcher
->htab
, xmlFreeIDCHashEntry
);
22508 matcher
->htab
= NULL
;
22510 matcher
->next
= NULL
;
22512 * Cache the matcher.
22514 if (vctxt
->idcMatcherCache
!= NULL
)
22515 matcher
->nextCached
= vctxt
->idcMatcherCache
;
22516 vctxt
->idcMatcherCache
= matcher
;
22523 * xmlSchemaIDCAddStateObject:
22524 * @vctxt: the WXS validation context
22525 * @matcher: the IDC matcher
22526 * @sel: the XPath information
22527 * @parent: the parent "selector" state object if any
22528 * @type: "selector" or "field"
22530 * Creates/reuses and activates state objects for the given
22531 * XPath information; if the XPath expression consists of unions,
22532 * multiple state objects are created for every unioned expression.
22534 * Returns 0 on success and -1 on internal errors.
22537 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt
,
22538 xmlSchemaIDCMatcherPtr matcher
,
22539 xmlSchemaIDCSelectPtr sel
,
22542 xmlSchemaIDCStateObjPtr sto
;
22545 * Reuse the state objects from the pool.
22547 if (vctxt
->xpathStatePool
!= NULL
) {
22548 sto
= vctxt
->xpathStatePool
;
22549 vctxt
->xpathStatePool
= sto
->next
;
22553 * Create a new state object.
22555 sto
= (xmlSchemaIDCStateObjPtr
) xmlMalloc(sizeof(xmlSchemaIDCStateObj
));
22557 xmlSchemaVErrMemory(NULL
,
22558 "allocating an IDC state object", NULL
);
22561 memset(sto
, 0, sizeof(xmlSchemaIDCStateObj
));
22564 * Add to global list.
22566 if (vctxt
->xpathStates
!= NULL
)
22567 sto
->next
= vctxt
->xpathStates
;
22568 vctxt
->xpathStates
= sto
;
22571 * Free the old xpath validation context.
22573 if (sto
->xpathCtxt
!= NULL
)
22574 xmlFreeStreamCtxt((xmlStreamCtxtPtr
) sto
->xpathCtxt
);
22577 * Create a new XPath (pattern) validation context.
22579 sto
->xpathCtxt
= (void *) xmlPatternGetStreamCtxt(
22580 (xmlPatternPtr
) sel
->xpathComp
);
22581 if (sto
->xpathCtxt
== NULL
) {
22582 VERROR_INT("xmlSchemaIDCAddStateObject",
22583 "failed to create an XPath validation context");
22587 sto
->depth
= vctxt
->depth
;
22588 sto
->matcher
= matcher
;
22590 sto
->nbHistory
= 0;
22593 xmlGenericError(xmlGenericErrorContext
, "IDC: STO push '%s'\n",
22600 * xmlSchemaXPathEvaluate:
22601 * @vctxt: the WXS validation context
22602 * @nodeType: the nodeType of the current node
22604 * Evaluates all active XPath state objects.
22606 * Returns the number of IC "field" state objects which resolved to
22607 * this node, 0 if none resolved and -1 on internal errors.
22610 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt
,
22611 xmlElementType nodeType
)
22613 xmlSchemaIDCStateObjPtr sto
, head
= NULL
, first
;
22614 int res
, resolved
= 0, depth
= vctxt
->depth
;
22616 if (vctxt
->xpathStates
== NULL
)
22619 if (nodeType
== XML_ATTRIBUTE_NODE
)
22623 xmlChar
*str
= NULL
;
22624 xmlGenericError(xmlGenericErrorContext
,
22625 "IDC: EVAL on %s, depth %d, type %d\n",
22626 xmlSchemaFormatQName(&str
, vctxt
->inode
->nsName
,
22627 vctxt
->inode
->localName
), depth
, nodeType
);
22632 * Process all active XPath state objects.
22634 first
= vctxt
->xpathStates
;
22636 while (sto
!= head
) {
22638 if (sto
->type
== XPATH_STATE_OBJ_TYPE_IDC_SELECTOR
)
22639 xmlGenericError(xmlGenericErrorContext
, "IDC: ['%s'] selector '%s'\n",
22640 sto
->matcher
->aidc
->def
->name
, sto
->sel
->xpath
);
22642 xmlGenericError(xmlGenericErrorContext
, "IDC: ['%s'] field '%s'\n",
22643 sto
->matcher
->aidc
->def
->name
, sto
->sel
->xpath
);
22645 if (nodeType
== XML_ELEMENT_NODE
)
22646 res
= xmlStreamPush((xmlStreamCtxtPtr
) sto
->xpathCtxt
,
22647 vctxt
->inode
->localName
, vctxt
->inode
->nsName
);
22649 res
= xmlStreamPushAttr((xmlStreamCtxtPtr
) sto
->xpathCtxt
,
22650 vctxt
->inode
->localName
, vctxt
->inode
->nsName
);
22653 VERROR_INT("xmlSchemaXPathEvaluate",
22654 "calling xmlStreamPush()");
22663 xmlGenericError(xmlGenericErrorContext
, "IDC: "
22667 * Register a match in the state object history.
22669 if (sto
->history
== NULL
) {
22670 sto
->history
= (int *) xmlMalloc(5 * sizeof(int));
22671 if (sto
->history
== NULL
) {
22672 xmlSchemaVErrMemory(NULL
,
22673 "allocating the state object history", NULL
);
22676 sto
->sizeHistory
= 5;
22677 } else if (sto
->sizeHistory
<= sto
->nbHistory
) {
22678 sto
->sizeHistory
*= 2;
22679 sto
->history
= (int *) xmlRealloc(sto
->history
,
22680 sto
->sizeHistory
* sizeof(int));
22681 if (sto
->history
== NULL
) {
22682 xmlSchemaVErrMemory(NULL
,
22683 "re-allocating the state object history", NULL
);
22687 sto
->history
[sto
->nbHistory
++] = depth
;
22690 xmlGenericError(xmlGenericErrorContext
, "IDC: push match '%d'\n",
22694 if (sto
->type
== XPATH_STATE_OBJ_TYPE_IDC_SELECTOR
) {
22695 xmlSchemaIDCSelectPtr sel
;
22697 * Activate state objects for the IDC fields of
22698 * the IDC selector.
22701 xmlGenericError(xmlGenericErrorContext
, "IDC: "
22702 "activating field states\n");
22704 sel
= sto
->matcher
->aidc
->def
->fields
;
22705 while (sel
!= NULL
) {
22706 if (xmlSchemaIDCAddStateObject(vctxt
, sto
->matcher
,
22707 sel
, XPATH_STATE_OBJ_TYPE_IDC_FIELD
) == -1)
22711 } else if (sto
->type
== XPATH_STATE_OBJ_TYPE_IDC_FIELD
) {
22713 * An IDC key node was found by the IDC field.
22716 xmlGenericError(xmlGenericErrorContext
,
22717 "IDC: key found\n");
22720 * Notify that the character value of this node is
22723 if (resolved
== 0) {
22724 if ((vctxt
->inode
->flags
&
22725 XML_SCHEMA_NODE_INFO_VALUE_NEEDED
) == 0)
22726 vctxt
->inode
->flags
|= XML_SCHEMA_NODE_INFO_VALUE_NEEDED
;
22731 if (sto
->next
== NULL
) {
22733 * Evaluate field state objects created on this node as well.
22736 sto
= vctxt
->xpathStates
;
22743 static const xmlChar
*
22744 xmlSchemaFormatIDCKeySequence_1(xmlSchemaValidCtxtPtr vctxt
,
22746 xmlSchemaPSVIIDCKeyPtr
*seq
,
22747 int count
, int for_hash
)
22750 xmlChar
*value
= NULL
;
22752 *buf
= xmlStrdup(BAD_CAST
"[");
22753 for (i
= 0; i
< count
; i
++) {
22754 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
22756 res
= xmlSchemaGetCanonValueWhtspExt(seq
[i
]->val
,
22757 xmlSchemaGetWhiteSpaceFacetValue(seq
[i
]->type
),
22760 res
= xmlSchemaGetCanonValueHash(seq
[i
]->val
, &value
);
22763 *buf
= xmlStrcat(*buf
, BAD_CAST value
);
22765 VERROR_INT("xmlSchemaFormatIDCKeySequence",
22766 "failed to compute a canonical value");
22767 *buf
= xmlStrcat(*buf
, BAD_CAST
"???");
22770 *buf
= xmlStrcat(*buf
, BAD_CAST
"', ");
22772 *buf
= xmlStrcat(*buf
, BAD_CAST
"'");
22773 if (value
!= NULL
) {
22778 *buf
= xmlStrcat(*buf
, BAD_CAST
"]");
22780 return (BAD_CAST
*buf
);
22783 static const xmlChar
*
22784 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt
,
22786 xmlSchemaPSVIIDCKeyPtr
*seq
,
22789 return xmlSchemaFormatIDCKeySequence_1(vctxt
, buf
, seq
, count
, 0);
22792 static const xmlChar
*
22793 xmlSchemaHashKeySequence(xmlSchemaValidCtxtPtr vctxt
,
22795 xmlSchemaPSVIIDCKeyPtr
*seq
,
22798 return xmlSchemaFormatIDCKeySequence_1(vctxt
, buf
, seq
, count
, 1);
22802 * xmlSchemaXPathPop:
22803 * @vctxt: the WXS validation context
22805 * Pops all XPath states.
22807 * Returns 0 on success and -1 on internal errors.
22810 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt
)
22812 xmlSchemaIDCStateObjPtr sto
;
22815 if (vctxt
->xpathStates
== NULL
)
22817 sto
= vctxt
->xpathStates
;
22819 res
= xmlStreamPop((xmlStreamCtxtPtr
) sto
->xpathCtxt
);
22823 } while (sto
!= NULL
);
22828 * xmlSchemaXPathProcessHistory:
22829 * @vctxt: the WXS validation context
22830 * @type: the simple/complex type of the current node if any at all
22831 * @val: the precompiled value
22833 * Processes and pops the history items of the IDC state objects.
22834 * IDC key-sequences are validated/created on IDC bindings.
22836 * Returns 0 on success and -1 on internal errors.
22839 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt
,
22842 xmlSchemaIDCStateObjPtr sto
, nextsto
;
22843 int res
, matchDepth
;
22844 xmlSchemaPSVIIDCKeyPtr key
= NULL
;
22845 xmlSchemaTypePtr type
= vctxt
->inode
->typeDef
, simpleType
= NULL
;
22847 if (vctxt
->xpathStates
== NULL
)
22849 sto
= vctxt
->xpathStates
;
22853 xmlChar
*str
= NULL
;
22854 xmlGenericError(xmlGenericErrorContext
,
22855 "IDC: BACK on %s, depth %d\n",
22856 xmlSchemaFormatQName(&str
, vctxt
->inode
->nsName
,
22857 vctxt
->inode
->localName
), vctxt
->depth
);
22862 * Evaluate the state objects.
22864 while (sto
!= NULL
) {
22865 res
= xmlStreamPop((xmlStreamCtxtPtr
) sto
->xpathCtxt
);
22867 VERROR_INT("xmlSchemaXPathProcessHistory",
22868 "calling xmlStreamPop()");
22872 xmlGenericError(xmlGenericErrorContext
, "IDC: stream pop '%s'\n",
22875 if (sto
->nbHistory
== 0)
22876 goto deregister_check
;
22878 matchDepth
= sto
->history
[sto
->nbHistory
-1];
22881 * Only matches at the current depth are of interest.
22883 if (matchDepth
!= depth
) {
22887 if (sto
->type
== XPATH_STATE_OBJ_TYPE_IDC_FIELD
) {
22889 * NOTE: According to
22890 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22891 * ... the simple-content of complex types is also allowed.
22894 if (WXS_IS_COMPLEX(type
)) {
22895 if (WXS_HAS_SIMPLE_CONTENT(type
)) {
22897 * Sanity check for complex types with simple content.
22899 simpleType
= type
->contentTypeDef
;
22900 if (simpleType
== NULL
) {
22901 VERROR_INT("xmlSchemaXPathProcessHistory",
22902 "field resolves to a CT with simple content "
22903 "but the CT is missing the ST definition");
22910 if (simpleType
== NULL
) {
22911 xmlChar
*str
= NULL
;
22914 * Not qualified if the field resolves to a node of non
22917 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
22918 XML_SCHEMAV_CVC_IDC
, NULL
,
22919 WXS_BASIC_CAST sto
->matcher
->aidc
->def
,
22920 "The XPath '%s' of a field of %s does evaluate to a node of "
22923 xmlSchemaGetIDCDesignation(&str
, sto
->matcher
->aidc
->def
));
22924 FREE_AND_NULL(str
);
22926 goto deregister_check
;
22929 if ((key
== NULL
) && (vctxt
->inode
->val
== NULL
)) {
22931 * Failed to provide the normalized value; maybe
22932 * the value was invalid.
22934 VERROR(XML_SCHEMAV_CVC_IDC
,
22935 WXS_BASIC_CAST sto
->matcher
->aidc
->def
,
22936 "Warning: No precomputed value available, the value "
22937 "was either invalid or something strange happened");
22939 goto deregister_check
;
22941 xmlSchemaIDCMatcherPtr matcher
= sto
->matcher
;
22942 xmlSchemaPSVIIDCKeyPtr
*keySeq
;
22946 * The key will be anchored on the matcher's list of
22947 * key-sequences. The position in this list is determined
22948 * by the target node's depth relative to the matcher's
22949 * depth of creation (i.e. the depth of the scope element).
22951 * Element Depth Pos List-entries
22954 * <target/> 2 2 target
22958 * The size of the list is only dependent on the depth of
22960 * An entry will be NULLed in selector_leave, i.e. when
22961 * we hit the target's
22963 pos
= sto
->depth
- matcher
->depth
;
22964 idx
= sto
->sel
->index
;
22967 * Create/grow the array of key-sequences.
22969 if (matcher
->keySeqs
== NULL
) {
22971 matcher
->sizeKeySeqs
= pos
* 2;
22973 matcher
->sizeKeySeqs
= 10;
22974 matcher
->keySeqs
= (xmlSchemaPSVIIDCKeyPtr
**)
22975 xmlMalloc(matcher
->sizeKeySeqs
*
22976 sizeof(xmlSchemaPSVIIDCKeyPtr
*));
22977 if (matcher
->keySeqs
== NULL
) {
22978 xmlSchemaVErrMemory(NULL
,
22979 "allocating an array of key-sequences",
22983 memset(matcher
->keySeqs
, 0,
22984 matcher
->sizeKeySeqs
*
22985 sizeof(xmlSchemaPSVIIDCKeyPtr
*));
22986 } else if (pos
>= matcher
->sizeKeySeqs
) {
22987 int i
= matcher
->sizeKeySeqs
;
22989 matcher
->sizeKeySeqs
*= 2;
22990 matcher
->keySeqs
= (xmlSchemaPSVIIDCKeyPtr
**)
22991 xmlRealloc(matcher
->keySeqs
,
22992 matcher
->sizeKeySeqs
*
22993 sizeof(xmlSchemaPSVIIDCKeyPtr
*));
22994 if (matcher
->keySeqs
== NULL
) {
22995 xmlSchemaVErrMemory(NULL
,
22996 "reallocating an array of key-sequences",
23001 * The array needs to be NULLed.
23002 * TODO: Use memset?
23004 for (; i
< matcher
->sizeKeySeqs
; i
++)
23005 matcher
->keySeqs
[i
] = NULL
;
23009 * Get/create the key-sequence.
23011 keySeq
= matcher
->keySeqs
[pos
];
23012 if (keySeq
== NULL
) {
23013 goto create_sequence
;
23014 } else if (keySeq
[idx
] != NULL
) {
23015 xmlChar
*str
= NULL
;
23017 * cvc-identity-constraint:
23018 * 3 For each node in the `target node set` all
23019 * of the {fields}, with that node as the context
23020 * node, evaluate to either an empty node-set or
23021 * a node-set with exactly one member, which must
23022 * have a simple type.
23024 * The key was already set; report an error.
23026 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
23027 XML_SCHEMAV_CVC_IDC
, NULL
,
23028 WXS_BASIC_CAST matcher
->aidc
->def
,
23029 "The XPath '%s' of a field of %s evaluates to a "
23030 "node-set with more than one member",
23032 xmlSchemaGetIDCDesignation(&str
, matcher
->aidc
->def
));
23033 FREE_AND_NULL(str
);
23035 goto deregister_check
;
23041 * Create a key-sequence.
23043 keySeq
= (xmlSchemaPSVIIDCKeyPtr
*) xmlMalloc(
23044 matcher
->aidc
->def
->nbFields
*
23045 sizeof(xmlSchemaPSVIIDCKeyPtr
));
23046 if (keySeq
== NULL
) {
23047 xmlSchemaVErrMemory(NULL
,
23048 "allocating an IDC key-sequence", NULL
);
23051 memset(keySeq
, 0, matcher
->aidc
->def
->nbFields
*
23052 sizeof(xmlSchemaPSVIIDCKeyPtr
));
23053 matcher
->keySeqs
[pos
] = keySeq
;
23056 * Create a key once per node only.
23059 key
= (xmlSchemaPSVIIDCKeyPtr
) xmlMalloc(
23060 sizeof(xmlSchemaPSVIIDCKey
));
23062 xmlSchemaVErrMemory(NULL
,
23063 "allocating a IDC key", NULL
);
23065 matcher
->keySeqs
[pos
] = NULL
;
23069 * Consume the compiled value.
23071 key
->type
= simpleType
;
23072 key
->val
= vctxt
->inode
->val
;
23073 vctxt
->inode
->val
= NULL
;
23075 * Store the key in a global list.
23077 if (xmlSchemaIDCStoreKey(vctxt
, key
) == -1) {
23078 xmlSchemaIDCFreeKey(key
);
23084 } else if (sto
->type
== XPATH_STATE_OBJ_TYPE_IDC_SELECTOR
) {
23086 xmlSchemaPSVIIDCKeyPtr
**keySeq
= NULL
;
23087 /* xmlSchemaPSVIIDCBindingPtr bind; */
23088 xmlSchemaPSVIIDCNodePtr ntItem
;
23089 xmlSchemaIDCMatcherPtr matcher
;
23090 xmlSchemaIDCPtr idc
;
23091 xmlSchemaItemListPtr targets
;
23092 int pos
, i
, j
, nbKeys
;
23094 * Here we have the following scenario:
23095 * An IDC 'selector' state object resolved to a target node,
23096 * during the time this target node was in the
23097 * ancestor-or-self axis, the 'field' state object(s) looked
23098 * out for matching nodes to create a key-sequence for this
23099 * target node. Now we are back to this target node and need
23100 * to put the key-sequence, together with the target node
23101 * itself, into the node-table of the corresponding IDC
23104 matcher
= sto
->matcher
;
23105 idc
= matcher
->aidc
->def
;
23106 nbKeys
= idc
->nbFields
;
23107 pos
= depth
- matcher
->depth
;
23109 * Check if the matcher has any key-sequences at all, plus
23110 * if it has a key-sequence for the current target node.
23112 if ((matcher
->keySeqs
== NULL
) ||
23113 (matcher
->sizeKeySeqs
<= pos
)) {
23114 if (idc
->type
== XML_SCHEMA_TYPE_IDC_KEY
)
23115 goto selector_key_error
;
23117 goto selector_leave
;
23120 keySeq
= &(matcher
->keySeqs
[pos
]);
23121 if (*keySeq
== NULL
) {
23122 if (idc
->type
== XML_SCHEMA_TYPE_IDC_KEY
)
23123 goto selector_key_error
;
23125 goto selector_leave
;
23128 for (i
= 0; i
< nbKeys
; i
++) {
23129 if ((*keySeq
)[i
] == NULL
) {
23131 * Not qualified, if not all fields did resolve.
23133 if (idc
->type
== XML_SCHEMA_TYPE_IDC_KEY
) {
23135 * All fields of a "key" IDC must resolve.
23137 goto selector_key_error
;
23139 goto selector_leave
;
23143 * All fields did resolve.
23147 * 4.1 If the {identity-constraint category} is unique(/key),
23148 * then no two members of the `qualified node set` have
23149 * `key-sequences` whose members are pairwise equal, as
23150 * defined by Equal in [XML Schemas: Datatypes].
23152 * Get the IDC binding from the matcher and check for
23153 * duplicate key-sequences.
23156 bind
= xmlSchemaIDCAcquireBinding(vctxt
, matcher
);
23158 targets
= xmlSchemaIDCAcquireTargetList(vctxt
, matcher
);
23159 if ((idc
->type
!= XML_SCHEMA_TYPE_IDC_KEYREF
) &&
23160 (targets
->nbItems
!= 0)) {
23161 xmlSchemaPSVIIDCKeyPtr ckey
, bkey
, *bkeySeq
;
23162 xmlIDCHashEntryPtr e
;
23166 if (!matcher
->htab
)
23169 xmlChar
*value
= NULL
;
23170 xmlSchemaHashKeySequence(vctxt
, &value
, *keySeq
, nbKeys
);
23171 e
= xmlHashLookup(matcher
->htab
, value
);
23172 FREE_AND_NULL(value
);
23176 * Compare the key-sequences, key by key.
23178 for (;e
; e
= e
->next
) {
23180 ((xmlSchemaPSVIIDCNodePtr
) targets
->items
[e
->index
])->keys
;
23181 for (j
= 0; j
< nbKeys
; j
++) {
23182 ckey
= (*keySeq
)[j
];
23184 res
= xmlSchemaAreValuesEqual(ckey
->val
, bkey
->val
);
23187 } else if (res
== 0) {
23189 * One of the keys differs, so the key-sequence
23190 * won't be equal; get out.
23197 * Duplicate key-sequence found.
23203 xmlChar
*str
= NULL
, *strB
= NULL
;
23205 * TODO: Try to report the key-sequence.
23207 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
23208 XML_SCHEMAV_CVC_IDC
, NULL
,
23209 WXS_BASIC_CAST idc
,
23210 "Duplicate key-sequence %s in %s",
23211 xmlSchemaFormatIDCKeySequence(vctxt
, &str
,
23212 (*keySeq
), nbKeys
),
23213 xmlSchemaGetIDCDesignation(&strB
, idc
));
23214 FREE_AND_NULL(str
);
23215 FREE_AND_NULL(strB
);
23216 goto selector_leave
;
23220 * Add a node-table item to the IDC binding.
23222 ntItem
= (xmlSchemaPSVIIDCNodePtr
) xmlMalloc(
23223 sizeof(xmlSchemaPSVIIDCNode
));
23224 if (ntItem
== NULL
) {
23225 xmlSchemaVErrMemory(NULL
,
23226 "allocating an IDC node-table item", NULL
);
23231 memset(ntItem
, 0, sizeof(xmlSchemaPSVIIDCNode
));
23234 * Store the node-table item in a global list.
23236 if (idc
->type
!= XML_SCHEMA_TYPE_IDC_KEYREF
) {
23237 if (xmlSchemaIDCStoreNodeTableItem(vctxt
, ntItem
) == -1) {
23243 ntItem
->nodeQNameID
= -1;
23246 * Save a cached QName for this node on the IDC node, to be
23247 * able to report it, even if the node is not saved.
23249 ntItem
->nodeQNameID
= xmlSchemaVAddNodeQName(vctxt
,
23250 vctxt
->inode
->localName
, vctxt
->inode
->nsName
);
23251 if (ntItem
->nodeQNameID
== -1) {
23259 * Init the node-table item: Save the node, position and
23260 * consume the key-sequence.
23262 ntItem
->node
= vctxt
->node
;
23263 ntItem
->nodeLine
= vctxt
->inode
->nodeLine
;
23264 ntItem
->keys
= *keySeq
;
23267 if (xmlSchemaIDCAppendNodeTableItem(bind
, ntItem
) == -1)
23269 if (xmlSchemaItemListAdd(targets
, ntItem
) == -1) {
23270 if (idc
->type
== XML_SCHEMA_TYPE_IDC_KEYREF
) {
23272 * Free the item, since keyref items won't be
23273 * put on a global list.
23275 xmlFree(ntItem
->keys
);
23280 if (idc
->type
!= XML_SCHEMA_TYPE_IDC_KEYREF
) {
23281 xmlChar
*value
= NULL
;
23282 xmlIDCHashEntryPtr r
, e
;
23283 if (!matcher
->htab
)
23284 matcher
->htab
= xmlHashCreate(4);
23285 xmlSchemaHashKeySequence(vctxt
, &value
, ntItem
->keys
, nbKeys
);
23286 e
= xmlMalloc(sizeof *e
);
23287 e
->index
= targets
->nbItems
- 1;
23288 r
= xmlHashLookup(matcher
->htab
, value
);
23294 xmlHashAddEntry(matcher
->htab
, value
, e
);
23296 FREE_AND_NULL(value
);
23299 goto selector_leave
;
23300 selector_key_error
:
23302 xmlChar
*str
= NULL
;
23304 * 4.2.1 (KEY) The `target node set` and the
23305 * `qualified node set` are equal, that is, every
23306 * member of the `target node set` is also a member
23307 * of the `qualified node set` and vice versa.
23309 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
23310 XML_SCHEMAV_CVC_IDC
, NULL
,
23311 WXS_BASIC_CAST idc
,
23312 "Not all fields of %s evaluate to a node",
23313 xmlSchemaGetIDCDesignation(&str
, idc
), NULL
);
23314 FREE_AND_NULL(str
);
23318 * Free the key-sequence if not added to the IDC table.
23320 if ((keySeq
!= NULL
) && (*keySeq
!= NULL
)) {
23324 } /* if selector */
23330 * Deregister state objects if they reach the depth of creation.
23332 if ((sto
->nbHistory
== 0) && (sto
->depth
== depth
)) {
23334 xmlGenericError(xmlGenericErrorContext
, "IDC: STO pop '%s'\n",
23337 if (vctxt
->xpathStates
!= sto
) {
23338 VERROR_INT("xmlSchemaXPathProcessHistory",
23339 "The state object to be removed is not the first "
23342 nextsto
= sto
->next
;
23344 * Unlink from the list of active XPath state objects.
23346 vctxt
->xpathStates
= sto
->next
;
23347 sto
->next
= vctxt
->xpathStatePool
;
23349 * Link it to the pool of reusable state objects.
23351 vctxt
->xpathStatePool
= sto
;
23355 } /* while (sto != NULL) */
23360 * xmlSchemaIDCRegisterMatchers:
23361 * @vctxt: the WXS validation context
23362 * @elemDecl: the element declaration
23364 * Creates helper objects to evaluate IDC selectors/fields
23367 * Returns 0 if OK and -1 on internal errors.
23370 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt
,
23371 xmlSchemaElementPtr elemDecl
)
23373 xmlSchemaIDCMatcherPtr matcher
, last
= NULL
;
23374 xmlSchemaIDCPtr idc
, refIdc
;
23375 xmlSchemaIDCAugPtr aidc
;
23377 idc
= (xmlSchemaIDCPtr
) elemDecl
->idcs
;
23383 xmlChar
*str
= NULL
;
23384 xmlGenericError(xmlGenericErrorContext
,
23385 "IDC: REGISTER on %s, depth %d\n",
23386 (char *) xmlSchemaFormatQName(&str
, vctxt
->inode
->nsName
,
23387 vctxt
->inode
->localName
), vctxt
->depth
);
23391 if (vctxt
->inode
->idcMatchers
!= NULL
) {
23392 VERROR_INT("xmlSchemaIDCRegisterMatchers",
23393 "The chain of IDC matchers is expected to be empty");
23397 if (idc
->type
== XML_SCHEMA_TYPE_IDC_KEYREF
) {
23399 * Since IDCs bubbles are expensive we need to know the
23400 * depth at which the bubbles should stop; this will be
23401 * the depth of the top-most keyref IDC. If no keyref
23402 * references a key/unique IDC, the keyrefDepth will
23403 * be -1, indicating that no bubbles are needed.
23405 refIdc
= (xmlSchemaIDCPtr
) idc
->ref
->item
;
23406 if (refIdc
!= NULL
) {
23408 * Remember that we have keyrefs on this node.
23410 vctxt
->inode
->hasKeyrefs
= 1;
23412 * Lookup the referenced augmented IDC info.
23414 aidc
= vctxt
->aidcs
;
23415 while (aidc
!= NULL
) {
23416 if (aidc
->def
== refIdc
)
23420 if (aidc
== NULL
) {
23421 VERROR_INT("xmlSchemaIDCRegisterMatchers",
23422 "Could not find an augmented IDC item for an IDC "
23426 if ((aidc
->keyrefDepth
== -1) ||
23427 (vctxt
->depth
< aidc
->keyrefDepth
))
23428 aidc
->keyrefDepth
= vctxt
->depth
;
23432 * Lookup the augmented IDC item for the IDC definition.
23434 aidc
= vctxt
->aidcs
;
23435 while (aidc
!= NULL
) {
23436 if (aidc
->def
== idc
)
23440 if (aidc
== NULL
) {
23441 VERROR_INT("xmlSchemaIDCRegisterMatchers",
23442 "Could not find an augmented IDC item for an IDC definition");
23446 * Create an IDC matcher for every IDC definition.
23448 if (vctxt
->idcMatcherCache
!= NULL
) {
23450 * Reuse a cached matcher.
23452 matcher
= vctxt
->idcMatcherCache
;
23453 vctxt
->idcMatcherCache
= matcher
->nextCached
;
23454 matcher
->nextCached
= NULL
;
23456 matcher
= (xmlSchemaIDCMatcherPtr
)
23457 xmlMalloc(sizeof(xmlSchemaIDCMatcher
));
23458 if (matcher
== NULL
) {
23459 xmlSchemaVErrMemory(vctxt
,
23460 "allocating an IDC matcher", NULL
);
23463 memset(matcher
, 0, sizeof(xmlSchemaIDCMatcher
));
23466 vctxt
->inode
->idcMatchers
= matcher
;
23468 last
->next
= matcher
;
23471 matcher
->type
= IDC_MATCHER
;
23472 matcher
->depth
= vctxt
->depth
;
23473 matcher
->aidc
= aidc
;
23474 matcher
->idcType
= aidc
->def
->type
;
23476 xmlGenericError(xmlGenericErrorContext
, "IDC: register matcher\n");
23479 * Init the automaton state object.
23481 if (xmlSchemaIDCAddStateObject(vctxt
, matcher
,
23482 idc
->selector
, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR
) == -1)
23486 } while (idc
!= NULL
);
23491 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt
,
23492 xmlSchemaNodeInfoPtr ielem
)
23494 xmlSchemaPSVIIDCBindingPtr bind
;
23495 int res
, i
, j
, k
, nbTargets
, nbFields
, nbDupls
, nbNodeTable
;
23496 xmlSchemaPSVIIDCKeyPtr
*keys
, *ntkeys
;
23497 xmlSchemaPSVIIDCNodePtr
*targets
, *dupls
;
23499 xmlSchemaIDCMatcherPtr matcher
= ielem
->idcMatchers
;
23500 /* vctxt->createIDCNodeTables */
23501 while (matcher
!= NULL
) {
23503 * Skip keyref IDCs and empty IDC target-lists.
23505 if ((matcher
->aidc
->def
->type
== XML_SCHEMA_TYPE_IDC_KEYREF
) ||
23506 WXS_ILIST_IS_EMPTY(matcher
->targets
))
23508 matcher
= matcher
->next
;
23512 * If we _want_ the IDC node-table to be created in any case
23513 * then do so. Otherwise create them only if keyrefs need them.
23515 if ((! vctxt
->createIDCNodeTables
) &&
23516 ((matcher
->aidc
->keyrefDepth
== -1) ||
23517 (matcher
->aidc
->keyrefDepth
> vctxt
->depth
)))
23519 matcher
= matcher
->next
;
23523 * Get/create the IDC binding on this element for the IDC definition.
23525 bind
= xmlSchemaIDCAcquireBinding(vctxt
, matcher
);
23527 goto internal_error
;
23529 if (! WXS_ILIST_IS_EMPTY(bind
->dupls
)) {
23530 dupls
= (xmlSchemaPSVIIDCNodePtr
*) bind
->dupls
->items
;
23531 nbDupls
= bind
->dupls
->nbItems
;
23536 if (bind
->nodeTable
!= NULL
) {
23537 nbNodeTable
= bind
->nbNodes
;
23542 if ((nbNodeTable
== 0) && (nbDupls
== 0)) {
23544 * Transfer all IDC target-nodes to the IDC node-table.
23547 (xmlSchemaPSVIIDCNodePtr
*) matcher
->targets
->items
;
23548 bind
->sizeNodes
= matcher
->targets
->sizeItems
;
23549 bind
->nbNodes
= matcher
->targets
->nbItems
;
23551 matcher
->targets
->items
= NULL
;
23552 matcher
->targets
->sizeItems
= 0;
23553 matcher
->targets
->nbItems
= 0;
23554 if (matcher
->htab
) {
23555 xmlHashFree(matcher
->htab
, xmlFreeIDCHashEntry
);
23556 matcher
->htab
= NULL
;
23560 * Compare the key-sequences and add to the IDC node-table.
23562 nbTargets
= matcher
->targets
->nbItems
;
23563 targets
= (xmlSchemaPSVIIDCNodePtr
*) matcher
->targets
->items
;
23564 nbFields
= matcher
->aidc
->def
->nbFields
;
23567 keys
= targets
[i
]->keys
;
23570 * Search in already found duplicates first.
23574 if (nbFields
== 1) {
23575 res
= xmlSchemaAreValuesEqual(keys
[0]->val
,
23576 dupls
[j
]->keys
[0]->val
);
23578 goto internal_error
;
23581 * Equal key-sequence.
23587 ntkeys
= dupls
[j
]->keys
;
23588 for (k
= 0; k
< nbFields
; k
++) {
23589 res
= xmlSchemaAreValuesEqual(keys
[k
]->val
,
23592 goto internal_error
;
23595 * One of the keys differs.
23602 * Equal key-sequence found.
23608 } while (j
< nbDupls
);
23613 if (nbFields
== 1) {
23614 res
= xmlSchemaAreValuesEqual(keys
[0]->val
,
23615 bind
->nodeTable
[j
]->keys
[0]->val
);
23617 goto internal_error
;
23620 * The key-sequence differs.
23622 goto next_node_table_entry
;
23626 ntkeys
= bind
->nodeTable
[j
]->keys
;
23627 for (k
= 0; k
< nbFields
; k
++) {
23628 res
= xmlSchemaAreValuesEqual(keys
[k
]->val
,
23631 goto internal_error
;
23634 * One of the keys differs.
23636 goto next_node_table_entry
;
23641 * Add the duplicate to the list of duplicates.
23643 if (bind
->dupls
== NULL
) {
23644 bind
->dupls
= xmlSchemaItemListCreate();
23645 if (bind
->dupls
== NULL
)
23646 goto internal_error
;
23648 if (xmlSchemaItemListAdd(bind
->dupls
, bind
->nodeTable
[j
]) == -1)
23649 goto internal_error
;
23651 * Remove the duplicate entry from the IDC node-table.
23653 bind
->nodeTable
[j
] = bind
->nodeTable
[bind
->nbNodes
-1];
23658 next_node_table_entry
:
23660 } while (j
< nbNodeTable
);
23663 * If everything is fine, then add the IDC target-node to
23664 * the IDC node-table.
23666 if (xmlSchemaIDCAppendNodeTableItem(bind
, targets
[i
]) == -1)
23667 goto internal_error
;
23671 } while (i
< nbTargets
);
23673 matcher
= matcher
->next
;
23682 * xmlSchemaBubbleIDCNodeTables:
23683 * @depth: the current tree depth
23685 * Merges IDC bindings of an element at @depth into the corresponding IDC
23686 * bindings of its parent element. If a duplicate note-table entry is found,
23687 * both, the parent node-table entry and child entry are discarded from the
23688 * node-table of the parent.
23690 * Returns 0 if OK and -1 on internal errors.
23693 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt
)
23695 xmlSchemaPSVIIDCBindingPtr bind
; /* IDC bindings of the current node. */
23696 xmlSchemaPSVIIDCBindingPtr
*parTable
, parBind
= NULL
; /* parent IDC bindings. */
23697 xmlSchemaPSVIIDCNodePtr node
, parNode
= NULL
, *dupls
, *parNodes
; /* node-table entries. */
23698 xmlSchemaIDCAugPtr aidc
;
23699 int i
, j
, k
, ret
= 0, nbFields
, oldNum
, oldDupls
;
23701 bind
= vctxt
->inode
->idcTable
;
23702 if (bind
== NULL
) {
23703 /* Fine, no table, no bubbles. */
23707 parTable
= &(vctxt
->elemInfos
[vctxt
->depth
-1]->idcTable
);
23709 * Walk all bindings; create new or add to existing bindings.
23710 * Remove duplicate key-sequences.
23712 while (bind
!= NULL
) {
23714 if ((bind
->nbNodes
== 0) && WXS_ILIST_IS_EMPTY(bind
->dupls
))
23717 * Check if the key/unique IDC table needs to be bubbled.
23719 if (! vctxt
->createIDCNodeTables
) {
23720 aidc
= vctxt
->aidcs
;
23722 if (aidc
->def
== bind
->definition
) {
23723 if ((aidc
->keyrefDepth
== -1) ||
23724 (aidc
->keyrefDepth
>= vctxt
->depth
)) {
23730 } while (aidc
!= NULL
);
23733 if (parTable
!= NULL
)
23734 parBind
= *parTable
;
23736 * Search a matching parent binding for the
23739 while (parBind
!= NULL
) {
23740 if (parBind
->definition
== bind
->definition
)
23742 parBind
= parBind
->next
;
23745 if (parBind
!= NULL
) {
23747 * Compare every node-table entry of the child node,
23748 * i.e. the key-sequence within, ...
23750 oldNum
= parBind
->nbNodes
; /* Skip newly added items. */
23752 if (! WXS_ILIST_IS_EMPTY(parBind
->dupls
)) {
23753 oldDupls
= parBind
->dupls
->nbItems
;
23754 dupls
= (xmlSchemaPSVIIDCNodePtr
*) parBind
->dupls
->items
;
23760 parNodes
= parBind
->nodeTable
;
23761 nbFields
= bind
->definition
->nbFields
;
23763 for (i
= 0; i
< bind
->nbNodes
; i
++) {
23764 node
= bind
->nodeTable
[i
];
23768 * ...with every key-sequence of the parent node, already
23769 * evaluated to be a duplicate key-sequence.
23773 while (j
< oldDupls
) {
23774 if (nbFields
== 1) {
23775 ret
= xmlSchemaAreValuesEqual(
23776 node
->keys
[0]->val
,
23777 dupls
[j
]->keys
[0]->val
);
23779 goto internal_error
;
23785 parNode
= dupls
[j
];
23786 for (k
= 0; k
< nbFields
; k
++) {
23787 ret
= xmlSchemaAreValuesEqual(
23788 node
->keys
[k
]->val
,
23789 parNode
->keys
[k
]->val
);
23791 goto internal_error
;
23797 /* Duplicate found. */
23801 if (j
!= oldDupls
) {
23802 /* Duplicate found. Skip this entry. */
23807 * ... and with every key-sequence of the parent node.
23811 while (j
< oldNum
) {
23812 parNode
= parNodes
[j
];
23813 if (nbFields
== 1) {
23814 ret
= xmlSchemaAreValuesEqual(
23815 node
->keys
[0]->val
,
23816 parNode
->keys
[0]->val
);
23818 goto internal_error
;
23824 for (k
= 0; k
< nbFields
; k
++) {
23825 ret
= xmlSchemaAreValuesEqual(
23826 node
->keys
[k
]->val
,
23827 parNode
->keys
[k
]->val
);
23829 goto internal_error
;
23835 /* Duplicate found. */
23841 * Handle duplicates. Move the duplicate in
23842 * the parent's node-table to the list of
23846 parBind
->nbNodes
--;
23848 * Move last old item to pos of duplicate.
23850 parNodes
[j
] = parNodes
[oldNum
];
23852 if (parBind
->nbNodes
!= oldNum
) {
23854 * If new items exist, move last new item to
23855 * last of old items.
23858 parNodes
[parBind
->nbNodes
];
23860 if (parBind
->dupls
== NULL
) {
23861 parBind
->dupls
= xmlSchemaItemListCreate();
23862 if (parBind
->dupls
== NULL
)
23863 goto internal_error
;
23865 xmlSchemaItemListAdd(parBind
->dupls
, parNode
);
23868 * Add the node-table entry (node and key-sequence) of
23869 * the child node to the node table of the parent node.
23871 if (parBind
->nodeTable
== NULL
) {
23872 parBind
->nodeTable
= (xmlSchemaPSVIIDCNodePtr
*)
23873 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr
));
23874 if (parBind
->nodeTable
== NULL
) {
23875 xmlSchemaVErrMemory(NULL
,
23876 "allocating IDC list of node-table items", NULL
);
23877 goto internal_error
;
23879 parBind
->sizeNodes
= 1;
23880 } else if (parBind
->nbNodes
>= parBind
->sizeNodes
) {
23881 parBind
->sizeNodes
*= 2;
23882 parBind
->nodeTable
= (xmlSchemaPSVIIDCNodePtr
*)
23883 xmlRealloc(parBind
->nodeTable
, parBind
->sizeNodes
*
23884 sizeof(xmlSchemaPSVIIDCNodePtr
));
23885 if (parBind
->nodeTable
== NULL
) {
23886 xmlSchemaVErrMemory(NULL
,
23887 "re-allocating IDC list of node-table items", NULL
);
23888 goto internal_error
;
23891 parNodes
= parBind
->nodeTable
;
23893 * Append the new node-table entry to the 'new node-table
23894 * entries' section.
23896 parNodes
[parBind
->nbNodes
++] = node
;
23904 * No binding for the IDC was found: create a new one and
23905 * copy all node-tables.
23907 parBind
= xmlSchemaIDCNewBinding(bind
->definition
);
23908 if (parBind
== NULL
)
23909 goto internal_error
;
23912 * TODO: Hmm, how to optimize the initial number of
23913 * allocated entries?
23915 if (bind
->nbNodes
!= 0) {
23917 * Add all IDC node-table entries.
23919 if (! vctxt
->psviExposeIDCNodeTables
) {
23921 * Just move the entries.
23922 * NOTE: this is quite save here, since
23923 * all the keyref lookups have already been
23926 parBind
->nodeTable
= bind
->nodeTable
;
23927 bind
->nodeTable
= NULL
;
23928 parBind
->sizeNodes
= bind
->sizeNodes
;
23929 bind
->sizeNodes
= 0;
23930 parBind
->nbNodes
= bind
->nbNodes
;
23934 * Copy the entries.
23936 parBind
->nodeTable
= (xmlSchemaPSVIIDCNodePtr
*)
23937 xmlMalloc(bind
->nbNodes
*
23938 sizeof(xmlSchemaPSVIIDCNodePtr
));
23939 if (parBind
->nodeTable
== NULL
) {
23940 xmlSchemaVErrMemory(NULL
,
23941 "allocating an array of IDC node-table "
23943 xmlSchemaIDCFreeBinding(parBind
);
23944 goto internal_error
;
23946 parBind
->sizeNodes
= bind
->nbNodes
;
23947 parBind
->nbNodes
= bind
->nbNodes
;
23948 memcpy(parBind
->nodeTable
, bind
->nodeTable
,
23949 bind
->nbNodes
* sizeof(xmlSchemaPSVIIDCNodePtr
));
23954 * Move the duplicates.
23956 if (parBind
->dupls
!= NULL
)
23957 xmlSchemaItemListFree(parBind
->dupls
);
23958 parBind
->dupls
= bind
->dupls
;
23959 bind
->dupls
= NULL
;
23961 if (parTable
!= NULL
) {
23962 if (*parTable
== NULL
)
23963 *parTable
= parBind
;
23965 parBind
->next
= *parTable
;
23966 *parTable
= parBind
;
23981 * xmlSchemaCheckCVCIDCKeyRef:
23982 * @vctxt: the WXS validation context
23983 * @elemDecl: the element declaration
23985 * Check the cvc-idc-keyref constraints.
23988 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt
)
23990 xmlSchemaIDCMatcherPtr matcher
;
23991 xmlSchemaPSVIIDCBindingPtr bind
;
23993 matcher
= vctxt
->inode
->idcMatchers
;
23997 while (matcher
!= NULL
) {
23998 if ((matcher
->idcType
== XML_SCHEMA_TYPE_IDC_KEYREF
) &&
23999 matcher
->targets
&&
24000 matcher
->targets
->nbItems
)
24002 int i
, j
, k
, res
, nbFields
, hasDupls
;
24003 xmlSchemaPSVIIDCKeyPtr
*refKeys
, *keys
;
24004 xmlSchemaPSVIIDCNodePtr refNode
= NULL
;
24005 xmlHashTablePtr table
= NULL
;
24007 nbFields
= matcher
->aidc
->def
->nbFields
;
24010 * Find the IDC node-table for the referenced IDC key/unique.
24012 bind
= vctxt
->inode
->idcTable
;
24013 while (bind
!= NULL
) {
24014 if ((xmlSchemaIDCPtr
) matcher
->aidc
->def
->ref
->item
==
24019 hasDupls
= (bind
&& bind
->dupls
&& bind
->dupls
->nbItems
) ? 1 : 0;
24021 * Search for a matching key-sequences.
24024 table
= xmlHashCreate(bind
->nbNodes
* 2);
24025 for (j
= 0; j
< bind
->nbNodes
; j
++) {
24027 xmlIDCHashEntryPtr r
, e
;
24028 keys
= bind
->nodeTable
[j
]->keys
;
24029 xmlSchemaHashKeySequence(vctxt
, &value
, keys
, nbFields
);
24030 e
= xmlMalloc(sizeof *e
);
24032 r
= xmlHashLookup(table
, value
);
24038 xmlHashAddEntry(table
, value
, e
);
24040 FREE_AND_NULL(value
);
24043 for (i
= 0; i
< matcher
->targets
->nbItems
; i
++) {
24045 refNode
= matcher
->targets
->items
[i
];
24046 if (bind
!= NULL
) {
24048 xmlIDCHashEntryPtr e
;
24049 refKeys
= refNode
->keys
;
24050 xmlSchemaHashKeySequence(vctxt
, &value
, refKeys
, nbFields
);
24051 e
= xmlHashLookup(table
, value
);
24052 FREE_AND_NULL(value
);
24054 for (;e
; e
= e
->next
) {
24055 keys
= bind
->nodeTable
[e
->index
]->keys
;
24056 for (k
= 0; k
< nbFields
; k
++) {
24057 res
= xmlSchemaAreValuesEqual(keys
[k
]->val
,
24061 else if (res
== -1) {
24072 if ((res
== 0) && hasDupls
) {
24074 * Search in duplicates
24076 for (j
= 0; j
< bind
->dupls
->nbItems
; j
++) {
24077 keys
= ((xmlSchemaPSVIIDCNodePtr
)
24078 bind
->dupls
->items
[j
])->keys
;
24079 for (k
= 0; k
< nbFields
; k
++) {
24080 res
= xmlSchemaAreValuesEqual(keys
[k
]->val
,
24084 else if (res
== -1) {
24090 * Match in duplicates found.
24092 xmlChar
*str
= NULL
, *strB
= NULL
;
24093 xmlSchemaKeyrefErr(vctxt
,
24094 XML_SCHEMAV_CVC_IDC
, refNode
,
24095 (xmlSchemaTypePtr
) matcher
->aidc
->def
,
24096 "More than one match found for "
24097 "key-sequence %s of keyref '%s'",
24098 xmlSchemaFormatIDCKeySequence(vctxt
, &str
,
24099 refNode
->keys
, nbFields
),
24100 xmlSchemaGetComponentQName(&strB
,
24101 matcher
->aidc
->def
));
24102 FREE_AND_NULL(str
);
24103 FREE_AND_NULL(strB
);
24111 xmlChar
*str
= NULL
, *strB
= NULL
;
24112 xmlSchemaKeyrefErr(vctxt
,
24113 XML_SCHEMAV_CVC_IDC
, refNode
,
24114 (xmlSchemaTypePtr
) matcher
->aidc
->def
,
24115 "No match found for key-sequence %s of keyref '%s'",
24116 xmlSchemaFormatIDCKeySequence(vctxt
, &str
,
24117 refNode
->keys
, nbFields
),
24118 xmlSchemaGetComponentQName(&strB
, matcher
->aidc
->def
));
24119 FREE_AND_NULL(str
);
24120 FREE_AND_NULL(strB
);
24124 xmlHashFree(table
, xmlFreeIDCHashEntry
);
24127 matcher
= matcher
->next
;
24129 /* TODO: Return an error if any error encountered. */
24133 /************************************************************************
24135 * XML Reader validation code *
24137 ************************************************************************/
24139 static xmlSchemaAttrInfoPtr
24140 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt
)
24142 xmlSchemaAttrInfoPtr iattr
;
24144 * Grow/create list of attribute infos.
24146 if (vctxt
->attrInfos
== NULL
) {
24147 vctxt
->attrInfos
= (xmlSchemaAttrInfoPtr
*)
24148 xmlMalloc(sizeof(xmlSchemaAttrInfoPtr
));
24149 vctxt
->sizeAttrInfos
= 1;
24150 if (vctxt
->attrInfos
== NULL
) {
24151 xmlSchemaVErrMemory(vctxt
,
24152 "allocating attribute info list", NULL
);
24155 } else if (vctxt
->sizeAttrInfos
<= vctxt
->nbAttrInfos
) {
24156 vctxt
->sizeAttrInfos
++;
24157 vctxt
->attrInfos
= (xmlSchemaAttrInfoPtr
*)
24158 xmlRealloc(vctxt
->attrInfos
,
24159 vctxt
->sizeAttrInfos
* sizeof(xmlSchemaAttrInfoPtr
));
24160 if (vctxt
->attrInfos
== NULL
) {
24161 xmlSchemaVErrMemory(vctxt
,
24162 "re-allocating attribute info list", NULL
);
24166 iattr
= vctxt
->attrInfos
[vctxt
->nbAttrInfos
++];
24167 if (iattr
->localName
!= NULL
) {
24168 VERROR_INT("xmlSchemaGetFreshAttrInfo",
24169 "attr info not cleared");
24172 iattr
->nodeType
= XML_ATTRIBUTE_NODE
;
24176 * Create an attribute info.
24178 iattr
= (xmlSchemaAttrInfoPtr
)
24179 xmlMalloc(sizeof(xmlSchemaAttrInfo
));
24180 if (iattr
== NULL
) {
24181 xmlSchemaVErrMemory(vctxt
, "creating new attribute info", NULL
);
24184 memset(iattr
, 0, sizeof(xmlSchemaAttrInfo
));
24185 iattr
->nodeType
= XML_ATTRIBUTE_NODE
;
24186 vctxt
->attrInfos
[vctxt
->nbAttrInfos
++] = iattr
;
24192 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt
,
24193 xmlNodePtr attrNode
,
24195 const xmlChar
*localName
,
24196 const xmlChar
*nsName
,
24201 xmlSchemaAttrInfoPtr attr
;
24203 attr
= xmlSchemaGetFreshAttrInfo(vctxt
);
24204 if (attr
== NULL
) {
24205 VERROR_INT("xmlSchemaPushAttribute",
24206 "calling xmlSchemaGetFreshAttrInfo()");
24209 attr
->node
= attrNode
;
24210 attr
->nodeLine
= nodeLine
;
24211 attr
->state
= XML_SCHEMAS_ATTR_UNKNOWN
;
24212 attr
->localName
= localName
;
24213 attr
->nsName
= nsName
;
24215 attr
->flags
|= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES
;
24217 * Evaluate if it's an XSI attribute.
24219 if (nsName
!= NULL
) {
24220 if (xmlStrEqual(localName
, BAD_CAST
"nil")) {
24221 if (xmlStrEqual(attr
->nsName
, xmlSchemaInstanceNs
)) {
24222 attr
->metaType
= XML_SCHEMA_ATTR_INFO_META_XSI_NIL
;
24224 } else if (xmlStrEqual(localName
, BAD_CAST
"type")) {
24225 if (xmlStrEqual(attr
->nsName
, xmlSchemaInstanceNs
)) {
24226 attr
->metaType
= XML_SCHEMA_ATTR_INFO_META_XSI_TYPE
;
24228 } else if (xmlStrEqual(localName
, BAD_CAST
"schemaLocation")) {
24229 if (xmlStrEqual(attr
->nsName
, xmlSchemaInstanceNs
)) {
24230 attr
->metaType
= XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC
;
24232 } else if (xmlStrEqual(localName
, BAD_CAST
"noNamespaceSchemaLocation")) {
24233 if (xmlStrEqual(attr
->nsName
, xmlSchemaInstanceNs
)) {
24234 attr
->metaType
= XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC
;
24236 } else if (xmlStrEqual(attr
->nsName
, xmlNamespaceNs
)) {
24237 attr
->metaType
= XML_SCHEMA_ATTR_INFO_META_XMLNS
;
24240 attr
->value
= value
;
24242 attr
->flags
|= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
;
24243 if (attr
->metaType
!= 0)
24244 attr
->state
= XML_SCHEMAS_ATTR_META
;
24249 * xmlSchemaClearElemInfo:
24250 * @vctxt: the WXS validation context
24251 * @ielem: the element information item
24254 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt
,
24255 xmlSchemaNodeInfoPtr ielem
)
24257 ielem
->hasKeyrefs
= 0;
24258 ielem
->appliedXPath
= 0;
24259 if (ielem
->flags
& XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES
) {
24260 FREE_AND_NULL(ielem
->localName
);
24261 FREE_AND_NULL(ielem
->nsName
);
24263 ielem
->localName
= NULL
;
24264 ielem
->nsName
= NULL
;
24266 if (ielem
->flags
& XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
) {
24267 FREE_AND_NULL(ielem
->value
);
24269 ielem
->value
= NULL
;
24271 if (ielem
->val
!= NULL
) {
24273 * PSVI TODO: Be careful not to free it when the value is
24274 * exposed via PSVI.
24276 xmlSchemaFreeValue(ielem
->val
);
24279 if (ielem
->idcMatchers
!= NULL
) {
24281 * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
24284 xmlSchemaIDCReleaseMatcherList(vctxt
, ielem
->idcMatchers
);
24286 xmlSchemaIDCFreeMatcherList(ielem
->idcMatchers
);
24288 ielem
->idcMatchers
= NULL
;
24290 if (ielem
->idcTable
!= NULL
) {
24292 * OPTIMIZE TODO: Use a pool of IDC tables??.
24294 xmlSchemaIDCFreeIDCTable(ielem
->idcTable
);
24295 ielem
->idcTable
= NULL
;
24297 if (ielem
->regexCtxt
!= NULL
) {
24298 xmlRegFreeExecCtxt(ielem
->regexCtxt
);
24299 ielem
->regexCtxt
= NULL
;
24301 if (ielem
->nsBindings
!= NULL
) {
24302 xmlFree((xmlChar
**)ielem
->nsBindings
);
24303 ielem
->nsBindings
= NULL
;
24304 ielem
->nbNsBindings
= 0;
24305 ielem
->sizeNsBindings
= 0;
24310 * xmlSchemaGetFreshElemInfo:
24311 * @vctxt: the schema validation context
24313 * Creates/reuses and initializes the element info item for
24314 * the current tree depth.
24316 * Returns the element info item or NULL on API or internal errors.
24318 static xmlSchemaNodeInfoPtr
24319 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt
)
24321 xmlSchemaNodeInfoPtr info
= NULL
;
24323 if (vctxt
->depth
> vctxt
->sizeElemInfos
) {
24324 VERROR_INT("xmlSchemaGetFreshElemInfo",
24325 "inconsistent depth encountered");
24328 if (vctxt
->elemInfos
== NULL
) {
24329 vctxt
->elemInfos
= (xmlSchemaNodeInfoPtr
*)
24330 xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr
));
24331 if (vctxt
->elemInfos
== NULL
) {
24332 xmlSchemaVErrMemory(vctxt
,
24333 "allocating the element info array", NULL
);
24336 memset(vctxt
->elemInfos
, 0, 10 * sizeof(xmlSchemaNodeInfoPtr
));
24337 vctxt
->sizeElemInfos
= 10;
24338 } else if (vctxt
->sizeElemInfos
<= vctxt
->depth
) {
24339 int i
= vctxt
->sizeElemInfos
;
24341 vctxt
->sizeElemInfos
*= 2;
24342 vctxt
->elemInfos
= (xmlSchemaNodeInfoPtr
*)
24343 xmlRealloc(vctxt
->elemInfos
, vctxt
->sizeElemInfos
*
24344 sizeof(xmlSchemaNodeInfoPtr
));
24345 if (vctxt
->elemInfos
== NULL
) {
24346 xmlSchemaVErrMemory(vctxt
,
24347 "re-allocating the element info array", NULL
);
24351 * We need the new memory to be NULLed.
24352 * TODO: Use memset instead?
24354 for (; i
< vctxt
->sizeElemInfos
; i
++)
24355 vctxt
->elemInfos
[i
] = NULL
;
24357 info
= vctxt
->elemInfos
[vctxt
->depth
];
24359 if (info
== NULL
) {
24360 info
= (xmlSchemaNodeInfoPtr
)
24361 xmlMalloc(sizeof(xmlSchemaNodeInfo
));
24362 if (info
== NULL
) {
24363 xmlSchemaVErrMemory(vctxt
,
24364 "allocating an element info", NULL
);
24367 vctxt
->elemInfos
[vctxt
->depth
] = info
;
24369 if (info
->localName
!= NULL
) {
24370 VERROR_INT("xmlSchemaGetFreshElemInfo",
24371 "elem info has not been cleared");
24375 memset(info
, 0, sizeof(xmlSchemaNodeInfo
));
24376 info
->nodeType
= XML_ELEMENT_NODE
;
24377 info
->depth
= vctxt
->depth
;
24382 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24383 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24384 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24387 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt
,
24389 xmlSchemaTypePtr type
,
24390 xmlSchemaValType valType
,
24391 const xmlChar
* value
,
24392 xmlSchemaValPtr val
,
24393 unsigned long length
,
24396 int ret
, error
= 0, found
;
24398 xmlSchemaTypePtr tmpType
;
24399 xmlSchemaFacetLinkPtr facetLink
;
24400 xmlSchemaFacetPtr facet
;
24401 unsigned long len
= 0;
24402 xmlSchemaWhitespaceValueType ws
;
24405 * In Libxml2, derived built-in types have currently no explicit facets.
24407 if (type
->type
== XML_SCHEMA_TYPE_BASIC
)
24411 * NOTE: Do not jump away, if the facetSet of the given type is
24412 * empty: until now, "pattern" and "enumeration" facets of the
24413 * *base types* need to be checked as well.
24415 if (type
->facetSet
== NULL
)
24416 goto pattern_and_enum
;
24418 if (! WXS_IS_ATOMIC(type
)) {
24419 if (WXS_IS_LIST(type
))
24422 goto pattern_and_enum
;
24426 * Whitespace handling is only of importance for string-based
24429 tmpType
= xmlSchemaGetPrimitiveType(type
);
24430 if ((tmpType
->builtInType
== XML_SCHEMAS_STRING
) ||
24431 WXS_IS_ANY_SIMPLE_TYPE(tmpType
)) {
24432 ws
= xmlSchemaGetWhiteSpaceFacetValue(type
);
24434 ws
= XML_SCHEMA_WHITESPACE_COLLAPSE
;
24437 * If the value was not computed (for string or
24438 * anySimpleType based types), then use the provided
24442 valType
= xmlSchemaGetValType(val
);
24445 for (facetLink
= type
->facetSet
; facetLink
!= NULL
;
24446 facetLink
= facetLink
->next
) {
24448 * Skip the pattern "whiteSpace": it is used to
24449 * format the character content beforehand.
24451 switch (facetLink
->facet
->type
) {
24452 case XML_SCHEMA_FACET_WHITESPACE
:
24453 case XML_SCHEMA_FACET_PATTERN
:
24454 case XML_SCHEMA_FACET_ENUMERATION
:
24456 case XML_SCHEMA_FACET_LENGTH
:
24457 case XML_SCHEMA_FACET_MINLENGTH
:
24458 case XML_SCHEMA_FACET_MAXLENGTH
:
24459 ret
= xmlSchemaValidateLengthFacetWhtsp(facetLink
->facet
,
24460 valType
, value
, val
, &len
, ws
);
24463 ret
= xmlSchemaValidateFacetWhtsp(facetLink
->facet
, ws
,
24464 valType
, value
, val
, ws
);
24468 AERROR_INT("xmlSchemaValidateFacets",
24469 "validating against a atomic type facet");
24471 } else if (ret
> 0) {
24473 xmlSchemaFacetErr(actxt
, ret
, node
,
24474 value
, len
, type
, facetLink
->facet
, NULL
, NULL
, NULL
);
24484 if (! WXS_IS_LIST(type
))
24485 goto pattern_and_enum
;
24487 * "length", "minLength" and "maxLength" of list types.
24490 for (facetLink
= type
->facetSet
; facetLink
!= NULL
;
24491 facetLink
= facetLink
->next
) {
24493 switch (facetLink
->facet
->type
) {
24494 case XML_SCHEMA_FACET_LENGTH
:
24495 case XML_SCHEMA_FACET_MINLENGTH
:
24496 case XML_SCHEMA_FACET_MAXLENGTH
:
24497 ret
= xmlSchemaValidateListSimpleTypeFacet(facetLink
->facet
,
24498 value
, length
, NULL
);
24504 AERROR_INT("xmlSchemaValidateFacets",
24505 "validating against a list type facet");
24507 } else if (ret
> 0) {
24509 xmlSchemaFacetErr(actxt
, ret
, node
,
24510 value
, length
, type
, facetLink
->facet
, NULL
, NULL
, NULL
);
24522 * Process enumerations. Facet values are in the value space
24523 * of the defining type's base type. This seems to be a bug in the
24524 * XML Schema 1.0 spec. Use the whitespace type of the base type.
24525 * Only the first set of enumerations in the ancestor-or-self axis
24526 * is used for validation.
24531 for (facet
= tmpType
->facets
; facet
!= NULL
; facet
= facet
->next
) {
24532 if (facet
->type
!= XML_SCHEMA_FACET_ENUMERATION
)
24535 ret
= xmlSchemaAreValuesEqual(facet
->val
, val
);
24538 else if (ret
< 0) {
24539 AERROR_INT("xmlSchemaValidateFacets",
24540 "validating against an enumeration facet");
24547 * Break on the first set of enumerations. Any additional
24548 * enumerations which might be existent on the ancestors
24549 * of the current type are restricted by this set; thus
24550 * *must* *not* be taken into account.
24554 tmpType
= tmpType
->baseType
;
24555 } while ((tmpType
!= NULL
) &&
24556 (tmpType
->type
!= XML_SCHEMA_TYPE_BASIC
));
24557 if (found
&& (ret
== 0)) {
24558 ret
= XML_SCHEMAV_CVC_ENUMERATION_VALID
;
24560 xmlSchemaFacetErr(actxt
, ret
, node
,
24561 value
, 0, type
, NULL
, NULL
, NULL
, NULL
);
24569 * Process patters. Pattern facets are ORed at type level
24570 * and ANDed if derived. Walk the base type axis.
24576 for (facetLink
= tmpType
->facetSet
; facetLink
!= NULL
;
24577 facetLink
= facetLink
->next
) {
24578 if (facetLink
->facet
->type
!= XML_SCHEMA_FACET_PATTERN
)
24582 * NOTE that for patterns, @value needs to be the
24583 * normalized value.
24585 ret
= xmlRegexpExec(facetLink
->facet
->regexp
, value
);
24588 else if (ret
< 0) {
24589 AERROR_INT("xmlSchemaValidateFacets",
24590 "validating against a pattern facet");
24594 * Save the last non-validating facet.
24596 facet
= facetLink
->facet
;
24599 if (found
&& (ret
!= 1)) {
24600 ret
= XML_SCHEMAV_CVC_PATTERN_VALID
;
24602 xmlSchemaFacetErr(actxt
, ret
, node
,
24603 value
, 0, type
, facet
, NULL
, NULL
, NULL
);
24610 tmpType
= tmpType
->baseType
;
24611 } while ((tmpType
!= NULL
) && (tmpType
->type
!= XML_SCHEMA_TYPE_BASIC
));
24617 xmlSchemaNormalizeValue(xmlSchemaTypePtr type
,
24618 const xmlChar
*value
)
24620 switch (xmlSchemaGetWhiteSpaceFacetValue(type
)) {
24621 case XML_SCHEMA_WHITESPACE_COLLAPSE
:
24622 return (xmlSchemaCollapseString(value
));
24623 case XML_SCHEMA_WHITESPACE_REPLACE
:
24624 return (xmlSchemaWhiteSpaceReplace(value
));
24631 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt
,
24632 const xmlChar
*value
,
24633 xmlSchemaValPtr
*val
,
24638 const xmlChar
*nsName
;
24639 xmlChar
*local
, *prefix
= NULL
;
24641 ret
= xmlValidateQName(value
, 1);
24644 VERROR_INT("xmlSchemaValidateQName",
24645 "calling xmlValidateQName()");
24648 return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
);
24651 * NOTE: xmlSplitQName2 will always return a duplicated
24654 /* TODO: Export and use xmlSchemaStrip instead */
24655 stripped
= xmlSchemaCollapseString(value
);
24656 local
= xmlSplitQName2(stripped
? stripped
: value
, &prefix
);
24659 local
= xmlStrdup(value
);
24661 * OPTIMIZE TODO: Use flags for:
24662 * - is there any namespace binding?
24663 * - is there a default namespace?
24665 nsName
= xmlSchemaLookupNamespace(vctxt
, prefix
);
24667 if (prefix
!= NULL
) {
24670 * A namespace must be found if the prefix is
24673 if (nsName
== NULL
) {
24674 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
;
24675 xmlSchemaCustomErr(ACTXT_CAST vctxt
, ret
, NULL
,
24676 WXS_BASIC_CAST
xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME
),
24677 "The QName value '%s' has no "
24678 "corresponding namespace declaration in "
24679 "scope", value
, NULL
);
24685 if (valNeeded
&& val
) {
24686 if (nsName
!= NULL
)
24687 *val
= xmlSchemaNewQNameValue(
24688 BAD_CAST
xmlStrdup(nsName
), BAD_CAST local
);
24690 *val
= xmlSchemaNewQNameValue(NULL
,
24701 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt
,
24703 xmlSchemaTypePtr type
,
24704 const xmlChar
*value
,
24705 xmlSchemaValPtr
*retVal
,
24710 int ret
= 0, valNeeded
= (retVal
) ? 1 : 0;
24711 xmlSchemaValPtr val
= NULL
;
24712 /* xmlSchemaWhitespaceValueType ws; */
24713 xmlChar
*normValue
= NULL
;
24715 #define NORMALIZE(atype) \
24716 if ((! isNormalized) && \
24717 (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24718 normValue = xmlSchemaNormalizeValue(atype, value); \
24719 if (normValue != NULL) \
24720 value = normValue; \
24721 isNormalized = 1; \
24724 if ((retVal
!= NULL
) && (*retVal
!= NULL
)) {
24725 xmlSchemaFreeValue(*retVal
);
24729 * 3.14.4 Simple Type Definition Validation Rules
24730 * Validation Rule: String Valid
24733 * 1 It is schema-valid with respect to that definition as defined
24734 * by Datatype Valid in [XML Schemas: Datatypes].
24737 * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24738 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
24739 * the string must be a `declared entity name`.
24742 * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24743 * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
24744 * then every whitespace-delimited substring of the string must be a `declared
24748 * 2.3 otherwise no further condition applies.
24750 if ((! valNeeded
) && (type
->flags
& XML_SCHEMAS_TYPE_FACETSNEEDVALUE
))
24753 value
= BAD_CAST
"";
24754 if (WXS_IS_ANY_SIMPLE_TYPE(type
) || WXS_IS_ATOMIC(type
)) {
24755 xmlSchemaTypePtr biType
; /* The built-in type. */
24757 * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
24758 * a literal in the `lexical space` of {base type definition}"
24761 * Whitespace-normalize.
24764 if (type
->type
!= XML_SCHEMA_TYPE_BASIC
) {
24766 * Get the built-in type.
24768 biType
= type
->baseType
;
24769 while ((biType
!= NULL
) &&
24770 (biType
->type
!= XML_SCHEMA_TYPE_BASIC
))
24771 biType
= biType
->baseType
;
24773 if (biType
== NULL
) {
24774 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24775 "could not get the built-in type");
24776 goto internal_error
;
24781 * NOTATIONs need to be processed here, since they need
24782 * to lookup in the hashtable of NOTATION declarations of the schema.
24784 if (actxt
->type
== XML_SCHEMA_CTXT_VALIDATOR
) {
24785 switch (biType
->builtInType
) {
24786 case XML_SCHEMAS_NOTATION
:
24787 ret
= xmlSchemaValidateNotation(
24788 (xmlSchemaValidCtxtPtr
) actxt
,
24789 ((xmlSchemaValidCtxtPtr
) actxt
)->schema
,
24790 NULL
, value
, &val
, valNeeded
);
24792 case XML_SCHEMAS_QNAME
:
24793 ret
= xmlSchemaValidateQName((xmlSchemaValidCtxtPtr
) actxt
,
24794 value
, &val
, valNeeded
);
24797 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24799 ret
= xmlSchemaValPredefTypeNodeNoNorm(biType
,
24800 value
, &val
, node
);
24802 ret
= xmlSchemaValPredefTypeNodeNoNorm(biType
,
24803 value
, NULL
, node
);
24806 } else if (actxt
->type
== XML_SCHEMA_CTXT_PARSER
) {
24807 switch (biType
->builtInType
) {
24808 case XML_SCHEMAS_NOTATION
:
24809 ret
= xmlSchemaValidateNotation(NULL
,
24810 ((xmlSchemaParserCtxtPtr
) actxt
)->schema
, node
,
24811 value
, &val
, valNeeded
);
24814 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24816 ret
= xmlSchemaValPredefTypeNodeNoNorm(biType
,
24817 value
, &val
, node
);
24819 ret
= xmlSchemaValPredefTypeNodeNoNorm(biType
,
24820 value
, NULL
, node
);
24825 * Validation via a public API is not implemented yet.
24828 goto internal_error
;
24832 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24833 "validating against a built-in type");
24834 goto internal_error
;
24836 if (WXS_IS_LIST(type
))
24837 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2
;
24839 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
;
24841 if ((ret
== 0) && (type
->flags
& XML_SCHEMAS_TYPE_HAS_FACETS
)) {
24845 ret
= xmlSchemaValidateFacets(actxt
, node
, type
,
24846 (xmlSchemaValType
) biType
->builtInType
, value
, val
,
24850 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24851 "validating facets of atomic simple type");
24852 goto internal_error
;
24854 if (WXS_IS_LIST(type
))
24855 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2
;
24857 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
;
24860 else if (fireErrors
&& (ret
> 0))
24861 xmlSchemaSimpleTypeErr(actxt
, ret
, node
, value
, type
, 1);
24862 } else if (WXS_IS_LIST(type
)) {
24864 xmlSchemaTypePtr itemType
;
24865 const xmlChar
*cur
, *end
;
24866 xmlChar
*tmpValue
= NULL
;
24867 unsigned long len
= 0;
24868 xmlSchemaValPtr prevVal
= NULL
, curVal
= NULL
;
24869 /* 1.2.2 if {variety} is `list` then the string must be a sequence
24870 * of white space separated tokens, each of which `match`es a literal
24871 * in the `lexical space` of {item type definition}
24874 * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24875 * the list type has an enum or pattern facet.
24879 * VAL TODO: Optimize validation of empty values.
24880 * VAL TODO: We do not have computed values for lists.
24882 itemType
= WXS_LIST_ITEMTYPE(type
);
24885 while (IS_BLANK_CH(*cur
))
24888 while ((*end
!= 0) && (!(IS_BLANK_CH(*end
))))
24892 tmpValue
= xmlStrndup(cur
, end
- cur
);
24896 ret
= xmlSchemaVCheckCVCSimpleType(actxt
, node
, itemType
,
24897 tmpValue
, &curVal
, fireErrors
, 0, 1);
24899 ret
= xmlSchemaVCheckCVCSimpleType(actxt
, node
, itemType
,
24900 tmpValue
, NULL
, fireErrors
, 0, 1);
24901 FREE_AND_NULL(tmpValue
);
24902 if (curVal
!= NULL
) {
24904 * Add to list of computed values.
24909 xmlSchemaValueAppend(prevVal
, curVal
);
24915 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24916 "validating an item of list simple type");
24917 goto internal_error
;
24919 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2
;
24923 } while (*cur
!= 0);
24924 FREE_AND_NULL(tmpValue
);
24925 if ((ret
== 0) && (type
->flags
& XML_SCHEMAS_TYPE_HAS_FACETS
)) {
24927 * Apply facets (pattern, enumeration).
24929 ret
= xmlSchemaValidateFacets(actxt
, node
, type
,
24930 XML_SCHEMAS_UNKNOWN
, value
, val
,
24934 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24935 "validating facets of list simple type");
24936 goto internal_error
;
24938 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2
;
24941 if (fireErrors
&& (ret
> 0)) {
24943 * Report the normalized value.
24947 xmlSchemaSimpleTypeErr(actxt
, ret
, node
, value
, type
, 1);
24949 } else if (WXS_IS_UNION(type
)) {
24950 xmlSchemaTypeLinkPtr memberLink
;
24952 * TODO: For all datatypes `derived` by `union` whiteSpace does
24953 * not apply directly; however, the normalization behavior of `union`
24954 * types is controlled by the value of whiteSpace on that one of the
24955 * `memberTypes` against which the `union` is successfully validated.
24957 * This means that the value is normalized by the first validating
24958 * member type, then the facets of the union type are applied. This
24959 * needs changing of the value!
24963 * 1.2.3 if {variety} is `union` then the string must `match` a
24964 * literal in the `lexical space` of at least one member of
24965 * {member type definitions}
24967 memberLink
= xmlSchemaGetUnionSimpleTypeMemberTypes(type
);
24968 if (memberLink
== NULL
) {
24969 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24970 "union simple type has no member types");
24971 goto internal_error
;
24974 * Always normalize union type values, since we currently
24975 * cannot store the whitespace information with the value
24976 * itself; otherwise a later value-comparison would be
24979 while (memberLink
!= NULL
) {
24981 ret
= xmlSchemaVCheckCVCSimpleType(actxt
, node
,
24982 memberLink
->type
, value
, &val
, 0, 1, 0);
24984 ret
= xmlSchemaVCheckCVCSimpleType(actxt
, node
,
24985 memberLink
->type
, value
, NULL
, 0, 1, 0);
24988 memberLink
= memberLink
->next
;
24992 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24993 "validating members of union simple type");
24994 goto internal_error
;
24996 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3
;
24999 * Apply facets (pattern, enumeration).
25001 if ((ret
== 0) && (type
->flags
& XML_SCHEMAS_TYPE_HAS_FACETS
)) {
25003 * The normalization behavior of `union` types is controlled by
25004 * the value of whiteSpace on that one of the `memberTypes`
25005 * against which the `union` is successfully validated.
25007 NORMALIZE(memberLink
->type
);
25008 ret
= xmlSchemaValidateFacets(actxt
, node
, type
,
25009 XML_SCHEMAS_UNKNOWN
, value
, val
,
25013 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
25014 "validating facets of union simple type");
25015 goto internal_error
;
25017 ret
= XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3
;
25020 if (fireErrors
&& (ret
> 0))
25021 xmlSchemaSimpleTypeErr(actxt
, ret
, node
, value
, type
, 1);
25024 if (normValue
!= NULL
)
25025 xmlFree(normValue
);
25027 if (retVal
!= NULL
)
25029 else if (val
!= NULL
)
25030 xmlSchemaFreeValue(val
);
25031 } else if (val
!= NULL
)
25032 xmlSchemaFreeValue(val
);
25035 if (normValue
!= NULL
)
25036 xmlFree(normValue
);
25038 xmlSchemaFreeValue(val
);
25043 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt
,
25044 const xmlChar
*value
,
25045 const xmlChar
**nsName
,
25046 const xmlChar
**localName
)
25050 if ((nsName
== NULL
) || (localName
== NULL
))
25055 ret
= xmlValidateQName(value
, 1);
25059 xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt
,
25060 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
, NULL
,
25061 value
, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME
), 1);
25065 xmlChar
*local
= NULL
;
25069 * NOTE: xmlSplitQName2 will return a duplicated
25072 local
= xmlSplitQName2(value
, &prefix
);
25074 *localName
= xmlDictLookup(vctxt
->dict
, value
, -1);
25076 *localName
= xmlDictLookup(vctxt
->dict
, local
, -1);
25080 *nsName
= xmlSchemaLookupNamespace(vctxt
, prefix
);
25082 if (prefix
!= NULL
) {
25085 * A namespace must be found if the prefix is NOT NULL.
25087 if (*nsName
== NULL
) {
25088 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
25089 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1
, NULL
,
25090 WXS_BASIC_CAST
xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME
),
25091 "The QName value '%s' has no "
25092 "corresponding namespace declaration in scope",
25102 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt
,
25103 xmlSchemaAttrInfoPtr iattr
,
25104 xmlSchemaTypePtr
*localType
,
25105 xmlSchemaElementPtr elemDecl
)
25109 * cvc-elt (3.3.4) : (4)
25111 * Schema-Validity Assessment (Element) (cvc-assess-elt)
25112 * (1.2.1.2.1) - (1.2.1.2.4)
25113 * Handle 'xsi:type'.
25115 if (localType
== NULL
)
25121 const xmlChar
*nsName
= NULL
, *local
= NULL
;
25123 * TODO: We should report a *warning* that the type was overridden
25126 ACTIVATE_ATTRIBUTE(iattr
);
25128 * (cvc-elt) (3.3.4) : (4.1)
25129 * (cvc-assess-elt) (1.2.1.2.2)
25131 ret
= xmlSchemaVExpandQName(vctxt
, iattr
->value
,
25135 VERROR_INT("xmlSchemaValidateElementByDeclaration",
25136 "calling xmlSchemaQNameExpand() to validate the "
25137 "attribute 'xsi:type'");
25138 goto internal_error
;
25143 * (cvc-elt) (3.3.4) : (4.2)
25144 * (cvc-assess-elt) (1.2.1.2.3)
25146 *localType
= xmlSchemaGetType(vctxt
->schema
, local
, nsName
);
25147 if (*localType
== NULL
) {
25148 xmlChar
*str
= NULL
;
25150 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
25151 XML_SCHEMAV_CVC_ELT_4_2
, NULL
,
25152 WXS_BASIC_CAST
xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME
),
25153 "The QName value '%s' of the xsi:type attribute does not "
25154 "resolve to a type definition",
25155 xmlSchemaFormatQName(&str
, nsName
, local
), NULL
);
25156 FREE_AND_NULL(str
);
25160 if (elemDecl
!= NULL
) {
25164 * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
25165 * "The `local type definition` must be validly
25166 * derived from the {type definition} given the union of
25167 * the {disallowed substitutions} and the {type definition}'s
25168 * {prohibited substitutions}, as defined in
25169 * Type Derivation OK (Complex) ($3.4.6)
25170 * (if it is a complex type definition),
25171 * or given {disallowed substitutions} as defined in Type
25172 * Derivation OK (Simple) ($3.14.6) (if it is a simple type
25175 * {disallowed substitutions}: the "block" on the element decl.
25176 * {prohibited substitutions}: the "block" on the type def.
25179 * OPTIMIZE TODO: We could map types already evaluated
25180 * to be validly derived from other types to avoid checking
25181 * this over and over for the same types.
25183 if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_BLOCK_EXTENSION
) ||
25184 (elemDecl
->subtypes
->flags
&
25185 XML_SCHEMAS_TYPE_BLOCK_EXTENSION
))
25186 set
|= SUBSET_EXTENSION
;
25188 if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_BLOCK_RESTRICTION
) ||
25189 (elemDecl
->subtypes
->flags
&
25190 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION
))
25191 set
|= SUBSET_RESTRICTION
;
25194 * REMOVED and CHANGED since this produced a parser context
25195 * which adds to the string dict of the schema. So this would
25196 * change the schema and we don't want this. We don't need
25197 * the parser context anymore.
25199 * if ((vctxt->pctxt == NULL) &&
25200 * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
25204 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt
, *localType
,
25205 elemDecl
->subtypes
, set
) != 0) {
25206 xmlChar
*str
= NULL
;
25208 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
25209 XML_SCHEMAV_CVC_ELT_4_3
, NULL
, NULL
,
25210 "The type definition '%s', specified by xsi:type, is "
25211 "blocked or not validly derived from the type definition "
25212 "of the element declaration",
25213 xmlSchemaFormatQName(&str
,
25214 (*localType
)->targetNamespace
,
25215 (*localType
)->name
),
25217 FREE_AND_NULL(str
);
25232 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt
)
25234 xmlSchemaElementPtr elemDecl
= vctxt
->inode
->decl
;
25235 xmlSchemaTypePtr actualType
;
25238 * cvc-elt (3.3.4) : 1
25240 if (elemDecl
== NULL
) {
25241 VERROR(XML_SCHEMAV_CVC_ELT_1
, NULL
,
25242 "No matching declaration available");
25243 return (vctxt
->err
);
25245 actualType
= WXS_ELEM_TYPEDEF(elemDecl
);
25247 * cvc-elt (3.3.4) : 2
25249 if (elemDecl
->flags
& XML_SCHEMAS_ELEM_ABSTRACT
) {
25250 VERROR(XML_SCHEMAV_CVC_ELT_2
, NULL
,
25251 "The element declaration is abstract");
25252 return (vctxt
->err
);
25254 if (actualType
== NULL
) {
25255 VERROR(XML_SCHEMAV_CVC_TYPE_1
, NULL
,
25256 "The type definition is absent");
25257 return (XML_SCHEMAV_CVC_TYPE_1
);
25259 if (vctxt
->nbAttrInfos
!= 0) {
25261 xmlSchemaAttrInfoPtr iattr
;
25263 * cvc-elt (3.3.4) : 3
25264 * Handle 'xsi:nil'.
25266 iattr
= xmlSchemaGetMetaAttrInfo(vctxt
,
25267 XML_SCHEMA_ATTR_INFO_META_XSI_NIL
);
25269 ACTIVATE_ATTRIBUTE(iattr
);
25271 * Validate the value.
25273 ret
= xmlSchemaVCheckCVCSimpleType(
25274 ACTXT_CAST vctxt
, NULL
,
25275 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN
),
25276 iattr
->value
, &(iattr
->val
), 1, 0, 0);
25279 VERROR_INT("xmlSchemaValidateElemDecl",
25280 "calling xmlSchemaVCheckCVCSimpleType() to "
25281 "validate the attribute 'xsi:nil'");
25285 if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_NILLABLE
) == 0) {
25287 * cvc-elt (3.3.4) : 3.1
25289 VERROR(XML_SCHEMAV_CVC_ELT_3_1
, NULL
,
25290 "The element is not 'nillable'");
25291 /* Does not return an error on purpose. */
25293 if (xmlSchemaValueGetAsBoolean(iattr
->val
)) {
25295 * cvc-elt (3.3.4) : 3.2.2
25297 if ((elemDecl
->flags
& XML_SCHEMAS_ELEM_FIXED
) &&
25298 (elemDecl
->value
!= NULL
)) {
25299 VERROR(XML_SCHEMAV_CVC_ELT_3_2_2
, NULL
,
25300 "The element cannot be 'nilled' because "
25301 "there is a fixed value constraint defined "
25303 /* Does not return an error on purpose. */
25305 vctxt
->inode
->flags
|=
25306 XML_SCHEMA_ELEM_INFO_NILLED
;
25312 * cvc-elt (3.3.4) : 4
25313 * Handle 'xsi:type'.
25315 iattr
= xmlSchemaGetMetaAttrInfo(vctxt
,
25316 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE
);
25318 xmlSchemaTypePtr localType
= NULL
;
25320 ret
= xmlSchemaProcessXSIType(vctxt
, iattr
, &localType
,
25324 VERROR_INT("xmlSchemaValidateElemDecl",
25325 "calling xmlSchemaProcessXSIType() to "
25326 "process the attribute 'xsi:type'");
25329 /* Does not return an error on purpose. */
25331 if (localType
!= NULL
) {
25332 vctxt
->inode
->flags
|= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE
;
25333 actualType
= localType
;
25338 * IDC: Register identity-constraint XPath matchers.
25340 if ((elemDecl
->idcs
!= NULL
) &&
25341 (xmlSchemaIDCRegisterMatchers(vctxt
, elemDecl
) == -1))
25344 * No actual type definition.
25346 if (actualType
== NULL
) {
25347 VERROR(XML_SCHEMAV_CVC_TYPE_1
, NULL
,
25348 "The type definition is absent");
25349 return (XML_SCHEMAV_CVC_TYPE_1
);
25352 * Remember the actual type definition.
25354 vctxt
->inode
->typeDef
= actualType
;
25360 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt
)
25362 xmlSchemaAttrInfoPtr iattr
;
25366 * SPEC cvc-type (3.1.1)
25367 * "The attributes of must be empty, excepting those whose namespace
25368 * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25369 * whose local name is one of type, nil, schemaLocation or
25370 * noNamespaceSchemaLocation."
25372 if (vctxt
->nbAttrInfos
== 0)
25374 for (i
= 0; i
< vctxt
->nbAttrInfos
; i
++) {
25375 iattr
= vctxt
->attrInfos
[i
];
25376 if (! iattr
->metaType
) {
25377 ACTIVATE_ATTRIBUTE(iattr
)
25378 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt
,
25379 XML_SCHEMAV_CVC_TYPE_3_1_1
, iattr
, NULL
);
25380 ret
= XML_SCHEMAV_CVC_TYPE_3_1_1
;
25388 * Cleanup currently used attribute infos.
25391 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt
)
25394 xmlSchemaAttrInfoPtr attr
;
25396 if (vctxt
->nbAttrInfos
== 0)
25398 for (i
= 0; i
< vctxt
->nbAttrInfos
; i
++) {
25399 attr
= vctxt
->attrInfos
[i
];
25400 if (attr
->flags
& XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES
) {
25401 if (attr
->localName
!= NULL
)
25402 xmlFree((xmlChar
*) attr
->localName
);
25403 if (attr
->nsName
!= NULL
)
25404 xmlFree((xmlChar
*) attr
->nsName
);
25406 if (attr
->flags
& XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
) {
25407 if (attr
->value
!= NULL
)
25408 xmlFree((xmlChar
*) attr
->value
);
25410 if (attr
->val
!= NULL
) {
25411 xmlSchemaFreeValue(attr
->val
);
25414 memset(attr
, 0, sizeof(xmlSchemaAttrInfo
));
25416 vctxt
->nbAttrInfos
= 0;
25420 * 3.4.4 Complex Type Definition Validation Rules
25421 * Element Locally Valid (Complex Type) (cvc-complex-type)
25422 * 3.2.4 Attribute Declaration Validation Rules
25423 * Validation Rule: Attribute Locally Valid (cvc-attribute)
25424 * Attribute Locally Valid (Use) (cvc-au)
25426 * Only "assessed" attribute information items will be visible to
25427 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25430 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt
)
25432 xmlSchemaTypePtr type
= vctxt
->inode
->typeDef
;
25433 xmlSchemaItemListPtr attrUseList
;
25434 xmlSchemaAttributeUsePtr attrUse
= NULL
;
25435 xmlSchemaAttributePtr attrDecl
= NULL
;
25436 xmlSchemaAttrInfoPtr iattr
, tmpiattr
;
25437 int i
, j
, found
, nbAttrs
, nbUses
;
25438 int xpathRes
= 0, res
, wildIDs
= 0, fixed
;
25439 xmlNodePtr defAttrOwnerElem
= NULL
;
25442 * SPEC (cvc-attribute)
25443 * (1) "The declaration must not be `absent` (see Missing
25444 * Sub-components ($5.3) for how this can fail to be
25446 * (2) "Its {type definition} must not be absent."
25448 * NOTE (1) + (2): This is not handled here, since we currently do not
25449 * allow validation against schemas which have missing sub-components.
25451 * SPEC (cvc-complex-type)
25452 * (3) "For each attribute information item in the element information
25453 * item's [attributes] excepting those whose [namespace name] is
25454 * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25455 * [local name] is one of type, nil, schemaLocation or
25456 * noNamespaceSchemaLocation, the appropriate case among the following
25460 attrUseList
= (xmlSchemaItemListPtr
) type
->attrUses
;
25462 * @nbAttrs is the number of attributes present in the instance.
25464 nbAttrs
= vctxt
->nbAttrInfos
;
25465 if (attrUseList
!= NULL
)
25466 nbUses
= attrUseList
->nbItems
;
25469 for (i
= 0; i
< nbUses
; i
++) {
25471 attrUse
= attrUseList
->items
[i
];
25472 attrDecl
= WXS_ATTRUSE_DECL(attrUse
);
25473 for (j
= 0; j
< nbAttrs
; j
++) {
25474 iattr
= vctxt
->attrInfos
[j
];
25476 * SPEC (cvc-complex-type) (3)
25477 * Skip meta attributes.
25479 if (iattr
->metaType
)
25481 if (iattr
->localName
[0] != attrDecl
->name
[0])
25483 if (!xmlStrEqual(iattr
->localName
, attrDecl
->name
))
25485 if (!xmlStrEqual(iattr
->nsName
, attrDecl
->targetNamespace
))
25489 * SPEC (cvc-complex-type)
25490 * (3.1) "If there is among the {attribute uses} an attribute
25491 * use with an {attribute declaration} whose {name} matches
25492 * the attribute information item's [local name] and whose
25493 * {target namespace} is identical to the attribute information
25494 * item's [namespace name] (where an `absent` {target namespace}
25495 * is taken to be identical to a [namespace name] with no value),
25496 * then the attribute information must be `valid` with respect
25497 * to that attribute use as per Attribute Locally Valid (Use)
25498 * ($3.5.4). In this case the {attribute declaration} of that
25499 * attribute use is the `context-determined declaration` for the
25500 * attribute information item with respect to Schema-Validity
25501 * Assessment (Attribute) ($3.2.4) and
25502 * Assessment Outcome (Attribute) ($3.2.5).
25504 iattr
->state
= XML_SCHEMAS_ATTR_ASSESSED
;
25505 iattr
->use
= attrUse
;
25507 * Context-determined declaration.
25509 iattr
->decl
= attrDecl
;
25510 iattr
->typeDef
= attrDecl
->subtypes
;
25517 if (attrUse
->occurs
== XML_SCHEMAS_ATTR_USE_REQUIRED
) {
25519 * Handle non-existent, required attributes.
25521 * SPEC (cvc-complex-type)
25522 * (4) "The {attribute declaration} of each attribute use in
25523 * the {attribute uses} whose {required} is true matches one
25524 * of the attribute information items in the element information
25525 * item's [attributes] as per clause 3.1 above."
25527 tmpiattr
= xmlSchemaGetFreshAttrInfo(vctxt
);
25528 if (tmpiattr
== NULL
) {
25530 "xmlSchemaVAttributesComplex",
25531 "calling xmlSchemaGetFreshAttrInfo()");
25534 tmpiattr
->state
= XML_SCHEMAS_ATTR_ERR_MISSING
;
25535 tmpiattr
->use
= attrUse
;
25536 tmpiattr
->decl
= attrDecl
;
25537 } else if ((attrUse
->occurs
== XML_SCHEMAS_ATTR_USE_OPTIONAL
) &&
25538 ((attrUse
->defValue
!= NULL
) ||
25539 (attrDecl
->defValue
!= NULL
))) {
25541 * Handle non-existent, optional, default/fixed attributes.
25543 tmpiattr
= xmlSchemaGetFreshAttrInfo(vctxt
);
25544 if (tmpiattr
== NULL
) {
25546 "xmlSchemaVAttributesComplex",
25547 "calling xmlSchemaGetFreshAttrInfo()");
25550 tmpiattr
->state
= XML_SCHEMAS_ATTR_DEFAULT
;
25551 tmpiattr
->use
= attrUse
;
25552 tmpiattr
->decl
= attrDecl
;
25553 tmpiattr
->typeDef
= attrDecl
->subtypes
;
25554 tmpiattr
->localName
= attrDecl
->name
;
25555 tmpiattr
->nsName
= attrDecl
->targetNamespace
;
25559 if (vctxt
->nbAttrInfos
== 0)
25562 * Validate against the wildcard.
25564 if (type
->attributeWildcard
!= NULL
) {
25566 * SPEC (cvc-complex-type)
25567 * (3.2.1) "There must be an {attribute wildcard}."
25569 for (i
= 0; i
< nbAttrs
; i
++) {
25570 iattr
= vctxt
->attrInfos
[i
];
25572 * SPEC (cvc-complex-type) (3)
25573 * Skip meta attributes.
25575 if (iattr
->state
!= XML_SCHEMAS_ATTR_UNKNOWN
)
25578 * SPEC (cvc-complex-type)
25579 * (3.2.2) "The attribute information item must be `valid` with
25580 * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
25582 * SPEC Item Valid (Wildcard) (cvc-wildcard)
25583 * "... its [namespace name] must be `valid` with respect to
25584 * the wildcard constraint, as defined in Wildcard allows
25585 * Namespace Name ($3.10.4)."
25587 if (xmlSchemaCheckCVCWildcardNamespace(type
->attributeWildcard
,
25588 iattr
->nsName
) == 0) {
25590 * Handle processContents.
25592 * SPEC (cvc-wildcard):
25593 * processContents | context-determined declaration:
25594 * "strict" "mustFind"
25598 if (type
->attributeWildcard
->processContents
==
25599 XML_SCHEMAS_ANY_SKIP
) {
25601 * context-determined declaration = "skip"
25603 * SPEC PSVI Assessment Outcome (Attribute)
25604 * [validity] = "notKnown"
25605 * [validation attempted] = "none"
25607 iattr
->state
= XML_SCHEMAS_ATTR_WILD_SKIP
;
25611 * Find an attribute declaration.
25613 iattr
->decl
= xmlSchemaGetAttributeDecl(vctxt
->schema
,
25614 iattr
->localName
, iattr
->nsName
);
25615 if (iattr
->decl
!= NULL
) {
25616 iattr
->state
= XML_SCHEMAS_ATTR_ASSESSED
;
25618 * SPEC (cvc-complex-type)
25619 * (5) "Let [Definition:] the wild IDs be the set of
25620 * all attribute information item to which clause 3.2
25621 * applied and whose `validation` resulted in a
25622 * `context-determined declaration` of mustFind or no
25623 * `context-determined declaration` at all, and whose
25624 * [local name] and [namespace name] resolve (as
25625 * defined by QName resolution (Instance) ($3.15.4)) to
25626 * an attribute declaration whose {type definition} is
25627 * or is derived from ID. Then all of the following
25630 iattr
->typeDef
= WXS_ATTR_TYPEDEF(iattr
->decl
);
25631 if (xmlSchemaIsDerivedFromBuiltInType(
25632 iattr
->typeDef
, XML_SCHEMAS_ID
)) {
25634 * SPEC (5.1) "There must be no more than one
25635 * item in `wild IDs`."
25637 if (wildIDs
!= 0) {
25639 iattr
->state
= XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID
;
25645 * SPEC (cvc-complex-type)
25646 * (5.2) "If `wild IDs` is non-empty, there must not
25647 * be any attribute uses among the {attribute uses}
25648 * whose {attribute declaration}'s {type definition}
25649 * is or is derived from ID."
25651 if (attrUseList
!= NULL
) {
25652 for (j
= 0; j
< attrUseList
->nbItems
; j
++) {
25653 if (xmlSchemaIsDerivedFromBuiltInType(
25654 WXS_ATTRUSE_TYPEDEF(attrUseList
->items
[j
]),
25656 /* URGENT VAL TODO: implement */
25657 iattr
->state
= XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID
;
25664 } else if (type
->attributeWildcard
->processContents
==
25665 XML_SCHEMAS_ANY_LAX
) {
25666 iattr
->state
= XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL
;
25668 * SPEC PSVI Assessment Outcome (Attribute)
25669 * [validity] = "notKnown"
25670 * [validation attempted] = "none"
25673 iattr
->state
= XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL
;
25679 if (vctxt
->nbAttrInfos
== 0)
25683 * Get the owner element; needed for creation of default attributes.
25684 * This fixes bug #341337, reported by David Grohmann.
25686 if (vctxt
->options
& XML_SCHEMA_VAL_VC_I_CREATE
) {
25687 xmlSchemaNodeInfoPtr ielem
= vctxt
->elemInfos
[vctxt
->depth
];
25688 if (ielem
&& ielem
->node
&& ielem
->node
->doc
)
25689 defAttrOwnerElem
= ielem
->node
;
25692 * Validate values, create default attributes, evaluate IDCs.
25694 for (i
= 0; i
< vctxt
->nbAttrInfos
; i
++) {
25695 iattr
= vctxt
->attrInfos
[i
];
25697 * VAL TODO: Note that we won't try to resolve IDCs to
25698 * "lax" and "skip" validated attributes. Check what to
25701 if ((iattr
->state
!= XML_SCHEMAS_ATTR_ASSESSED
) &&
25702 (iattr
->state
!= XML_SCHEMAS_ATTR_DEFAULT
))
25705 * VAL TODO: What to do if the type definition is missing?
25707 if (iattr
->typeDef
== NULL
) {
25708 iattr
->state
= XML_SCHEMAS_ATTR_ERR_NO_TYPE
;
25712 ACTIVATE_ATTRIBUTE(iattr
);
25716 if (vctxt
->xpathStates
!= NULL
) {
25720 xpathRes
= xmlSchemaXPathEvaluate(vctxt
,
25721 XML_ATTRIBUTE_NODE
);
25722 if (xpathRes
== -1) {
25723 VERROR_INT("xmlSchemaVAttributesComplex",
25724 "calling xmlSchemaXPathEvaluate()");
25725 goto internal_error
;
25729 if (iattr
->state
== XML_SCHEMAS_ATTR_DEFAULT
) {
25731 * Default/fixed attributes.
25732 * We need the value only if we need to resolve IDCs or
25733 * will create default attributes.
25735 if ((xpathRes
) || (defAttrOwnerElem
)) {
25736 if (iattr
->use
->defValue
!= NULL
) {
25737 iattr
->value
= (xmlChar
*) iattr
->use
->defValue
;
25738 iattr
->val
= iattr
->use
->defVal
;
25740 iattr
->value
= (xmlChar
*) iattr
->decl
->defValue
;
25741 iattr
->val
= iattr
->decl
->defVal
;
25744 * IDCs will consume the precomputed default value,
25745 * so we need to clone it.
25747 if (iattr
->val
== NULL
) {
25748 VERROR_INT("xmlSchemaVAttributesComplex",
25749 "default/fixed value on an attribute use was "
25750 "not precomputed");
25751 goto internal_error
;
25753 iattr
->val
= xmlSchemaCopyValue(iattr
->val
);
25754 if (iattr
->val
== NULL
) {
25755 VERROR_INT("xmlSchemaVAttributesComplex",
25756 "calling xmlSchemaCopyValue()");
25757 goto internal_error
;
25761 * PSVI: Add the default attribute to the current element.
25762 * VAL TODO: Should we use the *normalized* value? This currently
25763 * uses the *initial* value.
25766 if (defAttrOwnerElem
) {
25767 xmlChar
*normValue
;
25768 const xmlChar
*value
;
25770 value
= iattr
->value
;
25772 * Normalize the value.
25774 normValue
= xmlSchemaNormalizeValue(iattr
->typeDef
,
25776 if (normValue
!= NULL
)
25777 value
= BAD_CAST normValue
;
25779 if (iattr
->nsName
== NULL
) {
25780 if (xmlNewProp(defAttrOwnerElem
,
25781 iattr
->localName
, value
) == NULL
) {
25782 VERROR_INT("xmlSchemaVAttributesComplex",
25783 "calling xmlNewProp()");
25784 if (normValue
!= NULL
)
25785 xmlFree(normValue
);
25786 goto internal_error
;
25791 ns
= xmlSearchNsByHref(defAttrOwnerElem
->doc
,
25792 defAttrOwnerElem
, iattr
->nsName
);
25794 xmlChar prefix
[12];
25798 * Create a namespace declaration on the validation
25799 * root node if no namespace declaration is in scope.
25802 snprintf((char *) prefix
, 12, "p%d", counter
++);
25803 ns
= xmlSearchNs(defAttrOwnerElem
->doc
,
25804 defAttrOwnerElem
, BAD_CAST prefix
);
25805 if (counter
> 1000) {
25807 "xmlSchemaVAttributesComplex",
25808 "could not compute a ns prefix for a "
25809 "default/fixed attribute");
25810 if (normValue
!= NULL
)
25811 xmlFree(normValue
);
25812 goto internal_error
;
25814 } while (ns
!= NULL
);
25815 ns
= xmlNewNs(vctxt
->validationRoot
,
25816 iattr
->nsName
, BAD_CAST prefix
);
25820 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25821 * If we have QNames: do we need to ensure there's a
25822 * prefix defined for the QName?
25824 xmlNewNsProp(defAttrOwnerElem
, ns
, iattr
->localName
, value
);
25826 if (normValue
!= NULL
)
25827 xmlFree(normValue
);
25830 * Go directly to IDC evaluation.
25835 * Validate the value.
25837 if (vctxt
->value
!= NULL
) {
25839 * Free last computed value; just for safety reasons.
25841 xmlSchemaFreeValue(vctxt
->value
);
25842 vctxt
->value
= NULL
;
25845 * Note that the attribute *use* can be unavailable, if
25846 * the attribute was a wild attribute.
25848 if ((iattr
->decl
->flags
& XML_SCHEMAS_ATTR_FIXED
) ||
25849 ((iattr
->use
!= NULL
) &&
25850 (iattr
->use
->flags
& XML_SCHEMAS_ATTR_FIXED
)))
25855 * SPEC (cvc-attribute)
25856 * (3) "The item's `normalized value` must be locally `valid`
25857 * with respect to that {type definition} as per
25858 * String Valid ($3.14.4)."
25860 * VAL TODO: Do we already have the
25861 * "normalized attribute value" here?
25863 if (xpathRes
|| fixed
) {
25864 iattr
->flags
|= XML_SCHEMA_NODE_INFO_VALUE_NEEDED
;
25866 * Request a computed value.
25868 res
= xmlSchemaVCheckCVCSimpleType(
25870 iattr
->node
, iattr
->typeDef
, iattr
->value
, &(iattr
->val
),
25873 res
= xmlSchemaVCheckCVCSimpleType(
25875 iattr
->node
, iattr
->typeDef
, iattr
->value
, NULL
,
25881 VERROR_INT("xmlSchemaVAttributesComplex",
25882 "calling xmlSchemaStreamValidateSimpleTypeValue()");
25883 goto internal_error
;
25885 iattr
->state
= XML_SCHEMAS_ATTR_INVALID_VALUE
;
25887 * SPEC PSVI Assessment Outcome (Attribute)
25888 * [validity] = "invalid"
25895 * SPEC Attribute Locally Valid (Use) (cvc-au)
25896 * "For an attribute information item to be `valid`
25897 * with respect to an attribute use its *normalized*
25898 * value must match the *canonical* lexical
25899 * representation of the attribute use's {value
25900 * constraint}value, if it is present and fixed."
25902 * VAL TODO: The requirement for the *canonical* value
25903 * will be removed in XML Schema 1.1.
25906 * SPEC Attribute Locally Valid (cvc-attribute)
25907 * (4) "The item's *actual* value must match the *value* of
25908 * the {value constraint}, if it is present and fixed."
25910 if (iattr
->val
== NULL
) {
25911 /* VAL TODO: A value was not precomputed. */
25915 if ((iattr
->use
!= NULL
) &&
25916 (iattr
->use
->defValue
!= NULL
)) {
25917 if (iattr
->use
->defVal
== NULL
) {
25918 /* VAL TODO: A default value was not precomputed. */
25922 iattr
->vcValue
= iattr
->use
->defValue
;
25924 if (xmlSchemaCompareValuesWhtsp(attr->val,
25925 (xmlSchemaWhitespaceValueType) ws,
25927 (xmlSchemaWhitespaceValueType) ws) != 0) {
25929 if (! xmlSchemaAreValuesEqual(iattr
->val
, iattr
->use
->defVal
))
25930 iattr
->state
= XML_SCHEMAS_ATTR_ERR_FIXED_VALUE
;
25932 if (iattr
->decl
->defVal
== NULL
) {
25933 /* VAL TODO: A default value was not precomputed. */
25937 iattr
->vcValue
= iattr
->decl
->defValue
;
25939 if (xmlSchemaCompareValuesWhtsp(attr->val,
25940 (xmlSchemaWhitespaceValueType) ws,
25942 (xmlSchemaWhitespaceValueType) ws) != 0) {
25944 if (! xmlSchemaAreValuesEqual(iattr
->val
, iattr
->decl
->defVal
))
25945 iattr
->state
= XML_SCHEMAS_ATTR_ERR_FIXED_VALUE
;
25948 * [validity] = "valid"
25956 if (xmlSchemaXPathProcessHistory(vctxt
,
25957 vctxt
->depth
+1) == -1) {
25958 VERROR_INT("xmlSchemaVAttributesComplex",
25959 "calling xmlSchemaXPathEvaluate()");
25960 goto internal_error
;
25962 } else if (vctxt
->xpathStates
!= NULL
)
25963 xmlSchemaXPathPop(vctxt
);
25969 for (i
= 0; i
< vctxt
->nbAttrInfos
; i
++) {
25970 iattr
= vctxt
->attrInfos
[i
];
25971 if ((iattr
->state
== XML_SCHEMAS_ATTR_META
) ||
25972 (iattr
->state
== XML_SCHEMAS_ATTR_ASSESSED
) ||
25973 (iattr
->state
== XML_SCHEMAS_ATTR_WILD_SKIP
) ||
25974 (iattr
->state
== XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL
))
25976 ACTIVATE_ATTRIBUTE(iattr
);
25977 switch (iattr
->state
) {
25978 case XML_SCHEMAS_ATTR_ERR_MISSING
: {
25979 xmlChar
*str
= NULL
;
25981 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
25982 XML_SCHEMAV_CVC_COMPLEX_TYPE_4
, NULL
, NULL
,
25983 "The attribute '%s' is required but missing",
25984 xmlSchemaFormatQName(&str
,
25985 iattr
->decl
->targetNamespace
,
25986 iattr
->decl
->name
),
25991 case XML_SCHEMAS_ATTR_ERR_NO_TYPE
:
25992 VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2
, NULL
,
25993 "The type definition is absent");
25995 case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE
:
25996 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
25997 XML_SCHEMAV_CVC_AU
, NULL
, NULL
,
25998 "The value '%s' does not match the fixed "
25999 "value constraint '%s'",
26000 iattr
->value
, iattr
->vcValue
);
26002 case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL
:
26003 VERROR(XML_SCHEMAV_CVC_WILDCARD
, NULL
,
26004 "No matching global attribute declaration available, but "
26005 "demanded by the strict wildcard");
26007 case XML_SCHEMAS_ATTR_UNKNOWN
:
26008 if (iattr
->metaType
)
26011 * MAYBE VAL TODO: One might report different error messages
26012 * for the following errors.
26014 if (type
->attributeWildcard
== NULL
) {
26015 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt
,
26016 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1
, iattr
, NULL
);
26018 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt
,
26019 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2
, iattr
, NULL
);
26035 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt
,
26038 xmlSchemaWildcardPtr wild
= (xmlSchemaWildcardPtr
) vctxt
->inode
->decl
;
26040 * The namespace of the element was already identified to be
26041 * matching the wildcard.
26043 if ((skip
== NULL
) || (wild
== NULL
) ||
26044 (wild
->type
!= XML_SCHEMA_TYPE_ANY
)) {
26045 VERROR_INT("xmlSchemaValidateElemWildcard",
26050 if (wild
->processContents
== XML_SCHEMAS_ANY_SKIP
) {
26052 * URGENT VAL TODO: Either we need to position the stream to the
26053 * next sibling, or walk the whole subtree.
26059 xmlSchemaElementPtr decl
= NULL
;
26061 decl
= xmlSchemaGetElem(vctxt
->schema
,
26062 vctxt
->inode
->localName
, vctxt
->inode
->nsName
);
26063 if (decl
!= NULL
) {
26064 vctxt
->inode
->decl
= decl
;
26068 if (wild
->processContents
== XML_SCHEMAS_ANY_STRICT
) {
26069 /* VAL TODO: Change to proper error code. */
26070 VERROR(XML_SCHEMAV_CVC_ELT_1
, NULL
, /* WXS_BASIC_CAST wild */
26071 "No matching global element declaration available, but "
26072 "demanded by the strict wildcard");
26073 return (vctxt
->err
);
26075 if (vctxt
->nbAttrInfos
!= 0) {
26076 xmlSchemaAttrInfoPtr iattr
;
26078 * SPEC Validation Rule: Schema-Validity Assessment (Element)
26079 * (1.2.1.2.1) - (1.2.1.2.3 )
26081 * Use the xsi:type attribute for the type definition.
26083 iattr
= xmlSchemaGetMetaAttrInfo(vctxt
,
26084 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE
);
26085 if (iattr
!= NULL
) {
26086 if (xmlSchemaProcessXSIType(vctxt
, iattr
,
26087 &(vctxt
->inode
->typeDef
), NULL
) == -1) {
26088 VERROR_INT("xmlSchemaValidateElemWildcard",
26089 "calling xmlSchemaProcessXSIType() to "
26090 "process the attribute 'xsi:nil'");
26094 * Don't return an error on purpose.
26100 * SPEC Validation Rule: Schema-Validity Assessment (Element)
26102 * Fallback to "anyType".
26104 vctxt
->inode
->typeDef
=
26105 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE
);
26110 * xmlSchemaCheckCOSValidDefault:
26112 * This will be called if: not nilled, no content and a default/fixed
26113 * value is provided.
26117 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt
,
26118 const xmlChar
*value
,
26119 xmlSchemaValPtr
*val
)
26122 xmlSchemaNodeInfoPtr inode
= vctxt
->inode
;
26125 * cos-valid-default:
26126 * Schema Component Constraint: Element Default Valid (Immediate)
26127 * For a string to be a valid default with respect to a type
26128 * definition the appropriate case among the following must be true:
26130 if WXS_IS_COMPLEX(inode
->typeDef
) {
26134 * SPEC (2.1) "its {content type} must be a simple type definition
26136 * SPEC (2.2.2) "If the {content type} is mixed, then the {content
26137 * type}'s particle must be `emptiable` as defined by
26138 * Particle Emptiable ($3.9.6)."
26140 if ((! WXS_HAS_SIMPLE_CONTENT(inode
->typeDef
)) &&
26141 ((! WXS_HAS_MIXED_CONTENT(inode
->typeDef
)) ||
26142 (! WXS_EMPTIABLE(inode
->typeDef
)))) {
26143 ret
= XML_SCHEMAP_COS_VALID_DEFAULT_2_1
;
26144 /* NOTE that this covers (2.2.2) as well. */
26146 "For a string to be a valid default, the type definition "
26147 "must be a simple type or a complex type with simple content "
26148 "or mixed content and a particle emptiable");
26153 * 1 If the type definition is a simple type definition, then the string
26154 * must be `valid` with respect to that definition as defined by String
26159 * 2.2.1 If the {content type} is a simple type definition, then the
26160 * string must be `valid` with respect to that simple type definition
26161 * as defined by String Valid ($3.14.4).
26163 if (WXS_IS_SIMPLE(inode
->typeDef
)) {
26165 ret
= xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt
,
26166 NULL
, inode
->typeDef
, value
, val
, 1, 1, 0);
26168 } else if (WXS_HAS_SIMPLE_CONTENT(inode
->typeDef
)) {
26170 ret
= xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt
,
26171 NULL
, inode
->typeDef
->contentTypeDef
, value
, val
, 1, 1, 0);
26174 VERROR_INT("xmlSchemaCheckCOSValidDefault",
26175 "calling xmlSchemaVCheckCVCSimpleType()");
26181 xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED
,
26182 const xmlChar
* name ATTRIBUTE_UNUSED
,
26183 void *transdata
, void *inputdata
)
26185 xmlSchemaElementPtr item
= (xmlSchemaElementPtr
) transdata
;
26186 xmlSchemaNodeInfoPtr inode
= (xmlSchemaNodeInfoPtr
) inputdata
;
26187 inode
->decl
= item
;
26188 #ifdef DEBUG_CONTENT
26190 xmlChar
*str
= NULL
;
26192 if (item
->type
== XML_SCHEMA_TYPE_ELEMENT
) {
26193 xmlGenericError(xmlGenericErrorContext
,
26194 "AUTOMATON callback for '%s' [declaration]\n",
26195 xmlSchemaFormatQName(&str
,
26196 inode
->localName
, inode
->nsName
));
26198 xmlGenericError(xmlGenericErrorContext
,
26199 "AUTOMATON callback for '%s' [wildcard]\n",
26200 xmlSchemaFormatQName(&str
,
26201 inode
->localName
, inode
->nsName
));
26210 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt
)
26212 vctxt
->inode
= xmlSchemaGetFreshElemInfo(vctxt
);
26213 if (vctxt
->inode
== NULL
) {
26214 VERROR_INT("xmlSchemaValidatorPushElem",
26215 "calling xmlSchemaGetFreshElemInfo()");
26218 vctxt
->nbAttrInfos
= 0;
26223 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt
,
26224 xmlSchemaNodeInfoPtr inode
,
26225 xmlSchemaTypePtr type
,
26226 const xmlChar
*value
)
26228 if (inode
->flags
& XML_SCHEMA_NODE_INFO_VALUE_NEEDED
)
26229 return (xmlSchemaVCheckCVCSimpleType(
26230 ACTXT_CAST vctxt
, NULL
,
26231 type
, value
, &(inode
->val
), 1, 1, 0));
26233 return (xmlSchemaVCheckCVCSimpleType(
26234 ACTXT_CAST vctxt
, NULL
,
26235 type
, value
, NULL
, 1, 0, 0));
26241 * Process END of element.
26244 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt
)
26247 xmlSchemaNodeInfoPtr inode
= vctxt
->inode
;
26249 if (vctxt
->nbAttrInfos
!= 0)
26250 xmlSchemaClearAttrInfos(vctxt
);
26251 if (inode
->flags
& XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED
) {
26253 * This element was not expected;
26254 * we will not validate child elements of broken parents.
26255 * Skip validation of all content of the parent.
26257 vctxt
->skipDepth
= vctxt
->depth
-1;
26260 if ((inode
->typeDef
== NULL
) ||
26261 (inode
->flags
& XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE
)) {
26263 * 1. the type definition might be missing if the element was
26265 * 2. it might be abstract.
26270 * Check the content model.
26272 if ((inode
->typeDef
->contentType
== XML_SCHEMA_CONTENT_MIXED
) ||
26273 (inode
->typeDef
->contentType
== XML_SCHEMA_CONTENT_ELEMENTS
)) {
26276 * Workaround for "anyType".
26278 if (inode
->typeDef
->builtInType
== XML_SCHEMAS_ANYTYPE
)
26279 goto character_content
;
26281 if ((inode
->flags
& XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT
) == 0) {
26282 xmlChar
*values
[10];
26283 int terminal
, nbval
= 10, nbneg
;
26285 if (inode
->regexCtxt
== NULL
) {
26287 * Create the regex context.
26290 xmlRegNewExecCtxt(inode
->typeDef
->contModel
,
26291 xmlSchemaVContentModelCallback
, vctxt
);
26292 if (inode
->regexCtxt
== NULL
) {
26293 VERROR_INT("xmlSchemaValidatorPopElem",
26294 "failed to create a regex context");
26295 goto internal_error
;
26297 #ifdef DEBUG_AUTOMATA
26298 xmlGenericError(xmlGenericErrorContext
,
26299 "AUTOMATON create on '%s'\n", inode
->localName
);
26304 * Do not check further content if the node has been nilled
26306 if (INODE_NILLED(inode
)) {
26308 #ifdef DEBUG_AUTOMATA
26309 xmlGenericError(xmlGenericErrorContext
,
26310 "AUTOMATON succeeded on nilled '%s'\n",
26317 * Get hold of the still expected content, since a further
26318 * call to xmlRegExecPushString() will lose this information.
26320 xmlRegExecNextValues(inode
->regexCtxt
,
26321 &nbval
, &nbneg
, &values
[0], &terminal
);
26322 ret
= xmlRegExecPushString(inode
->regexCtxt
, NULL
, NULL
);
26323 if ((ret
<0) || ((ret
==0) && (!INODE_NILLED(inode
)))) {
26325 * Still missing something.
26329 XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT
;
26330 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt
,
26331 XML_SCHEMAV_ELEMENT_CONTENT
, NULL
, NULL
,
26332 "Missing child element(s)",
26333 nbval
, nbneg
, values
);
26334 #ifdef DEBUG_AUTOMATA
26335 xmlGenericError(xmlGenericErrorContext
,
26336 "AUTOMATON missing ERROR on '%s'\n",
26341 * Content model is satisfied.
26344 #ifdef DEBUG_AUTOMATA
26345 xmlGenericError(xmlGenericErrorContext
,
26346 "AUTOMATON succeeded on '%s'\n",
26356 if (inode
->typeDef
->contentType
== XML_SCHEMA_CONTENT_ELEMENTS
)
26361 if (vctxt
->value
!= NULL
) {
26362 xmlSchemaFreeValue(vctxt
->value
);
26363 vctxt
->value
= NULL
;
26366 * Check character content.
26368 if (inode
->decl
== NULL
) {
26370 * Speedup if no declaration exists.
26372 if (WXS_IS_SIMPLE(inode
->typeDef
)) {
26373 ret
= xmlSchemaVCheckINodeDataType(vctxt
,
26374 inode
, inode
->typeDef
, inode
->value
);
26375 } else if (WXS_HAS_SIMPLE_CONTENT(inode
->typeDef
)) {
26376 ret
= xmlSchemaVCheckINodeDataType(vctxt
,
26377 inode
, inode
->typeDef
->contentTypeDef
,
26381 VERROR_INT("xmlSchemaValidatorPopElem",
26382 "calling xmlSchemaVCheckCVCSimpleType()");
26383 goto internal_error
;
26388 * cvc-elt (3.3.4) : 5
26389 * The appropriate case among the following must be true:
26392 * cvc-elt (3.3.4) : 5.1
26393 * If the declaration has a {value constraint},
26394 * the item has neither element nor character [children] and
26395 * clause 3.2 has not applied, then all of the following must be true:
26397 if ((inode
->decl
->value
!= NULL
) &&
26398 (inode
->flags
& XML_SCHEMA_ELEM_INFO_EMPTY
) &&
26399 (! INODE_NILLED(inode
))) {
26401 * cvc-elt (3.3.4) : 5.1.1
26402 * If the `actual type definition` is a `local type definition`
26403 * then the canonical lexical representation of the {value constraint}
26404 * value must be a valid default for the `actual type definition` as
26405 * defined in Element Default Valid (Immediate) ($3.3.6).
26408 * NOTE: 'local' above means types acquired by xsi:type.
26409 * NOTE: Although the *canonical* value is stated, it is not
26410 * relevant if canonical or not. Additionally XML Schema 1.1
26411 * will removed this requirement as well.
26413 if (inode
->flags
& XML_SCHEMA_ELEM_INFO_LOCAL_TYPE
) {
26415 ret
= xmlSchemaCheckCOSValidDefault(vctxt
,
26416 inode
->decl
->value
, &(inode
->val
));
26419 VERROR_INT("xmlSchemaValidatorPopElem",
26420 "calling xmlSchemaCheckCOSValidDefault()");
26421 goto internal_error
;
26426 * Stop here, to avoid redundant validation of the value
26432 * cvc-elt (3.3.4) : 5.1.2
26433 * The element information item with the canonical lexical
26434 * representation of the {value constraint} value used as its
26435 * `normalized value` must be `valid` with respect to the
26436 * `actual type definition` as defined by Element Locally Valid (Type)
26439 if (WXS_IS_SIMPLE(inode
->typeDef
)) {
26440 ret
= xmlSchemaVCheckINodeDataType(vctxt
,
26441 inode
, inode
->typeDef
, inode
->decl
->value
);
26442 } else if (WXS_HAS_SIMPLE_CONTENT(inode
->typeDef
)) {
26443 ret
= xmlSchemaVCheckINodeDataType(vctxt
,
26444 inode
, inode
->typeDef
->contentTypeDef
,
26445 inode
->decl
->value
);
26449 VERROR_INT("xmlSchemaValidatorPopElem",
26450 "calling xmlSchemaVCheckCVCSimpleType()");
26451 goto internal_error
;
26458 * PSVI: Create a text node on the instance element.
26460 if ((vctxt
->options
& XML_SCHEMA_VAL_VC_I_CREATE
) &&
26461 (inode
->node
!= NULL
)) {
26462 xmlNodePtr textChild
;
26463 xmlChar
*normValue
;
26465 * VAL TODO: Normalize the value.
26467 normValue
= xmlSchemaNormalizeValue(inode
->typeDef
,
26468 inode
->decl
->value
);
26469 if (normValue
!= NULL
) {
26470 textChild
= xmlNewDocText(inode
->node
->doc
,
26471 BAD_CAST normValue
);
26472 xmlFree(normValue
);
26474 textChild
= xmlNewDocText(inode
->node
->doc
,
26475 inode
->decl
->value
);
26476 if (textChild
== NULL
) {
26477 VERROR_INT("xmlSchemaValidatorPopElem",
26478 "calling xmlNewDocText()");
26479 goto internal_error
;
26481 xmlAddChild(inode
->node
, textChild
);
26484 } else if (! INODE_NILLED(inode
)) {
26486 * 5.2.1 The element information item must be `valid` with respect
26487 * to the `actual type definition` as defined by Element Locally
26488 * Valid (Type) ($3.3.4).
26490 if (WXS_IS_SIMPLE(inode
->typeDef
)) {
26492 * SPEC (cvc-type) (3.1)
26493 * "If the type definition is a simple type definition, ..."
26494 * (3.1.3) "If clause 3.2 of Element Locally Valid
26495 * (Element) ($3.3.4) did not apply, then the `normalized value`
26496 * must be `valid` with respect to the type definition as defined
26497 * by String Valid ($3.14.4).
26499 ret
= xmlSchemaVCheckINodeDataType(vctxt
,
26500 inode
, inode
->typeDef
, inode
->value
);
26501 } else if (WXS_HAS_SIMPLE_CONTENT(inode
->typeDef
)) {
26503 * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26504 * definition, then the element information item must be
26505 * `valid` with respect to the type definition as per
26506 * Element Locally Valid (Complex Type) ($3.4.4);"
26508 * SPEC (cvc-complex-type) (2.2)
26509 * "If the {content type} is a simple type definition, ...
26510 * the `normalized value` of the element information item is
26511 * `valid` with respect to that simple type definition as
26512 * defined by String Valid ($3.14.4)."
26514 ret
= xmlSchemaVCheckINodeDataType(vctxt
,
26515 inode
, inode
->typeDef
->contentTypeDef
, inode
->value
);
26519 VERROR_INT("xmlSchemaValidatorPopElem",
26520 "calling xmlSchemaVCheckCVCSimpleType()");
26521 goto internal_error
;
26526 * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26527 * not applied, all of the following must be true:
26529 if ((inode
->decl
->value
!= NULL
) &&
26530 (inode
->decl
->flags
& XML_SCHEMAS_ELEM_FIXED
)) {
26533 * TODO: We will need a computed value, when comparison is
26534 * done on computed values.
26537 * 5.2.2.1 The element information item must have no element
26538 * information item [children].
26541 XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT
) {
26542 ret
= XML_SCHEMAV_CVC_ELT_5_2_2_1
;
26544 "The content must not contain element nodes since "
26545 "there is a fixed value constraint");
26549 * 5.2.2.2 The appropriate case among the following must
26552 if (WXS_HAS_MIXED_CONTENT(inode
->typeDef
)) {
26554 * 5.2.2.2.1 If the {content type} of the `actual type
26555 * definition` is mixed, then the *initial value* of the
26556 * item must match the canonical lexical representation
26557 * of the {value constraint} value.
26559 * ... the *initial value* of an element information
26560 * item is the string composed of, in order, the
26561 * [character code] of each character information item in
26562 * the [children] of that element information item.
26564 if (! xmlStrEqual(inode
->value
, inode
->decl
->value
)){
26566 * VAL TODO: Report invalid & expected values as well.
26567 * VAL TODO: Implement the canonical stuff.
26569 ret
= XML_SCHEMAV_CVC_ELT_5_2_2_2_1
;
26570 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
26572 "The initial value '%s' does not match the fixed "
26573 "value constraint '%s'",
26574 inode
->value
, inode
->decl
->value
);
26577 } else if (WXS_HAS_SIMPLE_CONTENT(inode
->typeDef
)) {
26579 * 5.2.2.2.2 If the {content type} of the `actual type
26580 * definition` is a simple type definition, then the
26581 * *actual value* of the item must match the canonical
26582 * lexical representation of the {value constraint} value.
26585 * VAL TODO: *actual value* is the normalized value, impl.
26587 * VAL TODO: Report invalid & expected values as well.
26588 * VAL TODO: Implement a comparison with the computed values.
26590 if (! xmlStrEqual(inode
->value
,
26591 inode
->decl
->value
)) {
26592 ret
= XML_SCHEMAV_CVC_ELT_5_2_2_2_2
;
26593 xmlSchemaCustomErr(ACTXT_CAST vctxt
,
26595 "The actual value '%s' does not match the fixed "
26596 "value constraint '%s'",
26598 inode
->decl
->value
);
26607 if (vctxt
->depth
< 0) {
26608 /* TODO: raise error? */
26611 if (vctxt
->depth
== vctxt
->skipDepth
)
26612 vctxt
->skipDepth
= -1;
26614 * Evaluate the history of XPath state objects.
26616 if (inode
->appliedXPath
&&
26617 (xmlSchemaXPathProcessHistory(vctxt
, vctxt
->depth
) == -1))
26618 goto internal_error
;
26621 * SPEC (6) "The element information item must be `valid` with
26622 * respect to each of the {identity-constraint definitions} as per
26623 * Identity-constraint Satisfied ($3.11.4)."
26626 * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26627 * need to be built in any case.
26628 * We will currently build IDC node-tables and bubble them only if
26629 * keyrefs do exist.
26633 * Add the current IDC target-nodes to the IDC node-tables.
26635 if ((inode
->idcMatchers
!= NULL
) &&
26636 (vctxt
->hasKeyrefs
|| vctxt
->createIDCNodeTables
))
26638 if (xmlSchemaIDCFillNodeTables(vctxt
, inode
) == -1)
26639 goto internal_error
;
26642 * Validate IDC keyrefs.
26644 if (vctxt
->inode
->hasKeyrefs
)
26645 if (xmlSchemaCheckCVCIDCKeyRef(vctxt
) == -1)
26646 goto internal_error
;
26648 * Merge/free the IDC table.
26650 if (inode
->idcTable
!= NULL
) {
26651 #ifdef DEBUG_IDC_NODE_TABLE
26652 xmlSchemaDebugDumpIDCTable(stdout
,
26657 if ((vctxt
->depth
> 0) &&
26658 (vctxt
->hasKeyrefs
|| vctxt
->createIDCNodeTables
))
26661 * Merge the IDC node table with the table of the parent node.
26663 if (xmlSchemaBubbleIDCNodeTables(vctxt
) == -1)
26664 goto internal_error
;
26668 * Clear the current ielem.
26669 * VAL TODO: Don't free the PSVI IDC tables if they are
26670 * requested for the PSVI.
26672 xmlSchemaClearElemInfo(vctxt
, inode
);
26674 * Skip further processing if we are on the validation root.
26676 if (vctxt
->depth
== 0) {
26678 vctxt
->inode
= NULL
;
26682 * Reset the keyrefDepth if needed.
26684 if (vctxt
->aidcs
!= NULL
) {
26685 xmlSchemaIDCAugPtr aidc
= vctxt
->aidcs
;
26687 if (aidc
->keyrefDepth
== vctxt
->depth
) {
26689 * A 'keyrefDepth' of a key/unique IDC matches the current
26690 * depth, this means that we are leaving the scope of the
26691 * top-most keyref IDC which refers to this IDC.
26693 aidc
->keyrefDepth
= -1;
26696 } while (aidc
!= NULL
);
26699 vctxt
->inode
= vctxt
->elemInfos
[vctxt
->depth
];
26701 * VAL TODO: 7 If the element information item is the `validation root`, it must be
26702 * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
26712 * 3.4.4 Complex Type Definition Validation Rules
26713 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26716 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt
)
26718 xmlSchemaNodeInfoPtr pielem
;
26719 xmlSchemaTypePtr ptype
;
26722 if (vctxt
->depth
<= 0) {
26723 VERROR_INT("xmlSchemaValidateChildElem",
26724 "not intended for the validation root");
26727 pielem
= vctxt
->elemInfos
[vctxt
->depth
-1];
26728 if (pielem
->flags
& XML_SCHEMA_ELEM_INFO_EMPTY
)
26729 pielem
->flags
^= XML_SCHEMA_ELEM_INFO_EMPTY
;
26731 * Handle 'nilled' elements.
26733 if (INODE_NILLED(pielem
)) {
26735 * SPEC (cvc-elt) (3.3.4) : (3.2.1)
26737 ACTIVATE_PARENT_ELEM
;
26738 ret
= XML_SCHEMAV_CVC_ELT_3_2_1
;
26740 "Neither character nor element content is allowed, "
26741 "because the element was 'nilled'");
26743 goto unexpected_elem
;
26746 ptype
= pielem
->typeDef
;
26748 if (ptype
->builtInType
== XML_SCHEMAS_ANYTYPE
) {
26750 * Workaround for "anyType": we have currently no content model
26751 * assigned for "anyType", so handle it explicitly.
26752 * "anyType" has an unbounded, lax "any" wildcard.
26754 vctxt
->inode
->decl
= xmlSchemaGetElem(vctxt
->schema
,
26755 vctxt
->inode
->localName
,
26756 vctxt
->inode
->nsName
);
26758 if (vctxt
->inode
->decl
== NULL
) {
26759 xmlSchemaAttrInfoPtr iattr
;
26761 * Process "xsi:type".
26762 * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26764 iattr
= xmlSchemaGetMetaAttrInfo(vctxt
,
26765 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE
);
26766 if (iattr
!= NULL
) {
26767 ret
= xmlSchemaProcessXSIType(vctxt
, iattr
,
26768 &(vctxt
->inode
->typeDef
), NULL
);
26771 VERROR_INT("xmlSchemaValidateChildElem",
26772 "calling xmlSchemaProcessXSIType() to "
26773 "process the attribute 'xsi:nil'");
26780 * Fallback to "anyType".
26782 * SPEC (cvc-assess-elt)
26783 * "If the item cannot be `strictly assessed`, [...]
26784 * an element information item's schema validity may be laxly
26785 * assessed if its `context-determined declaration` is not
26786 * skip by `validating` with respect to the `ur-type
26787 * definition` as per Element Locally Valid (Type) ($3.3.4)."
26789 vctxt
->inode
->typeDef
=
26790 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE
);
26796 switch (ptype
->contentType
) {
26797 case XML_SCHEMA_CONTENT_EMPTY
:
26799 * SPEC (2.1) "If the {content type} is empty, then the
26800 * element information item has no character or element
26801 * information item [children]."
26803 ACTIVATE_PARENT_ELEM
26804 ret
= XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1
;
26806 "Element content is not allowed, "
26807 "because the content type is empty");
26809 goto unexpected_elem
;
26812 case XML_SCHEMA_CONTENT_MIXED
:
26813 case XML_SCHEMA_CONTENT_ELEMENTS
: {
26814 xmlRegExecCtxtPtr regexCtxt
;
26815 xmlChar
*values
[10];
26816 int terminal
, nbval
= 10, nbneg
;
26818 /* VAL TODO: Optimized "anyType" validation.*/
26820 if (ptype
->contModel
== NULL
) {
26821 VERROR_INT("xmlSchemaValidateChildElem",
26822 "type has elem content but no content model");
26826 * Safety belt for evaluation if the cont. model was already
26827 * examined to be invalid.
26829 if (pielem
->flags
& XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT
) {
26830 VERROR_INT("xmlSchemaValidateChildElem",
26831 "validating elem, but elem content is already invalid");
26835 regexCtxt
= pielem
->regexCtxt
;
26836 if (regexCtxt
== NULL
) {
26838 * Create the regex context.
26840 regexCtxt
= xmlRegNewExecCtxt(ptype
->contModel
,
26841 xmlSchemaVContentModelCallback
, vctxt
);
26842 if (regexCtxt
== NULL
) {
26843 VERROR_INT("xmlSchemaValidateChildElem",
26844 "failed to create a regex context");
26847 pielem
->regexCtxt
= regexCtxt
;
26848 #ifdef DEBUG_AUTOMATA
26849 xmlGenericError(xmlGenericErrorContext
, "AUTOMATA create on '%s'\n",
26850 pielem
->localName
);
26855 * SPEC (2.4) "If the {content type} is element-only or mixed,
26856 * then the sequence of the element information item's
26857 * element information item [children], if any, taken in
26858 * order, is `valid` with respect to the {content type}'s
26859 * particle, as defined in Element Sequence Locally Valid
26860 * (Particle) ($3.9.4)."
26862 ret
= xmlRegExecPushString2(regexCtxt
,
26863 vctxt
->inode
->localName
,
26864 vctxt
->inode
->nsName
,
26866 #ifdef DEBUG_AUTOMATA
26868 xmlGenericError(xmlGenericErrorContext
,
26869 "AUTOMATON push ERROR for '%s' on '%s'\n",
26870 vctxt
->inode
->localName
, pielem
->localName
);
26872 xmlGenericError(xmlGenericErrorContext
,
26873 "AUTOMATON push OK for '%s' on '%s'\n",
26874 vctxt
->inode
->localName
, pielem
->localName
);
26876 if (vctxt
->err
== XML_SCHEMAV_INTERNAL
) {
26877 VERROR_INT("xmlSchemaValidateChildElem",
26878 "calling xmlRegExecPushString2()");
26882 xmlRegExecErrInfo(regexCtxt
, NULL
, &nbval
, &nbneg
,
26883 &values
[0], &terminal
);
26884 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt
,
26885 XML_SCHEMAV_ELEMENT_CONTENT
, NULL
,NULL
,
26886 "This element is not expected",
26887 nbval
, nbneg
, values
);
26889 goto unexpected_elem
;
26894 case XML_SCHEMA_CONTENT_SIMPLE
:
26895 case XML_SCHEMA_CONTENT_BASIC
:
26896 ACTIVATE_PARENT_ELEM
26897 if (WXS_IS_COMPLEX(ptype
)) {
26899 * SPEC (cvc-complex-type) (2.2)
26900 * "If the {content type} is a simple type definition, then
26901 * the element information item has no element information
26902 * item [children], ..."
26904 ret
= XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2
;
26905 VERROR(ret
, NULL
, "Element content is not allowed, "
26906 "because the content type is a simple type definition");
26909 * SPEC (cvc-type) (3.1.2) "The element information item must
26910 * have no element information item [children]."
26912 ret
= XML_SCHEMAV_CVC_TYPE_3_1_2
;
26913 VERROR(ret
, NULL
, "Element content is not allowed, "
26914 "because the type definition is simple");
26918 goto unexpected_elem
;
26927 * Pop this element and set the skipDepth to skip
26928 * all further content of the parent element.
26930 vctxt
->skipDepth
= vctxt
->depth
;
26931 vctxt
->inode
->flags
|= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED
;
26932 pielem
->flags
|= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT
;
26936 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26937 #define XML_SCHEMA_PUSH_TEXT_CREATED 2
26938 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26941 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt
,
26942 int nodeType
, const xmlChar
*value
, int len
,
26943 int mode
, int *consumed
)
26946 * Unfortunately we have to duplicate the text sometimes.
26947 * OPTIMIZE: Maybe we could skip it, if:
26948 * 1. content type is simple
26949 * 2. whitespace is "collapse"
26950 * 3. it consists of whitespace only
26952 * Process character content.
26954 if (consumed
!= NULL
)
26956 if (INODE_NILLED(vctxt
->inode
)) {
26958 * SPEC cvc-elt (3.3.4 - 3.2.1)
26959 * "The element information item must have no character or
26960 * element information item [children]."
26962 VERROR(XML_SCHEMAV_CVC_ELT_3_2_1
, NULL
,
26963 "Neither character nor element content is allowed "
26964 "because the element is 'nilled'");
26965 return (vctxt
->err
);
26968 * SPEC (2.1) "If the {content type} is empty, then the
26969 * element information item has no character or element
26970 * information item [children]."
26972 if (vctxt
->inode
->typeDef
->contentType
==
26973 XML_SCHEMA_CONTENT_EMPTY
) {
26974 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1
, NULL
,
26975 "Character content is not allowed, "
26976 "because the content type is empty");
26977 return (vctxt
->err
);
26980 if (vctxt
->inode
->typeDef
->contentType
==
26981 XML_SCHEMA_CONTENT_ELEMENTS
) {
26982 if ((nodeType
!= XML_TEXT_NODE
) ||
26983 (! xmlSchemaIsBlank((xmlChar
*) value
, len
))) {
26985 * SPEC cvc-complex-type (2.3)
26986 * "If the {content type} is element-only, then the
26987 * element information item has no character information
26988 * item [children] other than those whose [character
26989 * code] is defined as a white space in [XML 1.0 (Second
26992 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3
, NULL
,
26993 "Character content other than whitespace is not allowed "
26994 "because the content type is 'element-only'");
26995 return (vctxt
->err
);
27000 if ((value
== NULL
) || (value
[0] == 0))
27004 * NOTE that even if the content type is *mixed*, we need the
27005 * *initial value* for default/fixed value constraints.
27007 if ((vctxt
->inode
->typeDef
->contentType
== XML_SCHEMA_CONTENT_MIXED
) &&
27008 ((vctxt
->inode
->decl
== NULL
) ||
27009 (vctxt
->inode
->decl
->value
== NULL
)))
27012 if (vctxt
->inode
->value
== NULL
) {
27017 case XML_SCHEMA_PUSH_TEXT_PERSIST
:
27019 * When working on a tree.
27021 vctxt
->inode
->value
= value
;
27023 case XML_SCHEMA_PUSH_TEXT_CREATED
:
27025 * When working with the reader.
27026 * The value will be freed by the element info.
27028 vctxt
->inode
->value
= value
;
27029 if (consumed
!= NULL
)
27031 vctxt
->inode
->flags
|=
27032 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
;
27034 case XML_SCHEMA_PUSH_TEXT_VOLATILE
:
27036 * When working with SAX.
27037 * The value will be freed by the element info.
27040 vctxt
->inode
->value
= BAD_CAST
xmlStrndup(value
, len
);
27042 vctxt
->inode
->value
= BAD_CAST
xmlStrdup(value
);
27043 vctxt
->inode
->flags
|=
27044 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
;
27051 len
= xmlStrlen(value
);
27053 * Concat the value.
27055 if (vctxt
->inode
->flags
& XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
) {
27056 vctxt
->inode
->value
= BAD_CAST
xmlStrncat(
27057 (xmlChar
*) vctxt
->inode
->value
, value
, len
);
27059 vctxt
->inode
->value
=
27060 BAD_CAST
xmlStrncatNew(vctxt
->inode
->value
, value
, len
);
27061 vctxt
->inode
->flags
|= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES
;
27069 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt
)
27073 if ((vctxt
->skipDepth
!= -1) &&
27074 (vctxt
->depth
>= vctxt
->skipDepth
)) {
27075 VERROR_INT("xmlSchemaValidateElem",
27077 goto internal_error
;
27079 if (vctxt
->xsiAssemble
) {
27081 * We will stop validation if there was an error during
27082 * dynamic schema construction.
27083 * Note that we simply set @skipDepth to 0, this could
27084 * mean that a streaming document via SAX would be
27085 * still read to the end but it won't be validated any more.
27086 * TODO: If we are sure how to stop the validation at once
27087 * for all input scenarios, then this should be changed to
27088 * instantly stop the validation.
27090 ret
= xmlSchemaAssembleByXSI(vctxt
);
27093 goto internal_error
;
27094 vctxt
->skipDepth
= 0;
27098 * Augment the IDC definitions for the main schema and all imported ones
27099 * NOTE: main schema is the first in the imported list
27101 xmlHashScan(vctxt
->schema
->schemasImports
, xmlSchemaAugmentImportedIDC
,
27104 if (vctxt
->depth
> 0) {
27106 * Validate this element against the content model
27109 ret
= xmlSchemaValidateChildElem(vctxt
);
27112 VERROR_INT("xmlSchemaValidateElem",
27113 "calling xmlSchemaStreamValidateChildElement()");
27114 goto internal_error
;
27118 if (vctxt
->depth
== vctxt
->skipDepth
)
27120 if ((vctxt
->inode
->decl
== NULL
) &&
27121 (vctxt
->inode
->typeDef
== NULL
)) {
27122 VERROR_INT("xmlSchemaValidateElem",
27123 "the child element was valid but neither the "
27124 "declaration nor the type was set");
27125 goto internal_error
;
27129 * Get the declaration of the validation root.
27131 vctxt
->inode
->decl
= xmlSchemaGetElem(vctxt
->schema
,
27132 vctxt
->inode
->localName
,
27133 vctxt
->inode
->nsName
);
27134 if (vctxt
->inode
->decl
== NULL
) {
27135 ret
= XML_SCHEMAV_CVC_ELT_1
;
27137 "No matching global declaration available "
27138 "for the validation root");
27143 if (vctxt
->inode
->decl
== NULL
)
27144 goto type_validation
;
27146 if (vctxt
->inode
->decl
->type
== XML_SCHEMA_TYPE_ANY
) {
27151 ret
= xmlSchemaValidateElemWildcard(vctxt
, &skip
);
27154 VERROR_INT("xmlSchemaValidateElem",
27155 "calling xmlSchemaValidateElemWildcard()");
27156 goto internal_error
;
27161 vctxt
->skipDepth
= vctxt
->depth
;
27165 * The declaration might be set by the wildcard validation,
27166 * when the processContents is "lax" or "strict".
27168 if (vctxt
->inode
->decl
->type
!= XML_SCHEMA_TYPE_ELEMENT
) {
27170 * Clear the "decl" field to not confuse further processing.
27172 vctxt
->inode
->decl
= NULL
;
27173 goto type_validation
;
27177 * Validate against the declaration.
27179 ret
= xmlSchemaValidateElemDecl(vctxt
);
27182 VERROR_INT("xmlSchemaValidateElem",
27183 "calling xmlSchemaValidateElemDecl()");
27184 goto internal_error
;
27189 * Validate against the type definition.
27193 if (vctxt
->inode
->typeDef
== NULL
) {
27194 vctxt
->inode
->flags
|= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE
;
27195 ret
= XML_SCHEMAV_CVC_TYPE_1
;
27197 "The type definition is absent");
27200 if (vctxt
->inode
->typeDef
->flags
& XML_SCHEMAS_TYPE_ABSTRACT
) {
27201 vctxt
->inode
->flags
|= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE
;
27202 ret
= XML_SCHEMAV_CVC_TYPE_2
;
27204 "The type definition is abstract");
27208 * Evaluate IDCs. Do it here, since new IDC matchers are registered
27209 * during validation against the declaration. This must be done
27210 * _before_ attribute validation.
27212 if (vctxt
->xpathStates
!= NULL
) {
27213 ret
= xmlSchemaXPathEvaluate(vctxt
, XML_ELEMENT_NODE
);
27214 vctxt
->inode
->appliedXPath
= 1;
27216 VERROR_INT("xmlSchemaValidateElem",
27217 "calling xmlSchemaXPathEvaluate()");
27218 goto internal_error
;
27222 * Validate attributes.
27224 if (WXS_IS_COMPLEX(vctxt
->inode
->typeDef
)) {
27225 if ((vctxt
->nbAttrInfos
!= 0) ||
27226 (vctxt
->inode
->typeDef
->attrUses
!= NULL
)) {
27228 ret
= xmlSchemaVAttributesComplex(vctxt
);
27230 } else if (vctxt
->nbAttrInfos
!= 0) {
27232 ret
= xmlSchemaVAttributesSimple(vctxt
);
27235 * Clear registered attributes.
27237 if (vctxt
->nbAttrInfos
!= 0)
27238 xmlSchemaClearAttrInfos(vctxt
);
27240 VERROR_INT("xmlSchemaValidateElem",
27241 "calling attributes validation");
27242 goto internal_error
;
27245 * Don't return an error if attributes are invalid on purpose.
27251 vctxt
->skipDepth
= vctxt
->depth
;
27257 #ifdef XML_SCHEMA_READER_ENABLED
27259 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt
)
27261 const int WHTSP
= 13, SIGN_WHTSP
= 14, END_ELEM
= 15;
27262 int depth
, nodeType
, ret
= 0, consumed
;
27263 xmlSchemaNodeInfoPtr ielem
;
27266 ret
= xmlTextReaderRead(vctxt
->reader
);
27268 * Move to the document element.
27271 nodeType
= xmlTextReaderNodeType(vctxt
->reader
);
27272 if (nodeType
== XML_ELEMENT_NODE
)
27274 ret
= xmlTextReaderRead(vctxt
->reader
);
27281 depth
= xmlTextReaderDepth(vctxt
->reader
);
27282 nodeType
= xmlTextReaderNodeType(vctxt
->reader
);
27284 if (nodeType
== XML_ELEMENT_NODE
) {
27287 if (xmlSchemaValidatorPushElem(vctxt
) == -1) {
27288 VERROR_INT("xmlSchemaVReaderWalk",
27289 "calling xmlSchemaValidatorPushElem()");
27290 goto internal_error
;
27292 ielem
= vctxt
->inode
;
27293 ielem
->localName
= xmlTextReaderLocalName(vctxt
->reader
);
27294 ielem
->nsName
= xmlTextReaderNamespaceUri(vctxt
->reader
);
27295 ielem
->flags
|= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES
;
27297 * Is the element empty?
27299 ret
= xmlTextReaderIsEmptyElement(vctxt
->reader
);
27301 VERROR_INT("xmlSchemaVReaderWalk",
27302 "calling xmlTextReaderIsEmptyElement()");
27303 goto internal_error
;
27306 ielem
->flags
|= XML_SCHEMA_ELEM_INFO_EMPTY
;
27309 * Register attributes.
27311 vctxt
->nbAttrInfos
= 0;
27312 ret
= xmlTextReaderMoveToFirstAttribute(vctxt
->reader
);
27314 VERROR_INT("xmlSchemaVReaderWalk",
27315 "calling xmlTextReaderMoveToFirstAttribute()");
27316 goto internal_error
;
27321 * VAL TODO: How do we know that the reader works on a
27322 * node tree, to be able to pass a node here?
27324 if (xmlSchemaValidatorPushAttribute(vctxt
, NULL
,
27325 (const xmlChar
*) xmlTextReaderLocalName(vctxt
->reader
),
27326 xmlTextReaderNamespaceUri(vctxt
->reader
), 1,
27327 xmlTextReaderValue(vctxt
->reader
), 1) == -1) {
27329 VERROR_INT("xmlSchemaVReaderWalk",
27330 "calling xmlSchemaValidatorPushAttribute()");
27331 goto internal_error
;
27333 ret
= xmlTextReaderMoveToNextAttribute(vctxt
->reader
);
27335 VERROR_INT("xmlSchemaVReaderWalk",
27336 "calling xmlTextReaderMoveToFirstAttribute()");
27337 goto internal_error
;
27339 } while (ret
== 1);
27341 * Back to element position.
27343 ret
= xmlTextReaderMoveToElement(vctxt
->reader
);
27345 VERROR_INT("xmlSchemaVReaderWalk",
27346 "calling xmlTextReaderMoveToElement()");
27347 goto internal_error
;
27351 * Validate the element.
27353 ret
= xmlSchemaValidateElem(vctxt
);
27356 VERROR_INT("xmlSchemaVReaderWalk",
27357 "calling xmlSchemaValidateElem()");
27358 goto internal_error
;
27362 if (vctxt
->depth
== vctxt
->skipDepth
) {
27365 * Skip all content.
27367 if ((ielem
->flags
& XML_SCHEMA_ELEM_INFO_EMPTY
) == 0) {
27368 ret
= xmlTextReaderRead(vctxt
->reader
);
27369 curDepth
= xmlTextReaderDepth(vctxt
->reader
);
27370 while ((ret
== 1) && (curDepth
!= depth
)) {
27371 ret
= xmlTextReaderRead(vctxt
->reader
);
27372 curDepth
= xmlTextReaderDepth(vctxt
->reader
);
27376 * VAL TODO: A reader error occurred; what to do here?
27385 * READER VAL TODO: Is an END_ELEM really never called
27386 * if the elem is empty?
27388 if (ielem
->flags
& XML_SCHEMA_ELEM_INFO_EMPTY
)
27390 } else if (nodeType
== END_ELEM
) {
27392 * Process END of element.
27395 ret
= xmlSchemaValidatorPopElem(vctxt
);
27398 VERROR_INT("xmlSchemaVReaderWalk",
27399 "calling xmlSchemaValidatorPopElem()");
27400 goto internal_error
;
27404 if (vctxt
->depth
>= 0)
27405 ielem
= vctxt
->inode
;
27408 } else if ((nodeType
== XML_TEXT_NODE
) ||
27409 (nodeType
== XML_CDATA_SECTION_NODE
) ||
27410 (nodeType
== WHTSP
) ||
27411 (nodeType
== SIGN_WHTSP
)) {
27413 * Process character content.
27417 if ((nodeType
== WHTSP
) || (nodeType
== SIGN_WHTSP
))
27418 nodeType
= XML_TEXT_NODE
;
27420 value
= xmlTextReaderValue(vctxt
->reader
);
27421 ret
= xmlSchemaVPushText(vctxt
, nodeType
, BAD_CAST value
,
27422 -1, XML_SCHEMA_PUSH_TEXT_CREATED
, &consumed
);
27426 VERROR_INT("xmlSchemaVReaderWalk",
27427 "calling xmlSchemaVPushText()");
27428 goto internal_error
;
27430 } else if ((nodeType
== XML_ENTITY_NODE
) ||
27431 (nodeType
== XML_ENTITY_REF_NODE
)) {
27433 * VAL TODO: What to do with entities?
27440 ret
= xmlTextReaderRead(vctxt
->reader
);
27441 } while (ret
== 1);
27450 /************************************************************************
27452 * SAX validation handlers *
27454 ************************************************************************/
27457 * Process text content.
27460 xmlSchemaSAXHandleText(void *ctx
,
27461 const xmlChar
* ch
,
27464 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) ctx
;
27466 if (vctxt
->depth
< 0)
27468 if ((vctxt
->skipDepth
!= -1) && (vctxt
->depth
>= vctxt
->skipDepth
))
27470 if (vctxt
->inode
->flags
& XML_SCHEMA_ELEM_INFO_EMPTY
)
27471 vctxt
->inode
->flags
^= XML_SCHEMA_ELEM_INFO_EMPTY
;
27472 if (xmlSchemaVPushText(vctxt
, XML_TEXT_NODE
, ch
, len
,
27473 XML_SCHEMA_PUSH_TEXT_VOLATILE
, NULL
) == -1) {
27474 VERROR_INT("xmlSchemaSAXHandleCDataSection",
27475 "calling xmlSchemaVPushText()");
27477 xmlStopParser(vctxt
->parserCtxt
);
27482 * Process CDATA content.
27485 xmlSchemaSAXHandleCDataSection(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_CDATA_SECTION_NODE
, ch
, len
,
27498 XML_SCHEMA_PUSH_TEXT_VOLATILE
, NULL
) == -1) {
27499 VERROR_INT("xmlSchemaSAXHandleCDataSection",
27500 "calling xmlSchemaVPushText()");
27502 xmlStopParser(vctxt
->parserCtxt
);
27507 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED
,
27508 const xmlChar
* name ATTRIBUTE_UNUSED
)
27510 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) ctx
;
27512 if (vctxt
->depth
< 0)
27514 if ((vctxt
->skipDepth
!= -1) && (vctxt
->depth
>= vctxt
->skipDepth
))
27516 /* SAX VAL TODO: What to do here? */
27521 xmlSchemaSAXHandleStartElementNs(void *ctx
,
27522 const xmlChar
* localname
,
27523 const xmlChar
* prefix ATTRIBUTE_UNUSED
,
27524 const xmlChar
* URI
,
27526 const xmlChar
** namespaces
,
27528 int nb_defaulted ATTRIBUTE_UNUSED
,
27529 const xmlChar
** attributes
)
27531 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) ctx
;
27533 xmlSchemaNodeInfoPtr ielem
;
27537 * SAX VAL TODO: What to do with nb_defaulted?
27540 * Skip elements if inside a "skip" wildcard or invalid.
27543 if ((vctxt
->skipDepth
!= -1) && (vctxt
->depth
>= vctxt
->skipDepth
))
27546 * Push the element.
27548 if (xmlSchemaValidatorPushElem(vctxt
) == -1) {
27549 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27550 "calling xmlSchemaValidatorPushElem()");
27551 goto internal_error
;
27553 ielem
= vctxt
->inode
;
27555 * TODO: Is this OK?
27557 ielem
->nodeLine
= xmlSAX2GetLineNumber(vctxt
->parserCtxt
);
27558 ielem
->localName
= localname
;
27559 ielem
->nsName
= URI
;
27560 ielem
->flags
|= XML_SCHEMA_ELEM_INFO_EMPTY
;
27562 * Register namespaces on the elem info.
27564 if (nb_namespaces
!= 0) {
27566 * Although the parser builds its own namespace list,
27567 * we have no access to it, so we'll use an own one.
27569 for (i
= 0, j
= 0; i
< nb_namespaces
; i
++, j
+= 2) {
27571 * Store prefix and namespace name.
27573 if (ielem
->nsBindings
== NULL
) {
27574 ielem
->nsBindings
=
27575 (const xmlChar
**) xmlMalloc(10 *
27576 sizeof(const xmlChar
*));
27577 if (ielem
->nsBindings
== NULL
) {
27578 xmlSchemaVErrMemory(vctxt
,
27579 "allocating namespace bindings for SAX validation",
27581 goto internal_error
;
27583 ielem
->nbNsBindings
= 0;
27584 ielem
->sizeNsBindings
= 5;
27585 } else if (ielem
->sizeNsBindings
<= ielem
->nbNsBindings
) {
27586 ielem
->sizeNsBindings
*= 2;
27587 ielem
->nsBindings
=
27588 (const xmlChar
**) xmlRealloc(
27589 (void *) ielem
->nsBindings
,
27590 ielem
->sizeNsBindings
* 2 * sizeof(const xmlChar
*));
27591 if (ielem
->nsBindings
== NULL
) {
27592 xmlSchemaVErrMemory(vctxt
,
27593 "re-allocating namespace bindings for SAX validation",
27595 goto internal_error
;
27599 ielem
->nsBindings
[ielem
->nbNsBindings
* 2] = namespaces
[j
];
27600 if (namespaces
[j
+1][0] == 0) {
27604 ielem
->nsBindings
[ielem
->nbNsBindings
* 2 + 1] = NULL
;
27606 ielem
->nsBindings
[ielem
->nbNsBindings
* 2 + 1] =
27608 ielem
->nbNsBindings
++;
27612 * Register attributes.
27613 * SAX VAL TODO: We are not adding namespace declaration
27616 if (nb_attributes
!= 0) {
27617 int valueLen
, k
, l
;
27620 for (j
= 0, i
= 0; i
< nb_attributes
; i
++, j
+= 5) {
27622 * Duplicate the value, changing any & to a literal ampersand.
27624 * libxml2 differs from normal SAX here in that it escapes all ampersands
27625 * as & instead of delivering the raw converted string. Changing the
27626 * behavior at this point would break applications that use this API, so
27627 * we are forced to work around it.
27629 valueLen
= attributes
[j
+4] - attributes
[j
+3];
27630 value
= xmlMallocAtomic(valueLen
+ 1);
27631 if (value
== NULL
) {
27632 xmlSchemaVErrMemory(vctxt
,
27633 "allocating string for decoded attribute",
27635 goto internal_error
;
27637 for (k
= 0, l
= 0; k
< valueLen
; l
++) {
27638 if (k
< valueLen
- 4 &&
27639 attributes
[j
+3][k
+0] == '&' &&
27640 attributes
[j
+3][k
+1] == '#' &&
27641 attributes
[j
+3][k
+2] == '3' &&
27642 attributes
[j
+3][k
+3] == '8' &&
27643 attributes
[j
+3][k
+4] == ';') {
27647 value
[l
] = attributes
[j
+3][k
];
27653 * TODO: Set the node line.
27655 ret
= xmlSchemaValidatorPushAttribute(vctxt
,
27656 NULL
, ielem
->nodeLine
, attributes
[j
], attributes
[j
+2], 0,
27659 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27660 "calling xmlSchemaValidatorPushAttribute()");
27661 goto internal_error
;
27666 * Validate the element.
27668 ret
= xmlSchemaValidateElem(vctxt
);
27671 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27672 "calling xmlSchemaValidateElem()");
27673 goto internal_error
;
27682 xmlStopParser(vctxt
->parserCtxt
);
27687 xmlSchemaSAXHandleEndElementNs(void *ctx
,
27688 const xmlChar
* localname ATTRIBUTE_UNUSED
,
27689 const xmlChar
* prefix ATTRIBUTE_UNUSED
,
27690 const xmlChar
* URI ATTRIBUTE_UNUSED
)
27692 xmlSchemaValidCtxtPtr vctxt
= (xmlSchemaValidCtxtPtr
) ctx
;
27696 * Skip elements if inside a "skip" wildcard or if invalid.
27698 if (vctxt
->skipDepth
!= -1) {
27699 if (vctxt
->depth
> vctxt
->skipDepth
) {
27703 vctxt
->skipDepth
= -1;
27706 * SAX VAL TODO: Just a temporary check.
27708 if ((!xmlStrEqual(vctxt
->inode
->localName
, localname
)) ||
27709 (!xmlStrEqual(vctxt
->inode
->nsName
, URI
))) {
27710 VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27711 "elem pop mismatch");
27713 res
= xmlSchemaValidatorPopElem(vctxt
);
27716 VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27717 "calling xmlSchemaValidatorPopElem()");
27718 goto internal_error
;
27726 xmlStopParser(vctxt
->parserCtxt
);
27730 /************************************************************************
27732 * Validation interfaces *
27734 ************************************************************************/
27737 * xmlSchemaNewValidCtxt:
27738 * @schema: a precompiled XML Schemas
27740 * Create an XML Schemas validation context based on the given schema.
27742 * Returns the validation context or NULL in case of error
27744 xmlSchemaValidCtxtPtr
27745 xmlSchemaNewValidCtxt(xmlSchemaPtr schema
)
27747 xmlSchemaValidCtxtPtr ret
;
27749 ret
= (xmlSchemaValidCtxtPtr
) xmlMalloc(sizeof(xmlSchemaValidCtxt
));
27751 xmlSchemaVErrMemory(NULL
, "allocating validation context", NULL
);
27754 memset(ret
, 0, sizeof(xmlSchemaValidCtxt
));
27755 ret
->type
= XML_SCHEMA_CTXT_VALIDATOR
;
27756 ret
->dict
= xmlDictCreate();
27757 ret
->nodeQNames
= xmlSchemaItemListCreate();
27758 ret
->schema
= schema
;
27763 * xmlSchemaValidateSetFilename:
27764 * @vctxt: the schema validation context
27765 * @filename: the file name
27767 * Workaround to provide file error reporting information when this is
27768 * not provided by current APIs
27771 xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt
, const char *filename
) {
27774 if (vctxt
->filename
!= NULL
)
27775 xmlFree(vctxt
->filename
);
27776 if (filename
!= NULL
)
27777 vctxt
->filename
= (char *) xmlStrdup((const xmlChar
*) filename
);
27779 vctxt
->filename
= NULL
;
27783 * xmlSchemaClearValidCtxt:
27784 * @vctxt: the schema validation context
27786 * Free the resources associated to the schema validation context;
27787 * leaves some fields alive intended for reuse of the context.
27790 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt
)
27796 * TODO: Should we clear the flags?
27797 * Might be problematic if one reuses the context
27798 * and assumes that the options remain the same.
27801 vctxt
->validationRoot
= NULL
;
27803 #ifdef LIBXML_READER_ENABLED
27804 vctxt
->reader
= NULL
;
27806 vctxt
->hasKeyrefs
= 0;
27808 if (vctxt
->value
!= NULL
) {
27809 xmlSchemaFreeValue(vctxt
->value
);
27810 vctxt
->value
= NULL
;
27813 * Augmented IDC information.
27815 if (vctxt
->aidcs
!= NULL
) {
27816 xmlSchemaIDCAugPtr cur
= vctxt
->aidcs
, next
;
27821 } while (cur
!= NULL
);
27822 vctxt
->aidcs
= NULL
;
27825 if (vctxt
->idcNodes
!= NULL
) {
27827 xmlSchemaPSVIIDCNodePtr item
;
27829 for (i
= 0; i
< vctxt
->nbIdcNodes
; i
++) {
27830 item
= vctxt
->idcNodes
[i
];
27831 xmlFree(item
->keys
);
27834 xmlFree(vctxt
->idcNodes
);
27835 vctxt
->idcNodes
= NULL
;
27836 vctxt
->nbIdcNodes
= 0;
27837 vctxt
->sizeIdcNodes
= 0;
27840 if (vctxt
->idcKeys
!= NULL
) {
27842 for (i
= 0; i
< vctxt
->nbIdcKeys
; i
++)
27843 xmlSchemaIDCFreeKey(vctxt
->idcKeys
[i
]);
27844 xmlFree(vctxt
->idcKeys
);
27845 vctxt
->idcKeys
= NULL
;
27846 vctxt
->nbIdcKeys
= 0;
27847 vctxt
->sizeIdcKeys
= 0;
27851 * Note that we won't delete the XPath state pool here.
27853 if (vctxt
->xpathStates
!= NULL
) {
27854 xmlSchemaFreeIDCStateObjList(vctxt
->xpathStates
);
27855 vctxt
->xpathStates
= NULL
;
27860 if (vctxt
->nbAttrInfos
!= 0) {
27861 xmlSchemaClearAttrInfos(vctxt
);
27866 if (vctxt
->elemInfos
!= NULL
) {
27868 xmlSchemaNodeInfoPtr ei
;
27870 for (i
= 0; i
< vctxt
->sizeElemInfos
; i
++) {
27871 ei
= vctxt
->elemInfos
[i
];
27874 xmlSchemaClearElemInfo(vctxt
, ei
);
27877 xmlSchemaItemListClear(vctxt
->nodeQNames
);
27878 /* Recreate the dict. */
27879 xmlDictFree(vctxt
->dict
);
27881 * TODO: Is is save to recreate it? Do we have a scenario
27882 * where the user provides the dict?
27884 vctxt
->dict
= xmlDictCreate();
27886 if (vctxt
->filename
!= NULL
) {
27887 xmlFree(vctxt
->filename
);
27888 vctxt
->filename
= NULL
;
27892 * Note that some cleanup functions can move items to the cache,
27893 * so the cache shouldn't be freed too early.
27895 if (vctxt
->idcMatcherCache
!= NULL
) {
27896 xmlSchemaIDCMatcherPtr matcher
= vctxt
->idcMatcherCache
, tmp
;
27900 matcher
= matcher
->nextCached
;
27901 xmlSchemaIDCFreeMatcherList(tmp
);
27903 vctxt
->idcMatcherCache
= NULL
;
27908 * xmlSchemaFreeValidCtxt:
27909 * @ctxt: the schema validation context
27911 * Free the resources associated to the schema validation context
27914 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt
)
27918 if (ctxt
->value
!= NULL
)
27919 xmlSchemaFreeValue(ctxt
->value
);
27920 if (ctxt
->pctxt
!= NULL
)
27921 xmlSchemaFreeParserCtxt(ctxt
->pctxt
);
27922 if (ctxt
->idcNodes
!= NULL
) {
27924 xmlSchemaPSVIIDCNodePtr item
;
27926 for (i
= 0; i
< ctxt
->nbIdcNodes
; i
++) {
27927 item
= ctxt
->idcNodes
[i
];
27928 xmlFree(item
->keys
);
27931 xmlFree(ctxt
->idcNodes
);
27933 if (ctxt
->idcKeys
!= NULL
) {
27935 for (i
= 0; i
< ctxt
->nbIdcKeys
; i
++)
27936 xmlSchemaIDCFreeKey(ctxt
->idcKeys
[i
]);
27937 xmlFree(ctxt
->idcKeys
);
27940 if (ctxt
->xpathStates
!= NULL
) {
27941 xmlSchemaFreeIDCStateObjList(ctxt
->xpathStates
);
27942 ctxt
->xpathStates
= NULL
;
27944 if (ctxt
->xpathStatePool
!= NULL
) {
27945 xmlSchemaFreeIDCStateObjList(ctxt
->xpathStatePool
);
27946 ctxt
->xpathStatePool
= NULL
;
27950 * Augmented IDC information.
27952 if (ctxt
->aidcs
!= NULL
) {
27953 xmlSchemaIDCAugPtr cur
= ctxt
->aidcs
, next
;
27958 } while (cur
!= NULL
);
27960 if (ctxt
->attrInfos
!= NULL
) {
27962 xmlSchemaAttrInfoPtr attr
;
27964 /* Just a paranoid call to the cleanup. */
27965 if (ctxt
->nbAttrInfos
!= 0)
27966 xmlSchemaClearAttrInfos(ctxt
);
27967 for (i
= 0; i
< ctxt
->sizeAttrInfos
; i
++) {
27968 attr
= ctxt
->attrInfos
[i
];
27971 xmlFree(ctxt
->attrInfos
);
27973 if (ctxt
->elemInfos
!= NULL
) {
27975 xmlSchemaNodeInfoPtr ei
;
27977 for (i
= 0; i
< ctxt
->sizeElemInfos
; i
++) {
27978 ei
= ctxt
->elemInfos
[i
];
27981 xmlSchemaClearElemInfo(ctxt
, ei
);
27984 xmlFree(ctxt
->elemInfos
);
27986 if (ctxt
->nodeQNames
!= NULL
)
27987 xmlSchemaItemListFree(ctxt
->nodeQNames
);
27988 if (ctxt
->dict
!= NULL
)
27989 xmlDictFree(ctxt
->dict
);
27990 if (ctxt
->filename
!= NULL
)
27991 xmlFree(ctxt
->filename
);
27996 * xmlSchemaIsValid:
27997 * @ctxt: the schema validation context
27999 * Check if any error was detected during validation.
28001 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
28002 * of internal error.
28005 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt
)
28009 return(ctxt
->err
== 0);
28013 * xmlSchemaSetValidErrors:
28014 * @ctxt: a schema validation context
28015 * @err: the error function
28016 * @warn: the warning function
28017 * @ctx: the functions context
28019 * Set the error and warning callback information
28022 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt
,
28023 xmlSchemaValidityErrorFunc err
,
28024 xmlSchemaValidityWarningFunc warn
, void *ctx
)
28029 ctxt
->warning
= warn
;
28030 ctxt
->errCtxt
= ctx
;
28031 if (ctxt
->pctxt
!= NULL
)
28032 xmlSchemaSetParserErrors(ctxt
->pctxt
, err
, warn
, ctx
);
28036 * xmlSchemaSetValidStructuredErrors:
28037 * @ctxt: a schema validation context
28038 * @serror: the structured error function
28039 * @ctx: the functions context
28041 * Set the structured error callback
28044 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt
,
28045 xmlStructuredErrorFunc serror
, void *ctx
)
28049 ctxt
->serror
= serror
;
28050 ctxt
->error
= NULL
;
28051 ctxt
->warning
= NULL
;
28052 ctxt
->errCtxt
= ctx
;
28053 if (ctxt
->pctxt
!= NULL
)
28054 xmlSchemaSetParserStructuredErrors(ctxt
->pctxt
, serror
, ctx
);
28058 * xmlSchemaGetValidErrors:
28059 * @ctxt: a XML-Schema validation context
28060 * @err: the error function result
28061 * @warn: the warning function result
28062 * @ctx: the functions context result
28064 * Get the error and warning callback information
28066 * Returns -1 in case of error and 0 otherwise
28069 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt
,
28070 xmlSchemaValidityErrorFunc
* err
,
28071 xmlSchemaValidityWarningFunc
* warn
, void **ctx
)
28076 *err
= ctxt
->error
;
28078 *warn
= ctxt
->warning
;
28080 *ctx
= ctxt
->errCtxt
;
28086 * xmlSchemaSetValidOptions:
28087 * @ctxt: a schema validation context
28088 * @options: a combination of xmlSchemaValidOption
28090 * Sets the options to be used during the validation.
28092 * Returns 0 in case of success, -1 in case of an
28096 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt
,
28105 * WARNING: Change the start value if adding to the
28106 * xmlSchemaValidOption.
28107 * TODO: Is there an other, more easy to maintain,
28110 for (i
= 1; i
< (int) sizeof(int) * 8; i
++) {
28111 if (options
& 1<<i
)
28114 ctxt
->options
= options
;
28119 * xmlSchemaValidCtxtGetOptions:
28120 * @ctxt: a schema validation context
28122 * Get the validation context options.
28124 * Returns the option combination or -1 on error.
28127 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt
)
28133 return (ctxt
->options
);
28137 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt
)
28141 xmlSchemaNodeInfoPtr ielem
= NULL
;
28142 xmlNodePtr node
, valRoot
;
28143 const xmlChar
*nsName
;
28145 /* DOC VAL TODO: Move this to the start function. */
28146 if (vctxt
->validationRoot
!= NULL
)
28147 valRoot
= vctxt
->validationRoot
;
28149 valRoot
= xmlDocGetRootElement(vctxt
->doc
);
28150 if (valRoot
== NULL
) {
28151 /* VAL TODO: Error code? */
28152 VERROR(1, NULL
, "The document has no document element");
28156 vctxt
->validationRoot
= valRoot
;
28158 while (node
!= NULL
) {
28159 if ((vctxt
->skipDepth
!= -1) && (vctxt
->depth
>= vctxt
->skipDepth
))
28161 if (node
->type
== XML_ELEMENT_NODE
) {
28164 * Init the node-info.
28167 if (xmlSchemaValidatorPushElem(vctxt
) == -1)
28168 goto internal_error
;
28169 ielem
= vctxt
->inode
;
28170 ielem
->node
= node
;
28171 ielem
->nodeLine
= node
->line
;
28172 ielem
->localName
= node
->name
;
28173 if (node
->ns
!= NULL
)
28174 ielem
->nsName
= node
->ns
->href
;
28175 ielem
->flags
|= XML_SCHEMA_ELEM_INFO_EMPTY
;
28177 * Register attributes.
28178 * DOC VAL TODO: We do not register namespace declaration
28181 vctxt
->nbAttrInfos
= 0;
28182 if (node
->properties
!= NULL
) {
28183 attr
= node
->properties
;
28185 if (attr
->ns
!= NULL
)
28186 nsName
= attr
->ns
->href
;
28189 ret
= xmlSchemaValidatorPushAttribute(vctxt
,
28192 * Note that we give it the line number of the
28196 attr
->name
, nsName
, 0,
28197 xmlNodeListGetString(attr
->doc
, attr
->children
, 1), 1);
28199 VERROR_INT("xmlSchemaDocWalk",
28200 "calling xmlSchemaValidatorPushAttribute()");
28201 goto internal_error
;
28207 * Validate the element.
28209 ret
= xmlSchemaValidateElem(vctxt
);
28212 VERROR_INT("xmlSchemaDocWalk",
28213 "calling xmlSchemaValidateElem()");
28214 goto internal_error
;
28217 * Don't stop validation; just skip the content
28222 if ((vctxt
->skipDepth
!= -1) &&
28223 (vctxt
->depth
>= vctxt
->skipDepth
))
28225 } else if ((node
->type
== XML_TEXT_NODE
) ||
28226 (node
->type
== XML_CDATA_SECTION_NODE
)) {
28228 * Process character content.
28230 if ((ielem
!= NULL
) && (ielem
->flags
& XML_SCHEMA_ELEM_INFO_EMPTY
))
28231 ielem
->flags
^= XML_SCHEMA_ELEM_INFO_EMPTY
;
28232 ret
= xmlSchemaVPushText(vctxt
, node
->type
, node
->content
,
28233 -1, XML_SCHEMA_PUSH_TEXT_PERSIST
, NULL
);
28235 VERROR_INT("xmlSchemaVDocWalk",
28236 "calling xmlSchemaVPushText()");
28237 goto internal_error
;
28240 * DOC VAL TODO: Should we skip further validation of the
28241 * element content here?
28243 } else if ((node
->type
== XML_ENTITY_NODE
) ||
28244 (node
->type
== XML_ENTITY_REF_NODE
)) {
28246 * DOC VAL TODO: What to do with entities?
28248 VERROR_INT("xmlSchemaVDocWalk",
28249 "there is at least one entity reference in the node-tree "
28250 "currently being validated. Processing of entities with "
28251 "this XML Schema processor is not supported (yet). Please "
28252 "substitute entities before validation.");
28253 goto internal_error
;
28257 * DOC VAL TODO: XInclude nodes, etc.
28263 if (node
->children
!= NULL
) {
28264 node
= node
->children
;
28268 if (node
->type
== XML_ELEMENT_NODE
) {
28270 * Leaving the scope of an element.
28272 if (node
!= vctxt
->inode
->node
) {
28273 VERROR_INT("xmlSchemaVDocWalk",
28274 "element position mismatch");
28275 goto internal_error
;
28277 ret
= xmlSchemaValidatorPopElem(vctxt
);
28280 VERROR_INT("xmlSchemaVDocWalk",
28281 "calling xmlSchemaValidatorPopElem()");
28282 goto internal_error
;
28285 if (node
== valRoot
)
28289 if (node
->next
!= NULL
)
28292 node
= node
->parent
;
28304 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt
) {
28306 * Some initialization.
28309 vctxt
->nberrors
= 0;
28311 vctxt
->skipDepth
= -1;
28312 vctxt
->hasKeyrefs
= 0;
28313 #ifdef ENABLE_IDC_NODE_TABLES_TEST
28314 vctxt
->createIDCNodeTables
= 1;
28316 vctxt
->createIDCNodeTables
= 0;
28319 * Create a schema + parser if necessary.
28321 if (vctxt
->schema
== NULL
) {
28322 xmlSchemaParserCtxtPtr pctxt
;
28324 vctxt
->xsiAssemble
= 1;
28326 * If not schema was given then we will create a schema
28327 * dynamically using XSI schema locations.
28329 * Create the schema parser context.
28331 if ((vctxt
->pctxt
== NULL
) &&
28332 (xmlSchemaCreatePCtxtOnVCtxt(vctxt
) == -1))
28334 pctxt
= vctxt
->pctxt
;
28335 pctxt
->xsiAssemble
= 1;
28337 * Create the schema.
28339 vctxt
->schema
= xmlSchemaNewSchema(pctxt
);
28340 if (vctxt
->schema
== NULL
)
28343 * Create the schema construction context.
28345 pctxt
->constructor
= xmlSchemaConstructionCtxtCreate(pctxt
->dict
);
28346 if (pctxt
->constructor
== NULL
)
28348 pctxt
->constructor
->mainSchema
= vctxt
->schema
;
28350 * Take ownership of the constructor to be able to free it.
28352 pctxt
->ownsConstructor
= 1;
28355 * Augment the IDC definitions for the main schema and all imported ones
28356 * NOTE: main schema if the first in the imported list
28358 xmlHashScan(vctxt
->schema
->schemasImports
, xmlSchemaAugmentImportedIDC
,
28365 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt
) {
28366 if (vctxt
->xsiAssemble
) {
28367 if (vctxt
->schema
!= NULL
) {
28368 xmlSchemaFree(vctxt
->schema
);
28369 vctxt
->schema
= NULL
;
28372 xmlSchemaClearValidCtxt(vctxt
);
28376 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt
)
28380 if (xmlSchemaPreRun(vctxt
) < 0)
28383 if (vctxt
->doc
!= NULL
) {
28387 ret
= xmlSchemaVDocWalk(vctxt
);
28388 #ifdef LIBXML_READER_ENABLED
28389 } else if (vctxt
->reader
!= NULL
) {
28391 * XML Reader validation.
28393 #ifdef XML_SCHEMA_READER_ENABLED
28394 ret
= xmlSchemaVReaderWalk(vctxt
);
28397 } else if ((vctxt
->sax
!= NULL
) && (vctxt
->parserCtxt
!= NULL
)) {
28401 ret
= xmlParseDocument(vctxt
->parserCtxt
);
28403 VERROR_INT("xmlSchemaVStart",
28404 "no instance to validate");
28408 xmlSchemaPostRun(vctxt
);
28415 * xmlSchemaValidateOneElement:
28416 * @ctxt: a schema validation context
28417 * @elem: an element node
28419 * Validate a branch of a tree, starting with the given @elem.
28421 * Returns 0 if the element and its subtree is valid, a positive error
28422 * code number otherwise and -1 in case of an internal or API error.
28425 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt
, xmlNodePtr elem
)
28427 if ((ctxt
== NULL
) || (elem
== NULL
) || (elem
->type
!= XML_ELEMENT_NODE
))
28430 if (ctxt
->schema
== NULL
)
28433 ctxt
->doc
= elem
->doc
;
28435 ctxt
->validationRoot
= elem
;
28436 return(xmlSchemaVStart(ctxt
));
28440 * xmlSchemaValidateDoc:
28441 * @ctxt: a schema validation context
28442 * @doc: a parsed document tree
28444 * Validate a document tree in memory.
28446 * Returns 0 if the document is schemas valid, a positive error code
28447 * number otherwise and -1 in case of internal or API error.
28450 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt
, xmlDocPtr doc
)
28452 if ((ctxt
== NULL
) || (doc
== NULL
))
28456 ctxt
->node
= xmlDocGetRootElement(doc
);
28457 if (ctxt
->node
== NULL
) {
28458 xmlSchemaCustomErr(ACTXT_CAST ctxt
,
28459 XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING
,
28460 (xmlNodePtr
) doc
, NULL
,
28461 "The document has no document element", NULL
, NULL
);
28462 return (ctxt
->err
);
28464 ctxt
->validationRoot
= ctxt
->node
;
28465 return (xmlSchemaVStart(ctxt
));
28469 /************************************************************************
28471 * Function and data for SAX streaming API *
28473 ************************************************************************/
28474 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData
;
28475 typedef xmlSchemaSplitSAXData
*xmlSchemaSplitSAXDataPtr
;
28477 struct _xmlSchemaSplitSAXData
{
28478 xmlSAXHandlerPtr user_sax
;
28480 xmlSchemaValidCtxtPtr ctxt
;
28481 xmlSAXHandlerPtr schemas_sax
;
28484 #define XML_SAX_PLUG_MAGIC 0xdc43ba21
28486 struct _xmlSchemaSAXPlug
{
28487 unsigned int magic
;
28489 /* the original callbacks information */
28490 xmlSAXHandlerPtr
*user_sax_ptr
;
28491 xmlSAXHandlerPtr user_sax
;
28492 void **user_data_ptr
;
28495 /* the block plugged back and validation information */
28496 xmlSAXHandler schemas_sax
;
28497 xmlSchemaValidCtxtPtr ctxt
;
28500 /* All those functions just bounces to the user provided SAX handlers */
28502 internalSubsetSplit(void *ctx
, const xmlChar
*name
,
28503 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
28505 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28506 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28507 (ctxt
->user_sax
->internalSubset
!= NULL
))
28508 ctxt
->user_sax
->internalSubset(ctxt
->user_data
, name
, ExternalID
,
28513 isStandaloneSplit(void *ctx
)
28515 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28516 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28517 (ctxt
->user_sax
->isStandalone
!= NULL
))
28518 return(ctxt
->user_sax
->isStandalone(ctxt
->user_data
));
28523 hasInternalSubsetSplit(void *ctx
)
28525 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28526 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28527 (ctxt
->user_sax
->hasInternalSubset
!= NULL
))
28528 return(ctxt
->user_sax
->hasInternalSubset(ctxt
->user_data
));
28533 hasExternalSubsetSplit(void *ctx
)
28535 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28536 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28537 (ctxt
->user_sax
->hasExternalSubset
!= NULL
))
28538 return(ctxt
->user_sax
->hasExternalSubset(ctxt
->user_data
));
28543 externalSubsetSplit(void *ctx
, const xmlChar
*name
,
28544 const xmlChar
*ExternalID
, const xmlChar
*SystemID
)
28546 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28547 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28548 (ctxt
->user_sax
->externalSubset
!= NULL
))
28549 ctxt
->user_sax
->externalSubset(ctxt
->user_data
, name
, ExternalID
,
28553 static xmlParserInputPtr
28554 resolveEntitySplit(void *ctx
, const xmlChar
*publicId
, const xmlChar
*systemId
)
28556 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28557 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28558 (ctxt
->user_sax
->resolveEntity
!= NULL
))
28559 return(ctxt
->user_sax
->resolveEntity(ctxt
->user_data
, publicId
,
28564 static xmlEntityPtr
28565 getEntitySplit(void *ctx
, const xmlChar
*name
)
28567 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28568 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28569 (ctxt
->user_sax
->getEntity
!= NULL
))
28570 return(ctxt
->user_sax
->getEntity(ctxt
->user_data
, name
));
28574 static xmlEntityPtr
28575 getParameterEntitySplit(void *ctx
, const xmlChar
*name
)
28577 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28578 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28579 (ctxt
->user_sax
->getParameterEntity
!= NULL
))
28580 return(ctxt
->user_sax
->getParameterEntity(ctxt
->user_data
, name
));
28586 entityDeclSplit(void *ctx
, const xmlChar
*name
, int type
,
28587 const xmlChar
*publicId
, const xmlChar
*systemId
, xmlChar
*content
)
28589 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28590 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28591 (ctxt
->user_sax
->entityDecl
!= NULL
))
28592 ctxt
->user_sax
->entityDecl(ctxt
->user_data
, name
, type
, publicId
,
28593 systemId
, content
);
28597 attributeDeclSplit(void *ctx
, const xmlChar
* elem
,
28598 const xmlChar
* name
, int type
, int def
,
28599 const xmlChar
* defaultValue
, xmlEnumerationPtr tree
)
28601 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28602 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28603 (ctxt
->user_sax
->attributeDecl
!= NULL
)) {
28604 ctxt
->user_sax
->attributeDecl(ctxt
->user_data
, elem
, name
, type
,
28605 def
, defaultValue
, tree
);
28607 xmlFreeEnumeration(tree
);
28612 elementDeclSplit(void *ctx
, const xmlChar
*name
, int type
,
28613 xmlElementContentPtr content
)
28615 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28616 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28617 (ctxt
->user_sax
->elementDecl
!= NULL
))
28618 ctxt
->user_sax
->elementDecl(ctxt
->user_data
, name
, type
, content
);
28622 notationDeclSplit(void *ctx
, const xmlChar
*name
,
28623 const xmlChar
*publicId
, const xmlChar
*systemId
)
28625 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28626 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28627 (ctxt
->user_sax
->notationDecl
!= NULL
))
28628 ctxt
->user_sax
->notationDecl(ctxt
->user_data
, name
, publicId
,
28633 unparsedEntityDeclSplit(void *ctx
, const xmlChar
*name
,
28634 const xmlChar
*publicId
, const xmlChar
*systemId
,
28635 const xmlChar
*notationName
)
28637 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28638 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28639 (ctxt
->user_sax
->unparsedEntityDecl
!= NULL
))
28640 ctxt
->user_sax
->unparsedEntityDecl(ctxt
->user_data
, name
, publicId
,
28641 systemId
, notationName
);
28645 setDocumentLocatorSplit(void *ctx
, xmlSAXLocatorPtr loc
)
28647 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28648 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28649 (ctxt
->user_sax
->setDocumentLocator
!= NULL
))
28650 ctxt
->user_sax
->setDocumentLocator(ctxt
->user_data
, loc
);
28654 startDocumentSplit(void *ctx
)
28656 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28657 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28658 (ctxt
->user_sax
->startDocument
!= NULL
))
28659 ctxt
->user_sax
->startDocument(ctxt
->user_data
);
28663 endDocumentSplit(void *ctx
)
28665 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28666 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28667 (ctxt
->user_sax
->endDocument
!= NULL
))
28668 ctxt
->user_sax
->endDocument(ctxt
->user_data
);
28672 processingInstructionSplit(void *ctx
, const xmlChar
*target
,
28673 const xmlChar
*data
)
28675 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28676 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28677 (ctxt
->user_sax
->processingInstruction
!= NULL
))
28678 ctxt
->user_sax
->processingInstruction(ctxt
->user_data
, target
, data
);
28682 commentSplit(void *ctx
, const xmlChar
*value
)
28684 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28685 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28686 (ctxt
->user_sax
->comment
!= NULL
))
28687 ctxt
->user_sax
->comment(ctxt
->user_data
, value
);
28691 * Varargs error callbacks to the user application, harder ...
28694 static void XMLCDECL
28695 warningSplit(void *ctx
, const char *msg ATTRIBUTE_UNUSED
, ...) {
28696 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28697 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28698 (ctxt
->user_sax
->warning
!= NULL
)) {
28702 static void XMLCDECL
28703 errorSplit(void *ctx
, const char *msg ATTRIBUTE_UNUSED
, ...) {
28704 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28705 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28706 (ctxt
->user_sax
->error
!= NULL
)) {
28710 static void XMLCDECL
28711 fatalErrorSplit(void *ctx
, const char *msg ATTRIBUTE_UNUSED
, ...) {
28712 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28713 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28714 (ctxt
->user_sax
->fatalError
!= NULL
)) {
28720 * Those are function where both the user handler and the schemas handler
28721 * need to be called.
28724 charactersSplit(void *ctx
, const xmlChar
*ch
, int len
)
28726 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28729 if ((ctxt
->user_sax
!= NULL
) && (ctxt
->user_sax
->characters
!= NULL
))
28730 ctxt
->user_sax
->characters(ctxt
->user_data
, ch
, len
);
28731 if (ctxt
->ctxt
!= NULL
)
28732 xmlSchemaSAXHandleText(ctxt
->ctxt
, ch
, len
);
28736 ignorableWhitespaceSplit(void *ctx
, const xmlChar
*ch
, int len
)
28738 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28741 if ((ctxt
->user_sax
!= NULL
) &&
28742 (ctxt
->user_sax
->ignorableWhitespace
!= NULL
))
28743 ctxt
->user_sax
->ignorableWhitespace(ctxt
->user_data
, ch
, len
);
28744 if (ctxt
->ctxt
!= NULL
)
28745 xmlSchemaSAXHandleText(ctxt
->ctxt
, ch
, len
);
28749 cdataBlockSplit(void *ctx
, const xmlChar
*value
, int len
)
28751 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28754 if ((ctxt
->user_sax
!= NULL
) &&
28755 (ctxt
->user_sax
->cdataBlock
!= NULL
))
28756 ctxt
->user_sax
->cdataBlock(ctxt
->user_data
, value
, len
);
28757 if (ctxt
->ctxt
!= NULL
)
28758 xmlSchemaSAXHandleCDataSection(ctxt
->ctxt
, value
, len
);
28762 referenceSplit(void *ctx
, const xmlChar
*name
)
28764 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28767 if ((ctxt
!= NULL
) && (ctxt
->user_sax
!= NULL
) &&
28768 (ctxt
->user_sax
->reference
!= NULL
))
28769 ctxt
->user_sax
->reference(ctxt
->user_data
, name
);
28770 if (ctxt
->ctxt
!= NULL
)
28771 xmlSchemaSAXHandleReference(ctxt
->user_data
, name
);
28775 startElementNsSplit(void *ctx
, const xmlChar
* localname
,
28776 const xmlChar
* prefix
, const xmlChar
* URI
,
28777 int nb_namespaces
, const xmlChar
** namespaces
,
28778 int nb_attributes
, int nb_defaulted
,
28779 const xmlChar
** attributes
) {
28780 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28783 if ((ctxt
->user_sax
!= NULL
) &&
28784 (ctxt
->user_sax
->startElementNs
!= NULL
))
28785 ctxt
->user_sax
->startElementNs(ctxt
->user_data
, localname
, prefix
,
28786 URI
, nb_namespaces
, namespaces
,
28787 nb_attributes
, nb_defaulted
,
28789 if (ctxt
->ctxt
!= NULL
)
28790 xmlSchemaSAXHandleStartElementNs(ctxt
->ctxt
, localname
, prefix
,
28791 URI
, nb_namespaces
, namespaces
,
28792 nb_attributes
, nb_defaulted
,
28797 endElementNsSplit(void *ctx
, const xmlChar
* localname
,
28798 const xmlChar
* prefix
, const xmlChar
* URI
) {
28799 xmlSchemaSAXPlugPtr ctxt
= (xmlSchemaSAXPlugPtr
) ctx
;
28802 if ((ctxt
->user_sax
!= NULL
) &&
28803 (ctxt
->user_sax
->endElementNs
!= NULL
))
28804 ctxt
->user_sax
->endElementNs(ctxt
->user_data
, localname
, prefix
, URI
);
28805 if (ctxt
->ctxt
!= NULL
)
28806 xmlSchemaSAXHandleEndElementNs(ctxt
->ctxt
, localname
, prefix
, URI
);
28810 * xmlSchemaSAXPlug:
28811 * @ctxt: a schema validation context
28812 * @sax: a pointer to the original xmlSAXHandlerPtr
28813 * @user_data: a pointer to the original SAX user data pointer
28815 * Plug a SAX based validation layer in a SAX parsing event flow.
28816 * The original @saxptr and @dataptr data are replaced by new pointers
28817 * but the calls to the original will be maintained.
28819 * Returns a pointer to a data structure needed to unplug the validation layer
28820 * or NULL in case of errors.
28822 xmlSchemaSAXPlugPtr
28823 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt
,
28824 xmlSAXHandlerPtr
*sax
, void **user_data
)
28826 xmlSchemaSAXPlugPtr ret
;
28827 xmlSAXHandlerPtr old_sax
;
28829 if ((ctxt
== NULL
) || (sax
== NULL
) || (user_data
== NULL
))
28833 * We only allow to plug into SAX2 event streams
28836 if ((old_sax
!= NULL
) && (old_sax
->initialized
!= XML_SAX2_MAGIC
))
28838 if ((old_sax
!= NULL
) &&
28839 (old_sax
->startElementNs
== NULL
) && (old_sax
->endElementNs
== NULL
) &&
28840 ((old_sax
->startElement
!= NULL
) || (old_sax
->endElement
!= NULL
)))
28844 * everything seems right allocate the local data needed for that layer
28846 ret
= (xmlSchemaSAXPlugPtr
) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct
));
28850 memset(ret
, 0, sizeof(xmlSchemaSAXPlugStruct
));
28851 ret
->magic
= XML_SAX_PLUG_MAGIC
;
28852 ret
->schemas_sax
.initialized
= XML_SAX2_MAGIC
;
28854 ret
->user_sax_ptr
= sax
;
28855 ret
->user_sax
= old_sax
;
28856 if (old_sax
== NULL
) {
28858 * go direct, no need for the split block and functions.
28860 ret
->schemas_sax
.startElementNs
= xmlSchemaSAXHandleStartElementNs
;
28861 ret
->schemas_sax
.endElementNs
= xmlSchemaSAXHandleEndElementNs
;
28863 * Note that we use the same text-function for both, to prevent
28864 * the parser from testing for ignorable whitespace.
28866 ret
->schemas_sax
.ignorableWhitespace
= xmlSchemaSAXHandleText
;
28867 ret
->schemas_sax
.characters
= xmlSchemaSAXHandleText
;
28869 ret
->schemas_sax
.cdataBlock
= xmlSchemaSAXHandleCDataSection
;
28870 ret
->schemas_sax
.reference
= xmlSchemaSAXHandleReference
;
28872 ret
->user_data
= ctxt
;
28876 * for each callback unused by Schemas initialize it to the Split
28877 * routine only if non NULL in the user block, this can speed up
28878 * things at the SAX level.
28880 if (old_sax
->internalSubset
!= NULL
)
28881 ret
->schemas_sax
.internalSubset
= internalSubsetSplit
;
28882 if (old_sax
->isStandalone
!= NULL
)
28883 ret
->schemas_sax
.isStandalone
= isStandaloneSplit
;
28884 if (old_sax
->hasInternalSubset
!= NULL
)
28885 ret
->schemas_sax
.hasInternalSubset
= hasInternalSubsetSplit
;
28886 if (old_sax
->hasExternalSubset
!= NULL
)
28887 ret
->schemas_sax
.hasExternalSubset
= hasExternalSubsetSplit
;
28888 if (old_sax
->resolveEntity
!= NULL
)
28889 ret
->schemas_sax
.resolveEntity
= resolveEntitySplit
;
28890 if (old_sax
->getEntity
!= NULL
)
28891 ret
->schemas_sax
.getEntity
= getEntitySplit
;
28892 if (old_sax
->entityDecl
!= NULL
)
28893 ret
->schemas_sax
.entityDecl
= entityDeclSplit
;
28894 if (old_sax
->notationDecl
!= NULL
)
28895 ret
->schemas_sax
.notationDecl
= notationDeclSplit
;
28896 if (old_sax
->attributeDecl
!= NULL
)
28897 ret
->schemas_sax
.attributeDecl
= attributeDeclSplit
;
28898 if (old_sax
->elementDecl
!= NULL
)
28899 ret
->schemas_sax
.elementDecl
= elementDeclSplit
;
28900 if (old_sax
->unparsedEntityDecl
!= NULL
)
28901 ret
->schemas_sax
.unparsedEntityDecl
= unparsedEntityDeclSplit
;
28902 if (old_sax
->setDocumentLocator
!= NULL
)
28903 ret
->schemas_sax
.setDocumentLocator
= setDocumentLocatorSplit
;
28904 if (old_sax
->startDocument
!= NULL
)
28905 ret
->schemas_sax
.startDocument
= startDocumentSplit
;
28906 if (old_sax
->endDocument
!= NULL
)
28907 ret
->schemas_sax
.endDocument
= endDocumentSplit
;
28908 if (old_sax
->processingInstruction
!= NULL
)
28909 ret
->schemas_sax
.processingInstruction
= processingInstructionSplit
;
28910 if (old_sax
->comment
!= NULL
)
28911 ret
->schemas_sax
.comment
= commentSplit
;
28912 if (old_sax
->warning
!= NULL
)
28913 ret
->schemas_sax
.warning
= warningSplit
;
28914 if (old_sax
->error
!= NULL
)
28915 ret
->schemas_sax
.error
= errorSplit
;
28916 if (old_sax
->fatalError
!= NULL
)
28917 ret
->schemas_sax
.fatalError
= fatalErrorSplit
;
28918 if (old_sax
->getParameterEntity
!= NULL
)
28919 ret
->schemas_sax
.getParameterEntity
= getParameterEntitySplit
;
28920 if (old_sax
->externalSubset
!= NULL
)
28921 ret
->schemas_sax
.externalSubset
= externalSubsetSplit
;
28924 * the 6 schemas callback have to go to the splitter functions
28925 * Note that we use the same text-function for ignorableWhitespace
28926 * if possible, to prevent the parser from testing for ignorable
28929 ret
->schemas_sax
.characters
= charactersSplit
;
28930 if ((old_sax
->ignorableWhitespace
!= NULL
) &&
28931 (old_sax
->ignorableWhitespace
!= old_sax
->characters
))
28932 ret
->schemas_sax
.ignorableWhitespace
= ignorableWhitespaceSplit
;
28934 ret
->schemas_sax
.ignorableWhitespace
= charactersSplit
;
28935 ret
->schemas_sax
.cdataBlock
= cdataBlockSplit
;
28936 ret
->schemas_sax
.reference
= referenceSplit
;
28937 ret
->schemas_sax
.startElementNs
= startElementNsSplit
;
28938 ret
->schemas_sax
.endElementNs
= endElementNsSplit
;
28940 ret
->user_data_ptr
= user_data
;
28941 ret
->user_data
= *user_data
;
28946 * plug the pointers back.
28948 *sax
= &(ret
->schemas_sax
);
28950 ctxt
->flags
|= XML_SCHEMA_VALID_CTXT_FLAG_STREAM
;
28951 xmlSchemaPreRun(ctxt
);
28956 * xmlSchemaSAXUnplug:
28957 * @plug: a data structure returned by xmlSchemaSAXPlug
28959 * Unplug a SAX based validation layer in a SAX parsing event flow.
28960 * The original pointers used in the call are restored.
28962 * Returns 0 in case of success and -1 in case of failure.
28965 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug
)
28967 xmlSAXHandlerPtr
*sax
;
28970 if ((plug
== NULL
) || (plug
->magic
!= XML_SAX_PLUG_MAGIC
))
28974 xmlSchemaPostRun(plug
->ctxt
);
28975 /* restore the data */
28976 sax
= plug
->user_sax_ptr
;
28977 *sax
= plug
->user_sax
;
28978 if (plug
->user_sax
!= NULL
) {
28979 user_data
= plug
->user_data_ptr
;
28980 *user_data
= plug
->user_data
;
28983 /* free and return */
28989 * xmlSchemaValidateSetLocator:
28990 * @vctxt: a schema validation context
28991 * @f: the locator function pointer
28992 * @ctxt: the locator context
28994 * Allows to set a locator function to the validation context,
28995 * which will be used to provide file and line information since
28996 * those are not provided as part of the SAX validation flow
28997 * Setting @f to NULL disable the locator.
29001 xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt
,
29002 xmlSchemaValidityLocatorFunc f
,
29005 if (vctxt
== NULL
) return;
29006 vctxt
->locFunc
= f
;
29007 vctxt
->locCtxt
= ctxt
;
29011 * xmlSchemaValidateStreamLocator:
29012 * @ctx: the xmlTextReaderPtr used
29013 * @file: returned file information
29014 * @line: returned line information
29016 * Internal locator function for the readers
29018 * Returns 0 in case the Schema validation could be (de)activated and
29019 * -1 in case of error.
29022 xmlSchemaValidateStreamLocator(void *ctx
, const char **file
,
29023 unsigned long *line
) {
29024 xmlParserCtxtPtr ctxt
;
29026 if ((ctx
== NULL
) || ((file
== NULL
) && (line
== NULL
)))
29034 ctxt
= (xmlParserCtxtPtr
) ctx
;
29035 if (ctxt
->input
!= NULL
) {
29037 *file
= ctxt
->input
->filename
;
29039 *line
= ctxt
->input
->line
;
29046 * xmlSchemaValidateStream:
29047 * @ctxt: a schema validation context
29048 * @input: the input to use for reading the data
29049 * @enc: an optional encoding information
29050 * @sax: a SAX handler for the resulting events
29051 * @user_data: the context to provide to the SAX handler.
29053 * Validate an input based on a flow of SAX event from the parser
29054 * and forward the events to the @sax handler with the provided @user_data
29055 * the user provided @sax handler must be a SAX2 one.
29057 * Returns 0 if the document is schemas valid, a positive error code
29058 * number otherwise and -1 in case of internal or API error.
29061 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt
,
29062 xmlParserInputBufferPtr input
, xmlCharEncoding enc
,
29063 xmlSAXHandlerPtr sax
, void *user_data
)
29065 xmlSchemaSAXPlugPtr plug
= NULL
;
29066 xmlSAXHandlerPtr old_sax
= NULL
;
29067 xmlParserCtxtPtr pctxt
= NULL
;
29068 xmlParserInputPtr inputStream
= NULL
;
29071 if ((ctxt
== NULL
) || (input
== NULL
))
29075 * prepare the parser
29077 pctxt
= xmlNewParserCtxt();
29080 old_sax
= pctxt
->sax
;
29082 pctxt
->userData
= user_data
;
29085 xmlCtxtUseOptions(pctxt
, options
);
29087 pctxt
->linenumbers
= 1;
29088 xmlSchemaValidateSetLocator(ctxt
, xmlSchemaValidateStreamLocator
, pctxt
);
29090 inputStream
= xmlNewIOInputStream(pctxt
, input
, enc
);;
29091 if (inputStream
== NULL
) {
29095 inputPush(pctxt
, inputStream
);
29096 ctxt
->parserCtxt
= pctxt
;
29097 ctxt
->input
= input
;
29100 * Plug the validation and launch the parsing
29102 plug
= xmlSchemaSAXPlug(ctxt
, &(pctxt
->sax
), &(pctxt
->userData
));
29103 if (plug
== NULL
) {
29107 ctxt
->input
= input
;
29109 ctxt
->sax
= pctxt
->sax
;
29110 ctxt
->flags
|= XML_SCHEMA_VALID_CTXT_FLAG_STREAM
;
29111 ret
= xmlSchemaVStart(ctxt
);
29113 if ((ret
== 0) && (! ctxt
->parserCtxt
->wellFormed
)) {
29114 ret
= ctxt
->parserCtxt
->errNo
;
29120 ctxt
->parserCtxt
= NULL
;
29122 ctxt
->input
= NULL
;
29123 if (plug
!= NULL
) {
29124 xmlSchemaSAXUnplug(plug
);
29127 if (pctxt
!= NULL
) {
29128 pctxt
->sax
= old_sax
;
29129 xmlFreeParserCtxt(pctxt
);
29135 * xmlSchemaValidateFile:
29136 * @ctxt: a schema validation context
29137 * @filename: the URI of the instance
29138 * @options: a future set of options, currently unused
29140 * Do a schemas validation of the given resource, it will use the
29141 * SAX streamable validation internally.
29143 * Returns 0 if the document is valid, a positive error code
29144 * number otherwise and -1 in case of an internal or API error.
29147 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt
,
29148 const char * filename
,
29149 int options ATTRIBUTE_UNUSED
)
29152 xmlParserInputBufferPtr input
;
29154 if ((ctxt
== NULL
) || (filename
== NULL
))
29157 input
= xmlParserInputBufferCreateFilename(filename
,
29158 XML_CHAR_ENCODING_NONE
);
29161 ret
= xmlSchemaValidateStream(ctxt
, input
, XML_CHAR_ENCODING_NONE
,
29167 * xmlSchemaValidCtxtGetParserCtxt:
29168 * @ctxt: a schema validation context
29170 * allow access to the parser context of the schema validation context
29172 * Returns the parser context of the schema validation context or NULL
29173 * in case of error.
29176 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt
)
29180 return (ctxt
->parserCtxt
);
29183 #endif /* LIBXML_SCHEMAS_ENABLED */