2
* schemas.c : implementation of the XML Schema handling and
3
* schema validity checking
5
* See Copyright for the status of this software.
7
* Daniel Veillard <veillard@redhat.com>
12
* - when types are redefined in includes, check that all
13
* types in the redef list are equal
14
* -> need a type equality operation.
15
* - if we don't intend to use the schema for schemas, we
16
* need to validate all schema attributes (ref, type, name)
17
* against their types.
18
* - Eliminate item creation for: ??
21
* - For xsi-driven schema acquisition, augment the IDCs after every
22
* acquisition episode (xmlSchemaAugmentIDC).
25
* - Elimated item creation for: <restriction>, <extension>,
26
* <simpleContent>, <complexContent>, <list>, <union>
29
* - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
30
* IDC XPath expression and chameleon includes: the targetNamespace is changed, so
31
* XPath will have trouble to resolve to this namespace, since not known.
36
* Schema Component Constraint:
37
* All Group Limited (cos-all-limited)
40
* In xmlSchemaGroupDefReferenceTermFixup() and
42
* In xmlSchemaParseModelGroup()
43
* TODO: Actually this should go to component-level checks,
44
* but is done here due to performance. Move it to an other layer
45
* is schema construction via an API is implemented.
50
#ifdef LIBXML_SCHEMAS_ENABLED
53
#include <libxml/xmlmemory.h>
54
#include <libxml/parser.h>
55
#include <libxml/parserInternals.h>
56
#include <libxml/hash.h>
57
#include <libxml/uri.h>
58
#include <libxml/xmlschemas.h>
59
#include <libxml/schemasInternals.h>
60
#include <libxml/xmlschemastypes.h>
61
#include <libxml/xmlautomata.h>
62
#include <libxml/xmlregexp.h>
63
#include <libxml/dict.h>
64
#include <libxml/encoding.h>
65
#include <libxml/xmlIO.h>
66
#ifdef LIBXML_PATTERN_ENABLED
67
#include <libxml/pattern.h>
69
#ifdef LIBXML_READER_ENABLED
70
#include <libxml/xmlreader.h>
75
/* #define DEBUG_CONTENT 1 */
77
/* #define DEBUG_TYPE 1 */
79
/* #define DEBUG_CONTENT_REGEXP 1 */
81
/* #define DEBUG_AUTOMATA 1 */
83
/* #define DEBUG_IDC */
85
/* #define DEBUG_IDC_NODE_TABLE */
87
/* #define WXS_ELEM_DECL_CONS_ENABLED */
90
#ifndef DEBUG_IDC_NODE_TABLE
91
#define DEBUG_IDC_NODE_TABLE
95
/* #define ENABLE_PARTICLE_RESTRICTION 1 */
97
#define ENABLE_REDEFINE
99
/* #define ENABLE_NAMED_LOCALS */
101
/* #define ENABLE_IDC_NODE_TABLES_TEST */
103
#define DUMP_CONTENT_MODEL
105
#ifdef LIBXML_READER_ENABLED
106
/* #define XML_SCHEMA_READER_ENABLED */
109
#define UNBOUNDED (1 << 30)
111
xmlGenericError(xmlGenericErrorContext, \
112
"Unimplemented block at %s:%d\n", \
115
#define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
118
* The XML Schemas namespaces
120
static const xmlChar *xmlSchemaNs = (const xmlChar *)
121
"http://www.w3.org/2001/XMLSchema";
123
static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
124
"http://www.w3.org/2001/XMLSchema-instance";
126
static const xmlChar *xmlNamespaceNs = (const xmlChar *)
127
"http://www.w3.org/2000/xmlns/";
130
* Come casting macros.
132
#define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
133
#define PCTXT_CAST (xmlSchemaParserCtxtPtr)
134
#define VCTXT_CAST (xmlSchemaValidCtxtPtr)
135
#define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
136
#define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
137
#define WXS_PTC_CAST (xmlSchemaParticlePtr)
138
#define WXS_TYPE_CAST (xmlSchemaTypePtr)
139
#define WXS_ELEM_CAST (xmlSchemaElementPtr)
140
#define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
141
#define WXS_ATTR_CAST (xmlSchemaAttributePtr)
142
#define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
143
#define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
144
#define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
145
#define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
146
#define WXS_IDC_CAST (xmlSchemaIDCPtr)
147
#define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
148
#define WXS_LIST_CAST (xmlSchemaItemListPtr)
151
* Macros to query common properties of components.
153
#define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
155
#define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
157
* Macros for element declarations.
159
#define WXS_ELEM_TYPEDEF(e) (e)->subtypes
161
#define WXS_SUBST_HEAD(item) (item)->refDecl
163
* Macros for attribute declarations.
165
#define WXS_ATTR_TYPEDEF(a) (a)->subtypes
167
* Macros for attribute uses.
169
#define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl
171
#define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
173
#define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
175
#define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
177
* Macros for attribute groups.
179
#define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
180
#define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
182
* Macros for particles.
184
#define WXS_PARTICLE(p) WXS_PTC_CAST (p)
186
#define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
188
#define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
190
#define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
192
* Macros for model groups definitions.
194
#define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
196
* Macros for model groups.
198
#define WXS_IS_MODEL_GROUP(i) \
199
(((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
200
((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
201
((i)->type == XML_SCHEMA_TYPE_ALL))
203
#define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
205
* Macros for schema buckets.
207
#define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
208
((t) == XML_SCHEMA_SCHEMA_REDEFINE))
210
#define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
211
((t) == XML_SCHEMA_SCHEMA_IMPORT))
213
#define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
215
#define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
217
* Macros for complex/simple types.
219
#define WXS_IS_ANYTYPE(i) \
220
(( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
221
( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
223
#define WXS_IS_COMPLEX(i) \
224
(((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
225
((i)->builtInType == XML_SCHEMAS_ANYTYPE))
227
#define WXS_IS_SIMPLE(item) \
228
((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
229
((item->type == XML_SCHEMA_TYPE_BASIC) && \
230
(item->builtInType != XML_SCHEMAS_ANYTYPE)))
232
#define WXS_IS_ANY_SIMPLE_TYPE(i) \
233
(((i)->type == XML_SCHEMA_TYPE_BASIC) && \
234
((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
236
#define WXS_IS_RESTRICTION(t) \
237
((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
239
#define WXS_IS_EXTENSION(t) \
240
((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
242
#define WXS_IS_TYPE_NOT_FIXED(i) \
243
(((i)->type != XML_SCHEMA_TYPE_BASIC) && \
244
(((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
246
#define WXS_IS_TYPE_NOT_FIXED_1(item) \
247
(((item)->type != XML_SCHEMA_TYPE_BASIC) && \
248
(((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
250
#define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
252
#define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
254
* Macros for exclusively for complex types.
256
#define WXS_HAS_COMPLEX_CONTENT(item) \
257
((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
258
(item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
259
(item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
261
#define WXS_HAS_SIMPLE_CONTENT(item) \
262
((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
263
(item->contentType == XML_SCHEMA_CONTENT_BASIC))
265
#define WXS_HAS_MIXED_CONTENT(item) \
266
(item->contentType == XML_SCHEMA_CONTENT_MIXED)
268
#define WXS_EMPTIABLE(t) \
269
(xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
271
#define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
273
#define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
275
#define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
277
* Macros for exclusively for simple types.
279
#define WXS_LIST_ITEMTYPE(t) (t)->subtypes
281
#define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
283
#define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
285
#define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
287
* Misc parser context macros.
289
#define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
291
#define WXS_HAS_BUCKETS(ctx) \
292
( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
293
(WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
295
#define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
297
#define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
299
#define WXS_SCHEMA(ctx) (ctx)->schema
301
#define WXS_ADD_LOCAL(ctx, item) \
302
xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
304
#define WXS_ADD_GLOBAL(ctx, item) \
305
xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
307
#define WXS_ADD_PENDING(ctx, item) \
308
xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
310
* xmlSchemaItemList macros.
312
#define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
316
#define IS_SCHEMA(node, type) \
317
((node != NULL) && (node->ns != NULL) && \
318
(xmlStrEqual(node->name, (const xmlChar *) type)) && \
319
(xmlStrEqual(node->ns->href, xmlSchemaNs)))
321
#define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
324
* Since we put the default/fixed values into the dict, we can
325
* use pointer comparison for those values.
326
* REMOVED: (xmlStrEqual((v1), (v2)))
328
#define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
330
#define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
332
#define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
334
#define HFAILURE if (res == -1) goto exit_failure;
336
#define HERROR if (res != 0) goto exit_error;
338
#define HSTOP(ctx) if ((ctx)->stop) goto exit;
340
* Some flags used for various schema constraints.
342
#define SUBSET_RESTRICTION 1<<0
343
#define SUBSET_EXTENSION 1<<1
344
#define SUBSET_SUBSTITUTION 1<<2
345
#define SUBSET_LIST 1<<3
346
#define SUBSET_UNION 1<<4
348
typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
349
typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
351
typedef struct _xmlSchemaItemList xmlSchemaItemList;
352
typedef xmlSchemaItemList *xmlSchemaItemListPtr;
353
struct _xmlSchemaItemList {
354
void **items; /* used for dynamic addition of schemata */
355
int nbItems; /* used for dynamic addition of schemata */
356
int sizeItems; /* used for dynamic addition of schemata */
359
#define XML_SCHEMA_CTXT_PARSER 1
360
#define XML_SCHEMA_CTXT_VALIDATOR 2
362
typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
363
typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
364
struct _xmlSchemaAbstractCtxt {
365
int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
368
typedef struct _xmlSchemaBucket xmlSchemaBucket;
369
typedef xmlSchemaBucket *xmlSchemaBucketPtr;
371
#define XML_SCHEMA_SCHEMA_MAIN 0
372
#define XML_SCHEMA_SCHEMA_IMPORT 1
373
#define XML_SCHEMA_SCHEMA_INCLUDE 2
374
#define XML_SCHEMA_SCHEMA_REDEFINE 3
377
* xmlSchemaSchemaRelation:
379
* Used to create a graph of schema relationships.
381
typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
382
typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
383
struct _xmlSchemaSchemaRelation {
384
xmlSchemaSchemaRelationPtr next;
385
int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
386
const xmlChar *importNamespace;
387
xmlSchemaBucketPtr bucket;
390
#define XML_SCHEMA_BUCKET_MARKED 1<<0
391
#define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
393
struct _xmlSchemaBucket {
396
const xmlChar *schemaLocation;
397
const xmlChar *origTargetNamespace;
398
const xmlChar *targetNamespace;
400
xmlSchemaSchemaRelationPtr relations;
405
xmlSchemaItemListPtr globals; /* Global components. */
406
xmlSchemaItemListPtr locals; /* Local components. */
411
* (extends xmlSchemaBucket)
413
* Reflects a schema. Holds some information
414
* about the schema and its toplevel components. Duplicate
415
* toplevel components are not checked at this level.
417
typedef struct _xmlSchemaImport xmlSchemaImport;
418
typedef xmlSchemaImport *xmlSchemaImportPtr;
419
struct _xmlSchemaImport {
420
int type; /* Main OR import OR include. */
422
const xmlChar *schemaLocation; /* The URI of the schema document. */
423
/* For chameleon includes, @origTargetNamespace will be NULL */
424
const xmlChar *origTargetNamespace;
426
* For chameleon includes, @targetNamespace will be the
427
* targetNamespace of the including schema.
429
const xmlChar *targetNamespace;
430
xmlDocPtr doc; /* The schema node-tree. */
431
/* @relations will hold any included/imported/redefined schemas. */
432
xmlSchemaSchemaRelationPtr relations;
437
xmlSchemaItemListPtr globals;
438
xmlSchemaItemListPtr locals;
439
/* The imported schema. */
444
* (extends xmlSchemaBucket)
446
typedef struct _xmlSchemaInclude xmlSchemaInclude;
447
typedef xmlSchemaInclude *xmlSchemaIncludePtr;
448
struct _xmlSchemaInclude {
451
const xmlChar *schemaLocation;
452
const xmlChar *origTargetNamespace;
453
const xmlChar *targetNamespace;
455
xmlSchemaSchemaRelationPtr relations;
460
xmlSchemaItemListPtr globals; /* Global components. */
461
xmlSchemaItemListPtr locals; /* Local components. */
463
/* The owning main or import schema bucket. */
464
xmlSchemaImportPtr ownerImport;
468
* xmlSchemaBasicItem:
470
* The abstract base type for schema components.
472
typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
473
typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
474
struct _xmlSchemaBasicItem {
475
xmlSchemaTypeType type;
479
* xmlSchemaAnnotItem:
481
* The abstract base type for annotated schema components.
482
* (Extends xmlSchemaBasicItem)
484
typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
485
typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
486
struct _xmlSchemaAnnotItem {
487
xmlSchemaTypeType type;
488
xmlSchemaAnnotPtr annot;
494
* The abstract base type for tree-like structured schema components.
495
* (Extends xmlSchemaAnnotItem)
497
typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
498
typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
499
struct _xmlSchemaTreeItem {
500
xmlSchemaTypeType type;
501
xmlSchemaAnnotPtr annot;
502
xmlSchemaTreeItemPtr next;
503
xmlSchemaTreeItemPtr children;
507
#define XML_SCHEMA_ATTR_USE_FIXED 1<<0
509
* xmlSchemaAttributeUsePtr:
511
* The abstract base type for tree-like structured schema components.
512
* (Extends xmlSchemaTreeItem)
514
typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
515
typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
516
struct _xmlSchemaAttributeUse {
517
xmlSchemaTypeType type;
518
xmlSchemaAnnotPtr annot;
519
xmlSchemaAttributeUsePtr next; /* The next attr. use. */
521
* The attr. decl. OR a QName-ref. to an attr. decl. OR
522
* a QName-ref. to an attribute group definition.
524
xmlSchemaAttributePtr attrDecl;
528
int occurs; /* required, optional */
529
const xmlChar * defValue;
530
xmlSchemaValPtr defVal;
534
* xmlSchemaAttributeUseProhibPtr:
536
* A helper component to reflect attribute prohibitions.
537
* (Extends xmlSchemaBasicItem)
539
typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
540
typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
541
struct _xmlSchemaAttributeUseProhib {
542
xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
545
const xmlChar *targetNamespace;
552
typedef struct _xmlSchemaRedef xmlSchemaRedef;
553
typedef xmlSchemaRedef *xmlSchemaRedefPtr;
554
struct _xmlSchemaRedef {
555
xmlSchemaRedefPtr next;
556
xmlSchemaBasicItemPtr item; /* The redefining component. */
557
xmlSchemaBasicItemPtr reference; /* The referencing component. */
558
xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
559
const xmlChar *refName; /* The name of the to-be-redefined component. */
560
const xmlChar *refTargetNs; /* The target namespace of the
561
to-be-redefined comp. */
562
xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
566
* xmlSchemaConstructionCtxt:
568
typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
569
typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
570
struct _xmlSchemaConstructionCtxt {
571
xmlSchemaPtr mainSchema; /* The main schema. */
572
xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
574
xmlSchemaItemListPtr buckets; /* List of schema buckets. */
575
/* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
576
xmlSchemaBucketPtr bucket; /* The current schema bucket */
577
xmlSchemaItemListPtr pending; /* All Components of all schemas that
579
xmlHashTablePtr substGroups;
580
xmlSchemaRedefPtr redefs;
581
xmlSchemaRedefPtr lastRedef;
584
#define XML_SCHEMAS_PARSE_ERROR 1
585
#define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
587
struct _xmlSchemaParserCtxt {
589
void *errCtxt; /* user specific error context */
590
xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
591
xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
594
xmlStructuredErrorFunc serror;
596
xmlSchemaConstructionCtxtPtr constructor;
597
int ownsConstructor; /* TODO: Move this to parser *flags*. */
599
/* xmlSchemaPtr topschema; */
600
/* xmlHashTablePtr namespaces; */
602
xmlSchemaPtr schema; /* The main schema in use */
607
int preserve; /* Whether the doc should be freed */
613
* Used to build complex element content models
616
xmlAutomataStatePtr start;
617
xmlAutomataStatePtr end;
618
xmlAutomataStatePtr state;
620
xmlDictPtr dict; /* dictionnary for interned string names */
621
xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
623
xmlSchemaValidCtxtPtr vctxt;
627
int stop; /* If the parser should stop; i.e. a critical error. */
628
const xmlChar *targetNamespace;
629
xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
631
xmlSchemaRedefPtr redef; /* Used for redefinitions. */
632
int redefCounter; /* Used for redefinitions. */
633
xmlSchemaItemListPtr attrProhibs;
639
* A component reference item (not a schema component)
640
* (Extends xmlSchemaBasicItem)
642
typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
643
typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
644
struct _xmlSchemaQNameRef {
645
xmlSchemaTypeType type;
646
xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
647
xmlSchemaTypeType itemType;
649
const xmlChar *targetNamespace;
656
* A particle component.
657
* (Extends xmlSchemaTreeItem)
659
typedef struct _xmlSchemaParticle xmlSchemaParticle;
660
typedef xmlSchemaParticle *xmlSchemaParticlePtr;
661
struct _xmlSchemaParticle {
662
xmlSchemaTypeType type;
663
xmlSchemaAnnotPtr annot;
664
xmlSchemaTreeItemPtr next; /* next particle */
665
xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
666
a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
674
* xmlSchemaModelGroup:
676
* A model group component.
677
* (Extends xmlSchemaTreeItem)
679
typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
680
typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
681
struct _xmlSchemaModelGroup {
682
xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
683
xmlSchemaAnnotPtr annot;
684
xmlSchemaTreeItemPtr next; /* not used */
685
xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
689
#define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
690
#define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
692
* xmlSchemaModelGroupDef:
694
* A model group definition component.
695
* (Extends xmlSchemaTreeItem)
697
typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
698
typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
699
struct _xmlSchemaModelGroupDef {
700
xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
701
xmlSchemaAnnotPtr annot;
702
xmlSchemaTreeItemPtr next; /* not used */
703
xmlSchemaTreeItemPtr children; /* the "model group" */
705
const xmlChar *targetNamespace;
710
typedef struct _xmlSchemaIDC xmlSchemaIDC;
711
typedef xmlSchemaIDC *xmlSchemaIDCPtr;
714
* xmlSchemaIDCSelect:
716
* The identity-constraint "field" and "selector" item, holding the
719
typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
720
typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
721
struct _xmlSchemaIDCSelect {
722
xmlSchemaIDCSelectPtr next;
724
int index; /* an index position if significant for IDC key-sequences */
725
const xmlChar *xpath; /* the XPath expression */
726
void *xpathComp; /* the compiled XPath expression */
732
* The identity-constraint definition component.
733
* (Extends xmlSchemaAnnotItem)
736
struct _xmlSchemaIDC {
737
xmlSchemaTypeType type;
738
xmlSchemaAnnotPtr annot;
739
xmlSchemaIDCPtr next;
742
const xmlChar *targetNamespace;
743
xmlSchemaIDCSelectPtr selector;
744
xmlSchemaIDCSelectPtr fields;
746
xmlSchemaQNameRefPtr ref;
752
* The augmented IDC information used for validation.
754
typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
755
typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
756
struct _xmlSchemaIDCAug {
757
xmlSchemaIDCAugPtr next; /* next in a list */
758
xmlSchemaIDCPtr def; /* the IDC definition */
759
int keyrefDepth; /* the lowest tree level to which IDC
760
tables need to be bubbled upwards */
764
* xmlSchemaPSVIIDCKeySequence:
766
* The key sequence of a node table item.
768
typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
769
typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
770
struct _xmlSchemaPSVIIDCKey {
771
xmlSchemaTypePtr type;
776
* xmlSchemaPSVIIDCNode:
778
* The node table item of a node table.
780
typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
781
typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
782
struct _xmlSchemaPSVIIDCNode {
784
xmlSchemaPSVIIDCKeyPtr *keys;
791
* xmlSchemaPSVIIDCBinding:
793
* The identity-constraint binding item of the [identity-constraint table].
795
typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
796
typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
797
struct _xmlSchemaPSVIIDCBinding {
798
xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
799
xmlSchemaIDCPtr definition; /* the IDC definition */
800
xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
801
int nbNodes; /* number of entries in the node table */
802
int sizeNodes; /* size of the node table */
803
xmlSchemaItemListPtr dupls;
807
#define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
808
#define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
810
#define XPATH_STATE_OBJ_MATCHES -2
811
#define XPATH_STATE_OBJ_BLOCKED -3
813
typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
814
typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
817
* xmlSchemaIDCStateObj:
819
* The state object used to evaluate XPath expressions.
821
typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
822
typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
823
struct _xmlSchemaIDCStateObj {
825
xmlSchemaIDCStateObjPtr next; /* next if in a list */
826
int depth; /* depth of creation */
827
int *history; /* list of (depth, state-id) tuples */
830
xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
832
xmlSchemaIDCSelectPtr sel;
836
#define IDC_MATCHER 0
839
* xmlSchemaIDCMatcher:
841
* Used to evaluate IDC selectors (and fields).
843
struct _xmlSchemaIDCMatcher {
845
int depth; /* the tree depth at creation time */
846
xmlSchemaIDCMatcherPtr next; /* next in the list */
847
xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
848
xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
850
xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
853
xmlSchemaItemListPtr targets; /* list of target-node
854
(xmlSchemaPSVIIDCNodePtr) entries */
858
* Element info flags.
860
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0
861
#define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
862
#define XML_SCHEMA_ELEM_INFO_NILLED 1<<2
863
#define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3
865
#define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4
866
#define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5
867
#define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6
869
#define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7
870
#define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8
871
#define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9
872
#define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10
877
* Holds information of an element node.
879
struct _xmlSchemaNodeInfo {
883
const xmlChar *localName;
884
const xmlChar *nsName;
885
const xmlChar *value;
886
xmlSchemaValPtr val; /* the pre-computed value if any */
887
xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
889
int flags; /* combination of node info flags */
894
xmlSchemaElementPtr decl; /* the element/attribute declaration */
896
xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
897
for the scope element*/
898
xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
900
xmlRegExecCtxtPtr regexCtxt;
902
const xmlChar **nsBindings; /* Namespace bindings on this element */
907
int appliedXPath; /* Indicates that an XPath has been applied. */
910
#define XML_SCHEMAS_ATTR_UNKNOWN 1
911
#define XML_SCHEMAS_ATTR_ASSESSED 2
912
#define XML_SCHEMAS_ATTR_PROHIBITED 3
913
#define XML_SCHEMAS_ATTR_ERR_MISSING 4
914
#define XML_SCHEMAS_ATTR_INVALID_VALUE 5
915
#define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
916
#define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
917
#define XML_SCHEMAS_ATTR_DEFAULT 8
918
#define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
919
#define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
920
#define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
921
#define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
922
#define XML_SCHEMAS_ATTR_WILD_SKIP 13
923
#define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
924
#define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
925
#define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
926
#define XML_SCHEMAS_ATTR_META 17
928
* @metaType values of xmlSchemaAttrInfo.
930
#define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
931
#define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
932
#define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
933
#define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
934
#define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
936
typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
937
typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
938
struct _xmlSchemaAttrInfo {
942
const xmlChar *localName;
943
const xmlChar *nsName;
944
const xmlChar *value;
945
xmlSchemaValPtr val; /* the pre-computed value if any */
946
xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
947
int flags; /* combination of node info flags */
949
xmlSchemaAttributePtr decl; /* the attribute declaration */
950
xmlSchemaAttributeUsePtr use; /* the attribute use */
953
const xmlChar *vcValue; /* the value constraint value */
954
xmlSchemaNodeInfoPtr parent;
958
#define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
960
* xmlSchemaValidCtxt:
962
* A Schemas validation context
964
struct _xmlSchemaValidCtxt {
966
void *errCtxt; /* user specific data block */
967
xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
968
xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
969
xmlStructuredErrorFunc serror;
971
xmlSchemaPtr schema; /* The schema in use */
973
xmlParserInputBufferPtr input;
975
xmlSAXHandlerPtr sax;
976
xmlParserCtxtPtr parserCtxt;
977
void *user_data; /* TODO: What is this for? */
984
/* xmlSchemaTypePtr type; */
986
xmlRegExecCtxtPtr regexp;
987
xmlSchemaValPtr value;
991
xmlNodePtr validationRoot;
992
xmlSchemaParserCtxtPtr pctxt;
996
xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
998
xmlSchemaNodeInfoPtr inode; /* the current element information */
1000
xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
1002
xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
1003
xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
1004
xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
1006
xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
1010
xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
1018
#ifdef LIBXML_READER_ENABLED
1019
xmlTextReaderPtr reader;
1022
xmlSchemaAttrInfoPtr *attrInfos;
1027
xmlSchemaItemListPtr nodeQNames;
1029
int createIDCNodeTables;
1030
int psviExposeIDCNodeTables;
1034
* xmlSchemaSubstGroup:
1038
typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
1039
typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
1040
struct _xmlSchemaSubstGroup {
1041
xmlSchemaElementPtr head;
1042
xmlSchemaItemListPtr members;
1045
/************************************************************************
1047
* Some predeclarations *
1049
************************************************************************/
1051
static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
1052
xmlSchemaPtr schema,
1054
static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
1055
xmlSchemaPtr schema,
1058
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
1059
xmlSchemaAbstractCtxtPtr ctxt);
1060
static const xmlChar *
1061
xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
1063
xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1066
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
1067
xmlSchemaParserCtxtPtr ctxt);
1069
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
1070
static xmlSchemaWhitespaceValueType
1071
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
1072
static xmlSchemaTreeItemPtr
1073
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
1074
xmlNodePtr node, xmlSchemaTypeType type,
1076
static const xmlChar *
1077
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
1078
static xmlSchemaTypeLinkPtr
1079
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
1081
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
1082
const char *funcName,
1083
const char *message);
1085
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
1086
xmlSchemaTypePtr type,
1087
xmlSchemaTypePtr baseType,
1090
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
1091
xmlSchemaParserCtxtPtr ctxt);
1093
xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
1094
static xmlSchemaQNameRefPtr
1095
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
1096
xmlSchemaPtr schema,
1099
/************************************************************************
1101
* Helper functions *
1103
************************************************************************/
1106
* xmlSchemaItemTypeToStr:
1107
* @type: the type of the schema item
1109
* Returns the component name of a schema item.
1111
static const xmlChar *
1112
xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
1115
case XML_SCHEMA_TYPE_BASIC:
1116
return(BAD_CAST "simple type definition");
1117
case XML_SCHEMA_TYPE_SIMPLE:
1118
return(BAD_CAST "simple type definition");
1119
case XML_SCHEMA_TYPE_COMPLEX:
1120
return(BAD_CAST "complex type definition");
1121
case XML_SCHEMA_TYPE_ELEMENT:
1122
return(BAD_CAST "element declaration");
1123
case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1124
return(BAD_CAST "attribute use");
1125
case XML_SCHEMA_TYPE_ATTRIBUTE:
1126
return(BAD_CAST "attribute declaration");
1127
case XML_SCHEMA_TYPE_GROUP:
1128
return(BAD_CAST "model group definition");
1129
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1130
return(BAD_CAST "attribute group definition");
1131
case XML_SCHEMA_TYPE_NOTATION:
1132
return(BAD_CAST "notation declaration");
1133
case XML_SCHEMA_TYPE_SEQUENCE:
1134
return(BAD_CAST "model group (sequence)");
1135
case XML_SCHEMA_TYPE_CHOICE:
1136
return(BAD_CAST "model group (choice)");
1137
case XML_SCHEMA_TYPE_ALL:
1138
return(BAD_CAST "model group (all)");
1139
case XML_SCHEMA_TYPE_PARTICLE:
1140
return(BAD_CAST "particle");
1141
case XML_SCHEMA_TYPE_IDC_UNIQUE:
1142
return(BAD_CAST "unique identity-constraint");
1143
/* return(BAD_CAST "IDC (unique)"); */
1144
case XML_SCHEMA_TYPE_IDC_KEY:
1145
return(BAD_CAST "key identity-constraint");
1146
/* return(BAD_CAST "IDC (key)"); */
1147
case XML_SCHEMA_TYPE_IDC_KEYREF:
1148
return(BAD_CAST "keyref identity-constraint");
1149
/* return(BAD_CAST "IDC (keyref)"); */
1150
case XML_SCHEMA_TYPE_ANY:
1151
return(BAD_CAST "wildcard (any)");
1152
case XML_SCHEMA_EXTRA_QNAMEREF:
1153
return(BAD_CAST "[helper component] QName reference");
1154
case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
1155
return(BAD_CAST "[helper component] attribute use prohibition");
1157
return(BAD_CAST "Not a schema component");
1162
* xmlSchemaGetComponentTypeStr:
1163
* @type: the type of the schema item
1165
* Returns the component name of a schema item.
1167
static const xmlChar *
1168
xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
1170
switch (item->type) {
1171
case XML_SCHEMA_TYPE_BASIC:
1172
if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
1173
return(BAD_CAST "complex type definition");
1175
return(BAD_CAST "simple type definition");
1177
return(xmlSchemaItemTypeToStr(item->type));
1182
* xmlSchemaGetComponentNode:
1183
* @item: a schema component
1185
* Returns node associated with the schema component.
1186
* NOTE that such a node need not be available; plus, a component's
1187
* node need not to reflect the component directly, since there is no
1188
* one-to-one relationship between the XML Schema representation and
1189
* the component representation.
1192
xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
1194
switch (item->type) {
1195
case XML_SCHEMA_TYPE_ELEMENT:
1196
return (((xmlSchemaElementPtr) item)->node);
1197
case XML_SCHEMA_TYPE_ATTRIBUTE:
1198
return (((xmlSchemaAttributePtr) item)->node);
1199
case XML_SCHEMA_TYPE_COMPLEX:
1200
case XML_SCHEMA_TYPE_SIMPLE:
1201
return (((xmlSchemaTypePtr) item)->node);
1202
case XML_SCHEMA_TYPE_ANY:
1203
case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1204
return (((xmlSchemaWildcardPtr) item)->node);
1205
case XML_SCHEMA_TYPE_PARTICLE:
1206
return (((xmlSchemaParticlePtr) item)->node);
1207
case XML_SCHEMA_TYPE_SEQUENCE:
1208
case XML_SCHEMA_TYPE_CHOICE:
1209
case XML_SCHEMA_TYPE_ALL:
1210
return (((xmlSchemaModelGroupPtr) item)->node);
1211
case XML_SCHEMA_TYPE_GROUP:
1212
return (((xmlSchemaModelGroupDefPtr) item)->node);
1213
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1214
return (((xmlSchemaAttributeGroupPtr) item)->node);
1215
case XML_SCHEMA_TYPE_IDC_UNIQUE:
1216
case XML_SCHEMA_TYPE_IDC_KEY:
1217
case XML_SCHEMA_TYPE_IDC_KEYREF:
1218
return (((xmlSchemaIDCPtr) item)->node);
1219
case XML_SCHEMA_EXTRA_QNAMEREF:
1220
return(((xmlSchemaQNameRefPtr) item)->node);
1221
/* TODO: What to do with NOTATIONs?
1222
case XML_SCHEMA_TYPE_NOTATION:
1223
return (((xmlSchemaNotationPtr) item)->node);
1225
case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1226
return (((xmlSchemaAttributeUsePtr) item)->node);
1234
* xmlSchemaGetNextComponent:
1235
* @item: a schema component
1237
* Returns the next sibling of the schema component.
1239
static xmlSchemaBasicItemPtr
1240
xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
1242
switch (item->type) {
1243
case XML_SCHEMA_TYPE_ELEMENT:
1244
return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
1245
case XML_SCHEMA_TYPE_ATTRIBUTE:
1246
return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
1247
case XML_SCHEMA_TYPE_COMPLEX:
1248
case XML_SCHEMA_TYPE_SIMPLE:
1249
return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
1250
case XML_SCHEMA_TYPE_ANY:
1251
case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1253
case XML_SCHEMA_TYPE_PARTICLE:
1254
return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
1255
case XML_SCHEMA_TYPE_SEQUENCE:
1256
case XML_SCHEMA_TYPE_CHOICE:
1257
case XML_SCHEMA_TYPE_ALL:
1259
case XML_SCHEMA_TYPE_GROUP:
1261
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1262
return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
1263
case XML_SCHEMA_TYPE_IDC_UNIQUE:
1264
case XML_SCHEMA_TYPE_IDC_KEY:
1265
case XML_SCHEMA_TYPE_IDC_KEYREF:
1266
return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
1275
* xmlSchemaFormatQName:
1276
* @buf: the string buffer
1277
* @namespaceName: the namespace name
1278
* @localName: the local name
1280
* Returns the given QName in the format "{namespaceName}localName" or
1281
* just "localName" if @namespaceName is NULL.
1283
* Returns the localName if @namespaceName is NULL, a formatted
1286
static const xmlChar*
1287
xmlSchemaFormatQName(xmlChar **buf,
1288
const xmlChar *namespaceName,
1289
const xmlChar *localName)
1292
if (namespaceName != NULL) {
1293
*buf = xmlStrdup(BAD_CAST "{");
1294
*buf = xmlStrcat(*buf, namespaceName);
1295
*buf = xmlStrcat(*buf, BAD_CAST "}");
1297
if (localName != NULL) {
1298
if (namespaceName == NULL)
1300
*buf = xmlStrcat(*buf, localName);
1302
*buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
1304
return ((const xmlChar *) *buf);
1307
static const xmlChar*
1308
xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
1311
return (xmlSchemaFormatQName(buf, ns->href, localName));
1313
return (xmlSchemaFormatQName(buf, NULL, localName));
1316
static const xmlChar *
1317
xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
1319
switch (item->type) {
1320
case XML_SCHEMA_TYPE_ELEMENT:
1321
return (((xmlSchemaElementPtr) item)->name);
1322
case XML_SCHEMA_TYPE_ATTRIBUTE:
1323
return (((xmlSchemaAttributePtr) item)->name);
1324
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1325
return (((xmlSchemaAttributeGroupPtr) item)->name);
1326
case XML_SCHEMA_TYPE_BASIC:
1327
case XML_SCHEMA_TYPE_SIMPLE:
1328
case XML_SCHEMA_TYPE_COMPLEX:
1329
return (((xmlSchemaTypePtr) item)->name);
1330
case XML_SCHEMA_TYPE_GROUP:
1331
return (((xmlSchemaModelGroupDefPtr) item)->name);
1332
case XML_SCHEMA_TYPE_IDC_KEY:
1333
case XML_SCHEMA_TYPE_IDC_UNIQUE:
1334
case XML_SCHEMA_TYPE_IDC_KEYREF:
1335
return (((xmlSchemaIDCPtr) item)->name);
1336
case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1337
if (WXS_ATTRUSE_DECL(item) != NULL) {
1338
return(xmlSchemaGetComponentName(
1339
WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1342
case XML_SCHEMA_EXTRA_QNAMEREF:
1343
return (((xmlSchemaQNameRefPtr) item)->name);
1344
case XML_SCHEMA_TYPE_NOTATION:
1345
return (((xmlSchemaNotationPtr) item)->name);
1348
* Other components cannot have names.
1355
#define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
1356
#define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
1358
static const xmlChar *
1359
xmlSchemaGetQNameRefName(void *ref)
1361
return(((xmlSchemaQNameRefPtr) ref)->name);
1364
static const xmlChar *
1365
xmlSchemaGetQNameRefTargetNs(void *ref)
1367
return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
1371
static const xmlChar *
1372
xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
1374
switch (item->type) {
1375
case XML_SCHEMA_TYPE_ELEMENT:
1376
return (((xmlSchemaElementPtr) item)->targetNamespace);
1377
case XML_SCHEMA_TYPE_ATTRIBUTE:
1378
return (((xmlSchemaAttributePtr) item)->targetNamespace);
1379
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1380
return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
1381
case XML_SCHEMA_TYPE_BASIC:
1382
return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
1383
case XML_SCHEMA_TYPE_SIMPLE:
1384
case XML_SCHEMA_TYPE_COMPLEX:
1385
return (((xmlSchemaTypePtr) item)->targetNamespace);
1386
case XML_SCHEMA_TYPE_GROUP:
1387
return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
1388
case XML_SCHEMA_TYPE_IDC_KEY:
1389
case XML_SCHEMA_TYPE_IDC_UNIQUE:
1390
case XML_SCHEMA_TYPE_IDC_KEYREF:
1391
return (((xmlSchemaIDCPtr) item)->targetNamespace);
1392
case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
1393
if (WXS_ATTRUSE_DECL(item) != NULL) {
1394
return(xmlSchemaGetComponentTargetNs(
1395
WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
1397
/* TODO: Will returning NULL break something? */
1399
case XML_SCHEMA_EXTRA_QNAMEREF:
1400
return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
1401
case XML_SCHEMA_TYPE_NOTATION:
1402
return (((xmlSchemaNotationPtr) item)->targetNamespace);
1405
* Other components cannot have names.
1412
static const xmlChar*
1413
xmlSchemaGetComponentQName(xmlChar **buf,
1416
return (xmlSchemaFormatQName(buf,
1417
xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
1418
xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
1421
static const xmlChar*
1422
xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
1424
xmlChar *str = NULL;
1426
*buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
1427
*buf = xmlStrcat(*buf, BAD_CAST " '");
1428
*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
1429
(xmlSchemaBasicItemPtr) item));
1430
*buf = xmlStrcat(*buf, BAD_CAST "'");
1435
static const xmlChar*
1436
xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
1438
return(xmlSchemaGetComponentDesignation(buf, idc));
1442
* xmlSchemaWildcardPCToString:
1443
* @pc: the type of processContents
1445
* Returns a string representation of the type of
1448
static const xmlChar *
1449
xmlSchemaWildcardPCToString(int pc)
1452
case XML_SCHEMAS_ANY_SKIP:
1453
return (BAD_CAST "skip");
1454
case XML_SCHEMAS_ANY_LAX:
1455
return (BAD_CAST "lax");
1456
case XML_SCHEMAS_ANY_STRICT:
1457
return (BAD_CAST "strict");
1459
return (BAD_CAST "invalid process contents");
1464
* xmlSchemaGetCanonValueWhtspExt:
1465
* @val: the precomputed value
1466
* @retValue: the returned value
1467
* @ws: the whitespace type of the value
1469
* Get a the cononical representation of the value.
1470
* The caller has to free the returned retValue.
1472
* Returns 0 if the value could be built and -1 in case of
1473
* API errors or if the value type is not supported yet.
1476
xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
1477
xmlSchemaWhitespaceValueType ws,
1481
xmlSchemaValType valType;
1482
const xmlChar *value, *value2 = NULL;
1485
if ((retValue == NULL) || (val == NULL))
1487
list = xmlSchemaValueGetNext(val) ? 1 : 0;
1491
valType = xmlSchemaGetValType(val);
1493
case XML_SCHEMAS_STRING:
1494
case XML_SCHEMAS_NORMSTRING:
1495
case XML_SCHEMAS_ANYSIMPLETYPE:
1496
value = xmlSchemaValueGetAsString(val);
1497
if (value != NULL) {
1498
if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
1499
value2 = xmlSchemaCollapseString(value);
1500
else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
1501
value2 = xmlSchemaWhiteSpaceReplace(value);
1507
if (xmlSchemaGetCanonValue(val, &value2) == -1) {
1509
xmlFree((xmlChar *) value2);
1510
goto internal_error;
1514
if (*retValue == NULL)
1515
if (value == NULL) {
1517
*retValue = xmlStrdup(BAD_CAST "");
1519
*retValue = xmlStrdup(value);
1520
else if (value != NULL) {
1522
*retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
1523
*retValue = xmlStrcat((xmlChar *) *retValue, value);
1525
FREE_AND_NULL(value2)
1526
val = xmlSchemaValueGetNext(val);
1527
} while (val != NULL);
1531
if (*retValue != NULL)
1532
xmlFree((xmlChar *) (*retValue));
1534
xmlFree((xmlChar *) value2);
1539
* xmlSchemaFormatItemForReport:
1540
* @buf: the string buffer
1541
* @itemDes: the designation of the item
1542
* @itemName: the name of the item
1543
* @item: the item as an object
1544
* @itemNode: the node of the item
1545
* @local: the local name
1546
* @parsing: if the function is used during the parse
1548
* Returns a representation of the given item used
1549
* for error reports.
1551
* The following order is used to build the resulting
1552
* designation if the arguments are not NULL:
1553
* 1a. If itemDes not NULL -> itemDes
1554
* 1b. If (itemDes not NULL) and (itemName not NULL)
1555
* -> itemDes + itemName
1556
* 2. If the preceding was NULL and (item not NULL) -> item
1557
* 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
1559
* If the itemNode is an attribute node, the name of the attribute
1560
* will be appended to the result.
1562
* Returns the formatted string and sets @buf to the resulting value.
1565
xmlSchemaFormatItemForReport(xmlChar **buf,
1566
const xmlChar *itemDes,
1567
xmlSchemaBasicItemPtr item,
1568
xmlNodePtr itemNode)
1570
xmlChar *str = NULL;
1578
if (itemDes != NULL) {
1579
*buf = xmlStrdup(itemDes);
1580
} else if (item != NULL) {
1581
switch (item->type) {
1582
case XML_SCHEMA_TYPE_BASIC: {
1583
xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1585
if (WXS_IS_ATOMIC(type))
1586
*buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
1587
else if (WXS_IS_LIST(type))
1588
*buf = xmlStrdup(BAD_CAST "list type 'xs:");
1589
else if (WXS_IS_UNION(type))
1590
*buf = xmlStrdup(BAD_CAST "union type 'xs:");
1592
*buf = xmlStrdup(BAD_CAST "simple type 'xs:");
1593
*buf = xmlStrcat(*buf, type->name);
1594
*buf = xmlStrcat(*buf, BAD_CAST "'");
1597
case XML_SCHEMA_TYPE_SIMPLE: {
1598
xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1600
if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1601
*buf = xmlStrdup(BAD_CAST"");
1603
*buf = xmlStrdup(BAD_CAST "local ");
1605
if (WXS_IS_ATOMIC(type))
1606
*buf = xmlStrcat(*buf, BAD_CAST "atomic type");
1607
else if (WXS_IS_LIST(type))
1608
*buf = xmlStrcat(*buf, BAD_CAST "list type");
1609
else if (WXS_IS_UNION(type))
1610
*buf = xmlStrcat(*buf, BAD_CAST "union type");
1612
*buf = xmlStrcat(*buf, BAD_CAST "simple type");
1613
if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1614
*buf = xmlStrcat(*buf, BAD_CAST " '");
1615
*buf = xmlStrcat(*buf, type->name);
1616
*buf = xmlStrcat(*buf, BAD_CAST "'");
1620
case XML_SCHEMA_TYPE_COMPLEX: {
1621
xmlSchemaTypePtr type = WXS_TYPE_CAST item;
1623
if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
1624
*buf = xmlStrdup(BAD_CAST "");
1626
*buf = xmlStrdup(BAD_CAST "local ");
1627
*buf = xmlStrcat(*buf, BAD_CAST "complex type");
1628
if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
1629
*buf = xmlStrcat(*buf, BAD_CAST " '");
1630
*buf = xmlStrcat(*buf, type->name);
1631
*buf = xmlStrcat(*buf, BAD_CAST "'");
1635
case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
1636
xmlSchemaAttributeUsePtr ause;
1638
ause = WXS_ATTR_USE_CAST item;
1639
*buf = xmlStrdup(BAD_CAST "attribute use ");
1640
if (WXS_ATTRUSE_DECL(ause) != NULL) {
1641
*buf = xmlStrcat(*buf, BAD_CAST "'");
1642
*buf = xmlStrcat(*buf,
1643
xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
1645
*buf = xmlStrcat(*buf, BAD_CAST "'");
1647
*buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
1651
case XML_SCHEMA_TYPE_ATTRIBUTE: {
1652
xmlSchemaAttributePtr attr;
1654
attr = (xmlSchemaAttributePtr) item;
1655
*buf = xmlStrdup(BAD_CAST "attribute decl.");
1656
*buf = xmlStrcat(*buf, BAD_CAST " '");
1657
*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1658
attr->targetNamespace, attr->name));
1660
*buf = xmlStrcat(*buf, BAD_CAST "'");
1663
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
1664
xmlSchemaGetComponentDesignation(buf, item);
1666
case XML_SCHEMA_TYPE_ELEMENT: {
1667
xmlSchemaElementPtr elem;
1669
elem = (xmlSchemaElementPtr) item;
1670
*buf = xmlStrdup(BAD_CAST "element decl.");
1671
*buf = xmlStrcat(*buf, BAD_CAST " '");
1672
*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1673
elem->targetNamespace, elem->name));
1674
*buf = xmlStrcat(*buf, BAD_CAST "'");
1677
case XML_SCHEMA_TYPE_IDC_UNIQUE:
1678
case XML_SCHEMA_TYPE_IDC_KEY:
1679
case XML_SCHEMA_TYPE_IDC_KEYREF:
1680
if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
1681
*buf = xmlStrdup(BAD_CAST "unique '");
1682
else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
1683
*buf = xmlStrdup(BAD_CAST "key '");
1685
*buf = xmlStrdup(BAD_CAST "keyRef '");
1686
*buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
1687
*buf = xmlStrcat(*buf, BAD_CAST "'");
1689
case XML_SCHEMA_TYPE_ANY:
1690
case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
1691
*buf = xmlStrdup(xmlSchemaWildcardPCToString(
1692
((xmlSchemaWildcardPtr) item)->processContents));
1693
*buf = xmlStrcat(*buf, BAD_CAST " wildcard");
1695
case XML_SCHEMA_FACET_MININCLUSIVE:
1696
case XML_SCHEMA_FACET_MINEXCLUSIVE:
1697
case XML_SCHEMA_FACET_MAXINCLUSIVE:
1698
case XML_SCHEMA_FACET_MAXEXCLUSIVE:
1699
case XML_SCHEMA_FACET_TOTALDIGITS:
1700
case XML_SCHEMA_FACET_FRACTIONDIGITS:
1701
case XML_SCHEMA_FACET_PATTERN:
1702
case XML_SCHEMA_FACET_ENUMERATION:
1703
case XML_SCHEMA_FACET_WHITESPACE:
1704
case XML_SCHEMA_FACET_LENGTH:
1705
case XML_SCHEMA_FACET_MAXLENGTH:
1706
case XML_SCHEMA_FACET_MINLENGTH:
1707
*buf = xmlStrdup(BAD_CAST "facet '");
1708
*buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
1709
*buf = xmlStrcat(*buf, BAD_CAST "'");
1711
case XML_SCHEMA_TYPE_GROUP: {
1712
*buf = xmlStrdup(BAD_CAST "model group def.");
1713
*buf = xmlStrcat(*buf, BAD_CAST " '");
1714
*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1715
*buf = xmlStrcat(*buf, BAD_CAST "'");
1719
case XML_SCHEMA_TYPE_SEQUENCE:
1720
case XML_SCHEMA_TYPE_CHOICE:
1721
case XML_SCHEMA_TYPE_ALL:
1722
case XML_SCHEMA_TYPE_PARTICLE:
1723
*buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1725
case XML_SCHEMA_TYPE_NOTATION: {
1726
*buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
1727
*buf = xmlStrcat(*buf, BAD_CAST " '");
1728
*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
1729
*buf = xmlStrcat(*buf, BAD_CAST "'");
1738
if ((named == 0) && (itemNode != NULL)) {
1741
if (itemNode->type == XML_ATTRIBUTE_NODE)
1742
elem = itemNode->parent;
1745
*buf = xmlStrdup(BAD_CAST "Element '");
1746
if (elem->ns != NULL) {
1747
*buf = xmlStrcat(*buf,
1748
xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
1751
*buf = xmlStrcat(*buf, elem->name);
1752
*buf = xmlStrcat(*buf, BAD_CAST "'");
1755
if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
1756
*buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
1757
if (itemNode->ns != NULL) {
1758
*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
1759
itemNode->ns->href, itemNode->name));
1762
*buf = xmlStrcat(*buf, itemNode->name);
1763
*buf = xmlStrcat(*buf, BAD_CAST "'");
1771
* xmlSchemaFormatFacetEnumSet:
1772
* @buf: the string buffer
1773
* @type: the type holding the enumeration facets
1775
* Builds a string consisting of all enumeration elements.
1777
* Returns a string of all enumeration elements.
1779
static const xmlChar *
1780
xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
1781
xmlChar **buf, xmlSchemaTypePtr type)
1783
xmlSchemaFacetPtr facet;
1784
xmlSchemaWhitespaceValueType ws;
1785
xmlChar *value = NULL;
1794
* Use the whitespace type of the base type.
1796
ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
1797
for (facet = type->facets; facet != NULL; facet = facet->next) {
1798
if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
1801
res = xmlSchemaGetCanonValueWhtspExt(facet->val,
1804
xmlSchemaInternalErr(actxt,
1805
"xmlSchemaFormatFacetEnumSet",
1806
"compute the canonical lexical representation");
1813
*buf = xmlStrdup(BAD_CAST "'");
1815
*buf = xmlStrcat(*buf, BAD_CAST ", '");
1816
*buf = xmlStrcat(*buf, BAD_CAST value);
1817
*buf = xmlStrcat(*buf, BAD_CAST "'");
1818
if (value != NULL) {
1819
xmlFree((xmlChar *)value);
1824
* The enumeration facet of a type restricts the enumeration
1825
* facet of the ancestor type; i.e., such restricted enumerations
1826
* do not belong to the set of the given type. Thus we break
1827
* on the first found enumeration.
1831
type = type->baseType;
1832
} while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
1834
return ((const xmlChar *) *buf);
1837
/************************************************************************
1841
************************************************************************/
1845
xmlSchemaErrMemory(const char *msg)
1847
__xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1853
xmlSchemaPSimpleErr(const char *msg)
1855
__xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
1860
* xmlSchemaPErrMemory:
1861
* @node: a context node
1862
* @extra: extra informations
1864
* Handle an out of memory condition
1867
xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
1868
const char *extra, xmlNodePtr node)
1872
__xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
1878
* @ctxt: the parsing context
1879
* @node: the context node
1880
* @error: the error code
1881
* @msg: the error message
1885
* Handle a parser error
1888
xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
1889
const char *msg, const xmlChar * str1, const xmlChar * str2)
1891
xmlGenericErrorFunc channel = NULL;
1892
xmlStructuredErrorFunc schannel = NULL;
1898
channel = ctxt->error;
1899
data = ctxt->errCtxt;
1900
schannel = ctxt->serror;
1902
__xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
1903
error, XML_ERR_ERROR, NULL, 0,
1904
(const char *) str1, (const char *) str2, NULL, 0, 0,
1910
* @ctxt: the parsing context
1911
* @node: the context node
1912
* @node: the current child
1913
* @error: the error code
1914
* @msg: the error message
1918
* Handle a parser error
1921
xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
1922
xmlNodePtr child, int error,
1923
const char *msg, const xmlChar * str1, const xmlChar * str2)
1926
xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
1928
xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
1934
* @ctxt: the parsing context
1935
* @node: the context node
1936
* @error: the error code
1937
* @strData1: extra data
1938
* @strData2: extra data
1939
* @strData3: extra data
1941
* @str1: extra parameter for the message display
1942
* @str2: extra parameter for the message display
1943
* @str3: extra parameter for the message display
1944
* @str4: extra parameter for the message display
1945
* @str5: extra parameter for the message display
1947
* Handle a parser error
1950
xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
1951
const xmlChar * strData1, const xmlChar * strData2,
1952
const xmlChar * strData3, const char *msg, const xmlChar * str1,
1953
const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
1954
const xmlChar * str5)
1957
xmlGenericErrorFunc channel = NULL;
1958
xmlStructuredErrorFunc schannel = NULL;
1964
channel = ctxt->error;
1965
data = ctxt->errCtxt;
1966
schannel = ctxt->serror;
1968
__xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
1969
error, XML_ERR_ERROR, NULL, 0,
1970
(const char *) strData1, (const char *) strData2,
1971
(const char *) strData3, 0, 0, msg, str1, str2,
1975
/************************************************************************
1977
* Allround error functions *
1979
************************************************************************/
1982
* xmlSchemaVTypeErrMemory:
1983
* @node: a context node
1984
* @extra: extra informations
1986
* Handle an out of memory condition
1989
xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
1990
const char *extra, xmlNodePtr node)
1994
ctxt->err = XML_SCHEMAV_INTERNAL;
1996
__xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
2001
xmlSchemaPSimpleInternalErr(xmlNodePtr node,
2002
const char *msg, const xmlChar *str)
2004
__xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
2005
msg, (const char *) str);
2008
#define WXS_ERROR_TYPE_ERROR 1
2009
#define WXS_ERROR_TYPE_WARNING 2
2012
* @ctxt: the validation context
2013
* @node: the context node
2014
* @error: the error code
2015
* @msg: the error message
2020
* Handle a validation error
2023
xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
2024
xmlErrorLevel errorLevel,
2025
int error, xmlNodePtr node, int line, const char *msg,
2026
const xmlChar *str1, const xmlChar *str2,
2027
const xmlChar *str3, const xmlChar *str4)
2029
xmlStructuredErrorFunc schannel = NULL;
2030
xmlGenericErrorFunc channel = NULL;
2034
if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2035
xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
2036
const char *file = NULL;
2037
if (errorLevel != XML_ERR_WARNING) {
2040
channel = vctxt->error;
2042
channel = vctxt->warning;
2044
schannel = vctxt->serror;
2045
data = vctxt->errCtxt;
2048
* Error node. If we specify a line number, then
2049
* do not channel any node to the error function.
2052
if ((node == NULL) &&
2053
(vctxt->depth >= 0) &&
2054
(vctxt->inode != NULL)) {
2055
node = vctxt->inode->node;
2058
* Get filename and line if no node-tree.
2060
if ((node == NULL) &&
2061
(vctxt->parserCtxt != NULL) &&
2062
(vctxt->parserCtxt->input != NULL)) {
2063
file = vctxt->parserCtxt->input->filename;
2064
line = vctxt->parserCtxt->input->line;
2068
* Override the given node's (if any) position
2069
* and channel only the given line number.
2075
if (vctxt->doc != NULL)
2076
file = (const char *) vctxt->doc->URL;
2077
else if ((vctxt->parserCtxt != NULL) &&
2078
(vctxt->parserCtxt->input != NULL))
2079
file = vctxt->parserCtxt->input->filename;
2081
__xmlRaiseError(schannel, channel, data, ctxt,
2082
node, XML_FROM_SCHEMASV,
2083
error, errorLevel, file, line,
2084
(const char *) str1, (const char *) str2,
2085
(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
2087
} else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
2088
xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
2089
if (errorLevel != XML_ERR_WARNING) {
2092
channel = pctxt->error;
2094
channel = pctxt->warning;
2096
schannel = pctxt->serror;
2097
data = pctxt->errCtxt;
2098
__xmlRaiseError(schannel, channel, data, ctxt,
2099
node, XML_FROM_SCHEMASP, error,
2100
errorLevel, NULL, 0,
2101
(const char *) str1, (const char *) str2,
2102
(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
2111
* @ctxt: the validation context
2112
* @node: the context node
2113
* @error: the error code
2114
* @msg: the error message
2119
* Handle a validation error
2122
xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
2123
int error, xmlNodePtr node, const char *msg,
2124
const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
2126
xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2127
msg, str1, str2, str3, NULL);
2131
xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
2132
int error, xmlNodePtr node, const char *msg,
2133
const xmlChar *str1, const xmlChar *str2,
2134
const xmlChar *str3, const xmlChar *str4)
2136
xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
2137
msg, str1, str2, str3, str4);
2141
xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
2142
int error, xmlNodePtr node, const char *msg,
2143
const xmlChar *str1, const xmlChar *str2)
2145
xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
2149
xmlSchemaFormatNodeForError(xmlChar ** msg,
2150
xmlSchemaAbstractCtxtPtr actxt,
2153
xmlChar *str = NULL;
2156
if ((node != NULL) &&
2157
(node->type != XML_ELEMENT_NODE) &&
2158
(node->type != XML_ATTRIBUTE_NODE))
2161
* Don't try to format other nodes than element and
2163
* Play save and return an empty string.
2165
*msg = xmlStrdup(BAD_CAST "");
2170
* Work on tree nodes.
2172
if (node->type == XML_ATTRIBUTE_NODE) {
2173
xmlNodePtr elem = node->parent;
2175
*msg = xmlStrdup(BAD_CAST "Element '");
2176
if (elem->ns != NULL)
2177
*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2178
elem->ns->href, elem->name));
2180
*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2183
*msg = xmlStrcat(*msg, BAD_CAST "', ");
2184
*msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2186
*msg = xmlStrdup(BAD_CAST "Element '");
2188
if (node->ns != NULL)
2189
*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2190
node->ns->href, node->name));
2192
*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2195
*msg = xmlStrcat(*msg, BAD_CAST "': ");
2196
} else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
2197
xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
2199
* Work on node infos.
2201
if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
2202
xmlSchemaNodeInfoPtr ielem =
2203
vctxt->elemInfos[vctxt->depth];
2205
*msg = xmlStrdup(BAD_CAST "Element '");
2206
*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2207
ielem->nsName, ielem->localName));
2209
*msg = xmlStrcat(*msg, BAD_CAST "', ");
2210
*msg = xmlStrcat(*msg, BAD_CAST "attribute '");
2212
*msg = xmlStrdup(BAD_CAST "Element '");
2214
*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
2215
vctxt->inode->nsName, vctxt->inode->localName));
2217
*msg = xmlStrcat(*msg, BAD_CAST "': ");
2218
} else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
2220
* Hmm, no node while parsing?
2221
* Return an empty string, in case NULL will break something.
2223
*msg = xmlStrdup(BAD_CAST "");
2229
* VAL TODO: The output of the given schema component is currently
2233
if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
2234
*msg = xmlStrcat(*msg, BAD_CAST " [");
2235
*msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
2236
NULL, type, NULL, 0));
2238
*msg = xmlStrcat(*msg, BAD_CAST "]");
2245
xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
2246
const char *funcName,
2247
const char *message,
2248
const xmlChar *str1,
2249
const xmlChar *str2)
2251
xmlChar *msg = NULL;
2255
msg = xmlStrdup(BAD_CAST "Internal error: ");
2256
msg = xmlStrcat(msg, BAD_CAST funcName);
2257
msg = xmlStrcat(msg, BAD_CAST ", ");
2258
msg = xmlStrcat(msg, BAD_CAST message);
2259
msg = xmlStrcat(msg, BAD_CAST ".\n");
2261
if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
2262
xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
2263
(const char *) msg, str1, str2);
2265
else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
2266
xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
2267
(const char *) msg, str1, str2);
2273
xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
2274
const char *funcName,
2275
const char *message)
2277
xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
2282
xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
2283
const char *funcName,
2284
const char *message,
2285
const xmlChar *str1,
2286
const xmlChar *str2)
2288
xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
2294
xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
2295
xmlParserErrors error,
2297
xmlSchemaBasicItemPtr item,
2298
const char *message,
2299
const xmlChar *str1, const xmlChar *str2,
2300
const xmlChar *str3, const xmlChar *str4)
2302
xmlChar *msg = NULL;
2304
if ((node == NULL) && (item != NULL) &&
2305
(actxt->type == XML_SCHEMA_CTXT_PARSER)) {
2306
node = WXS_ITEM_NODE(item);
2307
xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
2308
msg = xmlStrcat(msg, BAD_CAST ": ");
2310
xmlSchemaFormatNodeForError(&msg, actxt, node);
2311
msg = xmlStrcat(msg, (const xmlChar *) message);
2312
msg = xmlStrcat(msg, BAD_CAST ".\n");
2313
xmlSchemaErr4(actxt, error, node,
2314
(const char *) msg, str1, str2, str3, str4);
2319
xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
2320
xmlParserErrors error,
2322
xmlSchemaBasicItemPtr item,
2323
const char *message,
2324
const xmlChar *str1,
2325
const xmlChar *str2)
2327
xmlSchemaCustomErr4(actxt, error, node, item,
2328
message, str1, str2, NULL, NULL);
2334
xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
2335
xmlParserErrors error,
2337
xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2338
const char *message,
2339
const xmlChar *str1,
2340
const xmlChar *str2,
2341
const xmlChar *str3)
2343
xmlChar *msg = NULL;
2345
xmlSchemaFormatNodeForError(&msg, actxt, node);
2346
msg = xmlStrcat(msg, (const xmlChar *) message);
2347
msg = xmlStrcat(msg, BAD_CAST ".\n");
2349
/* URGENT TODO: Set the error code to something sane. */
2350
xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
2351
(const char *) msg, str1, str2, str3, NULL);
2359
xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
2360
xmlParserErrors error,
2361
xmlSchemaPSVIIDCNodePtr idcNode,
2362
xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2363
const char *message,
2364
const xmlChar *str1,
2365
const xmlChar *str2)
2367
xmlChar *msg = NULL, *qname = NULL;
2369
msg = xmlStrdup(BAD_CAST "Element '%s': ");
2370
msg = xmlStrcat(msg, (const xmlChar *) message);
2371
msg = xmlStrcat(msg, BAD_CAST ".\n");
2372
xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
2373
error, NULL, idcNode->nodeLine, (const char *) msg,
2374
xmlSchemaFormatQName(&qname,
2375
vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
2376
vctxt->nodeQNames->items[idcNode->nodeQNameID]),
2378
FREE_AND_NULL(qname);
2383
xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
2387
return (node->type);
2388
if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
2389
(((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
2390
return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
2395
xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
2397
switch (item->type) {
2398
case XML_SCHEMA_TYPE_COMPLEX:
2399
case XML_SCHEMA_TYPE_SIMPLE:
2400
if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
2403
case XML_SCHEMA_TYPE_GROUP:
2405
case XML_SCHEMA_TYPE_ELEMENT:
2406
if ( ((xmlSchemaElementPtr) item)->flags &
2407
XML_SCHEMAS_ELEM_GLOBAL)
2410
case XML_SCHEMA_TYPE_ATTRIBUTE:
2411
if ( ((xmlSchemaAttributePtr) item)->flags &
2412
XML_SCHEMAS_ATTR_GLOBAL)
2415
/* Note that attribute groups are always global. */
2423
xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2424
xmlParserErrors error,
2426
const xmlChar *value,
2427
xmlSchemaTypePtr type,
2430
xmlChar *msg = NULL;
2432
xmlSchemaFormatNodeForError(&msg, actxt, node);
2434
if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2435
XML_ATTRIBUTE_NODE))
2436
msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
2438
msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
2441
if (! xmlSchemaIsGlobalItem(type))
2442
msg = xmlStrcat(msg, BAD_CAST "the local ");
2444
msg = xmlStrcat(msg, BAD_CAST "the ");
2446
if (WXS_IS_ATOMIC(type))
2447
msg = xmlStrcat(msg, BAD_CAST "atomic type");
2448
else if (WXS_IS_LIST(type))
2449
msg = xmlStrcat(msg, BAD_CAST "list type");
2450
else if (WXS_IS_UNION(type))
2451
msg = xmlStrcat(msg, BAD_CAST "union type");
2453
if (xmlSchemaIsGlobalItem(type)) {
2454
xmlChar *str = NULL;
2455
msg = xmlStrcat(msg, BAD_CAST " '");
2456
if (type->builtInType != 0) {
2457
msg = xmlStrcat(msg, BAD_CAST "xs:");
2458
msg = xmlStrcat(msg, type->name);
2460
msg = xmlStrcat(msg,
2461
xmlSchemaFormatQName(&str,
2462
type->targetNamespace, type->name));
2463
msg = xmlStrcat(msg, BAD_CAST "'");
2466
msg = xmlStrcat(msg, BAD_CAST ".\n");
2467
if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
2468
XML_ATTRIBUTE_NODE))
2469
xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2471
xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2475
static const xmlChar *
2476
xmlSchemaFormatErrorNodeQName(xmlChar ** str,
2477
xmlSchemaNodeInfoPtr ni,
2481
if (node->ns != NULL)
2482
return (xmlSchemaFormatQName(str, node->ns->href, node->name));
2484
return (xmlSchemaFormatQName(str, NULL, node->name));
2485
} else if (ni != NULL)
2486
return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
2491
xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
2492
xmlParserErrors error,
2493
xmlSchemaAttrInfoPtr ni,
2496
xmlChar *msg = NULL, *str = NULL;
2498
xmlSchemaFormatNodeForError(&msg, actxt, node);
2499
msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
2500
xmlSchemaErr(actxt, error, node, (const char *) msg,
2501
xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
2508
xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
2509
xmlParserErrors error,
2511
xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
2512
const char *message,
2517
xmlChar *str = NULL, *msg = NULL;
2518
xmlChar *localName, *nsName;
2519
const xmlChar *cur, *end;
2522
xmlSchemaFormatNodeForError(&msg, actxt, node);
2523
msg = xmlStrcat(msg, (const xmlChar *) message);
2524
msg = xmlStrcat(msg, BAD_CAST ".");
2526
* Note that is does not make sense to report that we have a
2527
* wildcard here, since the wildcard might be unfolded into
2528
* multiple transitions.
2530
if (nbval + nbneg > 0) {
2531
if (nbval + nbneg > 1) {
2532
str = xmlStrdup(BAD_CAST " Expected is one of ( ");
2534
str = xmlStrdup(BAD_CAST " Expected is ( ");
2537
for (i = 0; i < nbval + nbneg; i++) {
2541
if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
2544
str = xmlStrcat(str, BAD_CAST "##other");
2547
* Get the local name.
2553
localName = xmlStrdup(BAD_CAST "*");
2556
while ((*end != 0) && (*end != '|'))
2558
localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
2563
* Skip "*|*" if they come with negated expressions, since
2564
* they represent the same negated wildcard.
2566
if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
2568
* Get the namespace name.
2572
nsName = xmlStrdup(BAD_CAST "{*}");
2578
nsName = xmlStrdup(BAD_CAST "{##other:");
2580
nsName = xmlStrdup(BAD_CAST "{");
2582
nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
2583
nsName = xmlStrcat(nsName, BAD_CAST "}");
2585
str = xmlStrcat(str, BAD_CAST nsName);
2586
FREE_AND_NULL(nsName)
2588
FREE_AND_NULL(localName);
2592
str = xmlStrcat(str, BAD_CAST localName);
2593
FREE_AND_NULL(localName);
2595
if (i < nbval + nbneg -1)
2596
str = xmlStrcat(str, BAD_CAST ", ");
2598
str = xmlStrcat(str, BAD_CAST " ).\n");
2599
msg = xmlStrcat(msg, BAD_CAST str);
2602
msg = xmlStrcat(msg, BAD_CAST "\n");
2603
xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2608
xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
2609
xmlParserErrors error,
2611
const xmlChar *value,
2612
unsigned long length,
2613
xmlSchemaTypePtr type,
2614
xmlSchemaFacetPtr facet,
2615
const char *message,
2616
const xmlChar *str1,
2617
const xmlChar *str2)
2619
xmlChar *str = NULL, *msg = NULL;
2620
xmlSchemaTypeType facetType;
2621
int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
2623
xmlSchemaFormatNodeForError(&msg, actxt, node);
2624
if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
2625
facetType = XML_SCHEMA_FACET_ENUMERATION;
2627
* If enumerations are validated, one must not expect the
2628
* facet to be given.
2631
facetType = facet->type;
2632
msg = xmlStrcat(msg, BAD_CAST "[");
2633
msg = xmlStrcat(msg, BAD_CAST "facet '");
2634
msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
2635
msg = xmlStrcat(msg, BAD_CAST "'] ");
2636
if (message == NULL) {
2638
* Use a default message.
2640
if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
2641
(facetType == XML_SCHEMA_FACET_MINLENGTH) ||
2642
(facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
2644
char len[25], actLen[25];
2646
/* FIXME, TODO: What is the max expected string length of the
2649
if (nodeType == XML_ATTRIBUTE_NODE)
2650
msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
2652
msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
2654
snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
2655
snprintf(actLen, 24, "%lu", length);
2657
if (facetType == XML_SCHEMA_FACET_LENGTH)
2658
msg = xmlStrcat(msg,
2659
BAD_CAST "this differs from the allowed length of '%s'.\n");
2660
else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
2661
msg = xmlStrcat(msg,
2662
BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
2663
else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
2664
msg = xmlStrcat(msg,
2665
BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
2667
if (nodeType == XML_ATTRIBUTE_NODE)
2668
xmlSchemaErr3(actxt, error, node, (const char *) msg,
2669
value, (const xmlChar *) actLen, (const xmlChar *) len);
2671
xmlSchemaErr(actxt, error, node, (const char *) msg,
2672
(const xmlChar *) actLen, (const xmlChar *) len);
2674
} else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
2675
msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
2676
"of the set {%s}.\n");
2677
xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2678
xmlSchemaFormatFacetEnumSet(actxt, &str, type));
2679
} else if (facetType == XML_SCHEMA_FACET_PATTERN) {
2680
msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
2681
"by the pattern '%s'.\n");
2682
xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2684
} else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
2685
msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
2686
"minimum value allowed ('%s').\n");
2687
xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2689
} else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
2690
msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
2691
"maximum value allowed ('%s').\n");
2692
xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2694
} else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
2695
msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
2697
xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2699
} else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
2700
msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
2702
xmlSchemaErr(actxt, error, node, (const char *) msg, value,
2704
} else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
2705
msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
2706
"digits than are allowed ('%s').\n");
2707
xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2709
} else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
2710
msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
2711
"digits than are allowed ('%s').\n");
2712
xmlSchemaErr(actxt, error, node, (const char*) msg, value,
2714
} else if (nodeType == XML_ATTRIBUTE_NODE) {
2715
msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
2716
xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
2718
msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
2719
xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
2722
msg = xmlStrcat(msg, (const xmlChar *) message);
2723
msg = xmlStrcat(msg, BAD_CAST ".\n");
2724
xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
2730
#define VERROR(err, type, msg) \
2731
xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
2733
#define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
2735
#define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
2736
#define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
2738
#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
2742
* xmlSchemaPMissingAttrErr:
2743
* @ctxt: the schema validation context
2744
* @ownerDes: the designation of the owner
2745
* @ownerName: the name of the owner
2746
* @ownerItem: the owner as a schema object
2747
* @ownerElem: the owner as an element node
2748
* @node: the parent element node of the missing attribute node
2749
* @type: the corresponding type of the attribute node
2751
* Reports an illegal attribute.
2754
xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
2755
xmlParserErrors error,
2756
xmlSchemaBasicItemPtr ownerItem,
2757
xmlNodePtr ownerElem,
2759
const char *message)
2761
xmlChar *des = NULL;
2763
xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2765
if (message != NULL)
2766
xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
2768
xmlSchemaPErr(ctxt, ownerElem, error,
2769
"%s: The attribute '%s' is required but missing.\n",
2770
BAD_CAST des, BAD_CAST name);
2776
* xmlSchemaPResCompAttrErr:
2777
* @ctxt: the schema validation context
2778
* @error: the error code
2779
* @ownerDes: the designation of the owner
2780
* @ownerItem: the owner as a schema object
2781
* @ownerElem: the owner as an element node
2782
* @name: the name of the attribute holding the QName
2783
* @refName: the referenced local name
2784
* @refURI: the referenced namespace URI
2785
* @message: optional message
2787
* Used to report QName attribute values that failed to resolve
2788
* to schema components.
2791
xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
2792
xmlParserErrors error,
2793
xmlSchemaBasicItemPtr ownerItem,
2794
xmlNodePtr ownerElem,
2796
const xmlChar *refName,
2797
const xmlChar *refURI,
2798
xmlSchemaTypeType refType,
2799
const char *refTypeStr)
2801
xmlChar *des = NULL, *strA = NULL;
2803
xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
2804
if (refTypeStr == NULL)
2805
refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
2806
xmlSchemaPErrExt(ctxt, ownerElem, error,
2808
"%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
2809
"%s.\n", BAD_CAST des, BAD_CAST name,
2810
xmlSchemaFormatQName(&strA, refURI, refName),
2811
BAD_CAST refTypeStr, NULL);
2817
* xmlSchemaPCustomAttrErr:
2818
* @ctxt: the schema parser context
2819
* @error: the error code
2820
* @ownerDes: the designation of the owner
2821
* @ownerItem: the owner as a schema object
2822
* @attr: the illegal attribute node
2824
* Reports an illegal attribute during the parse.
2827
xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
2828
xmlParserErrors error,
2830
xmlSchemaBasicItemPtr ownerItem,
2834
xmlChar *des = NULL;
2836
if (ownerDes == NULL)
2837
xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
2838
else if (*ownerDes == NULL) {
2839
xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
2844
xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
2845
"%s, attribute '%s': %s.\n",
2846
BAD_CAST des, (const xmlChar *) "Unknown",
2847
(const xmlChar *) msg, NULL, NULL);
2849
xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
2850
"%s, attribute '%s': %s.\n",
2851
BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
2853
if (ownerDes == NULL)
2858
* xmlSchemaPIllegalAttrErr:
2859
* @ctxt: the schema parser context
2860
* @error: the error code
2861
* @ownerDes: the designation of the attribute's owner
2862
* @ownerItem: the attribute's owner item
2863
* @attr: the illegal attribute node
2865
* Reports an illegal attribute during the parse.
2868
xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
2869
xmlParserErrors error,
2870
xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
2873
xmlChar *strA = NULL, *strB = NULL;
2875
xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
2876
xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
2877
"%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
2878
xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
2880
FREE_AND_NULL(strA);
2881
FREE_AND_NULL(strB);
2885
* xmlSchemaPCustomErr:
2886
* @ctxt: the schema parser context
2887
* @error: the error code
2888
* @itemDes: the designation of the schema item
2889
* @item: the schema item
2890
* @itemElem: the node of the schema item
2891
* @message: the error message
2892
* @str1: an optional param for the error message
2893
* @str2: an optional param for the error message
2894
* @str3: an optional param for the error message
2896
* Reports an error during parsing.
2899
xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
2900
xmlParserErrors error,
2901
xmlSchemaBasicItemPtr item,
2902
xmlNodePtr itemElem,
2903
const char *message,
2904
const xmlChar *str1,
2905
const xmlChar *str2,
2906
const xmlChar *str3)
2908
xmlChar *des = NULL, *msg = NULL;
2910
xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
2911
msg = xmlStrdup(BAD_CAST "%s: ");
2912
msg = xmlStrcat(msg, (const xmlChar *) message);
2913
msg = xmlStrcat(msg, BAD_CAST ".\n");
2914
if ((itemElem == NULL) && (item != NULL))
2915
itemElem = WXS_ITEM_NODE(item);
2916
xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
2917
(const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
2923
* xmlSchemaPCustomErr:
2924
* @ctxt: the schema parser context
2925
* @error: the error code
2926
* @itemDes: the designation of the schema item
2927
* @item: the schema item
2928
* @itemElem: the node of the schema item
2929
* @message: the error message
2930
* @str1: the optional param for the error message
2932
* Reports an error during parsing.
2935
xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
2936
xmlParserErrors error,
2937
xmlSchemaBasicItemPtr item,
2938
xmlNodePtr itemElem,
2939
const char *message,
2940
const xmlChar *str1)
2942
xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
2947
* xmlSchemaPAttrUseErr:
2948
* @ctxt: the schema parser context
2949
* @error: the error code
2950
* @itemDes: the designation of the schema type
2951
* @item: the schema type
2952
* @itemElem: the node of the schema type
2953
* @attr: the invalid schema attribute
2954
* @message: the error message
2955
* @str1: the optional param for the error message
2957
* Reports an attribute use error during parsing.
2960
xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
2961
xmlParserErrors error,
2963
xmlSchemaBasicItemPtr ownerItem,
2964
const xmlSchemaAttributeUsePtr attruse,
2965
const char *message,
2966
const xmlChar *str1, const xmlChar *str2,
2967
const xmlChar *str3,const xmlChar *str4)
2969
xmlChar *str = NULL, *msg = NULL;
2971
xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
2972
msg = xmlStrcat(msg, BAD_CAST ", ");
2973
msg = xmlStrcat(msg,
2974
BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
2975
WXS_BASIC_CAST attruse, NULL));
2977
msg = xmlStrcat(msg, BAD_CAST ": ");
2978
msg = xmlStrcat(msg, (const xmlChar *) message);
2979
msg = xmlStrcat(msg, BAD_CAST ".\n");
2980
xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
2981
(const char *) msg, str1, str2, str3, str4);
2986
* xmlSchemaPIllegalFacetAtomicErr:
2987
* @ctxt: the schema parser context
2988
* @error: the error code
2989
* @type: the schema type
2990
* @baseType: the base type of type
2991
* @facet: the illegal facet
2993
* Reports an illegal facet for atomic simple types.
2996
xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
2997
xmlParserErrors error,
2998
xmlSchemaTypePtr type,
2999
xmlSchemaTypePtr baseType,
3000
xmlSchemaFacetPtr facet)
3002
xmlChar *des = NULL, *strT = NULL;
3004
xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
3005
xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
3006
"%s: The facet '%s' is not allowed on types derived from the "
3008
BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
3009
xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
3012
FREE_AND_NULL(strT);
3016
* xmlSchemaPIllegalFacetListUnionErr:
3017
* @ctxt: the schema parser context
3018
* @error: the error code
3019
* @itemDes: the designation of the schema item involved
3020
* @item: the schema item involved
3021
* @facet: the illegal facet
3023
* Reports an illegal facet for <list> and <union>.
3026
xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
3027
xmlParserErrors error,
3028
xmlSchemaTypePtr type,
3029
xmlSchemaFacetPtr facet)
3031
xmlChar *des = NULL;
3033
xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
3035
xmlSchemaPErr(ctxt, type->node, error,
3036
"%s: The facet '%s' is not allowed.\n",
3037
BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
3042
* xmlSchemaPMutualExclAttrErr:
3043
* @ctxt: the schema validation context
3044
* @error: the error code
3045
* @elemDes: the designation of the parent element node
3046
* @attr: the bad attribute node
3047
* @type: the corresponding type of the attribute node
3049
* Reports an illegal attribute.
3052
xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
3053
xmlParserErrors error,
3054
xmlSchemaBasicItemPtr ownerItem,
3059
xmlChar *des = NULL;
3061
xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
3062
xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
3063
"%s: The attributes '%s' and '%s' are mutually exclusive.\n",
3064
BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
3069
* xmlSchemaPSimpleTypeErr:
3070
* @ctxt: the schema validation context
3071
* @error: the error code
3072
* @type: the type specifier
3073
* @ownerDes: the designation of the owner
3074
* @ownerItem: the schema object if existent
3075
* @node: the validated node
3076
* @value: the validated value
3078
* Reports a simple type validation error.
3079
* TODO: Should this report the value of an element as well?
3082
xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
3083
xmlParserErrors error,
3084
xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
3086
xmlSchemaTypePtr type,
3087
const char *expected,
3088
const xmlChar *value,
3089
const char *message,
3090
const xmlChar *str1,
3091
const xmlChar *str2)
3093
xmlChar *msg = NULL;
3095
xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
3096
if (message == NULL) {
3098
* Use default messages.
3101
if (node->type == XML_ATTRIBUTE_NODE)
3102
msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
3104
msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
3106
if (! xmlSchemaIsGlobalItem(type))
3107
msg = xmlStrcat(msg, BAD_CAST "the local ");
3109
msg = xmlStrcat(msg, BAD_CAST "the ");
3111
if (WXS_IS_ATOMIC(type))
3112
msg = xmlStrcat(msg, BAD_CAST "atomic type");
3113
else if (WXS_IS_LIST(type))
3114
msg = xmlStrcat(msg, BAD_CAST "list type");
3115
else if (WXS_IS_UNION(type))
3116
msg = xmlStrcat(msg, BAD_CAST "union type");
3118
if (xmlSchemaIsGlobalItem(type)) {
3119
xmlChar *str = NULL;
3120
msg = xmlStrcat(msg, BAD_CAST " '");
3121
if (type->builtInType != 0) {
3122
msg = xmlStrcat(msg, BAD_CAST "xs:");
3123
msg = xmlStrcat(msg, type->name);
3125
msg = xmlStrcat(msg,
3126
xmlSchemaFormatQName(&str,
3127
type->targetNamespace, type->name));
3128
msg = xmlStrcat(msg, BAD_CAST "'.");
3132
if (node->type == XML_ATTRIBUTE_NODE)
3133
msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
3135
msg = xmlStrcat(msg, BAD_CAST "The character content is not "
3139
msg = xmlStrcat(msg, BAD_CAST " Expected is '");
3140
msg = xmlStrcat(msg, BAD_CAST expected);
3141
msg = xmlStrcat(msg, BAD_CAST "'.\n");
3143
msg = xmlStrcat(msg, BAD_CAST "\n");
3144
if (node->type == XML_ATTRIBUTE_NODE)
3145
xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
3147
xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
3149
msg = xmlStrcat(msg, BAD_CAST message);
3150
msg = xmlStrcat(msg, BAD_CAST ".\n");
3151
xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
3152
(const char*) msg, str1, str2, NULL, NULL, NULL);
3159
* xmlSchemaPContentErr:
3160
* @ctxt: the schema parser context
3161
* @error: the error code
3162
* @onwerDes: the designation of the holder of the content
3163
* @ownerItem: the owner item of the holder of the content
3164
* @ownerElem: the node of the holder of the content
3165
* @child: the invalid child node
3166
* @message: the optional error message
3167
* @content: the optional string describing the correct content
3169
* Reports an error concerning the content of a schema element.
3172
xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
3173
xmlParserErrors error,
3174
xmlSchemaBasicItemPtr ownerItem,
3175
xmlNodePtr ownerElem,
3177
const char *message,
3178
const char *content)
3180
xmlChar *des = NULL;
3182
xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
3183
if (message != NULL)
3184
xmlSchemaPErr2(ctxt, ownerElem, child, error,
3186
BAD_CAST des, BAD_CAST message);
3188
if (content != NULL) {
3189
xmlSchemaPErr2(ctxt, ownerElem, child, error,
3190
"%s: The content is not valid. Expected is %s.\n",
3191
BAD_CAST des, BAD_CAST content);
3193
xmlSchemaPErr2(ctxt, ownerElem, child, error,
3194
"%s: The content is not valid.\n",
3195
BAD_CAST des, NULL);
3201
/************************************************************************
3203
* Streamable error functions *
3205
************************************************************************/
3210
/************************************************************************
3212
* Validation helper functions *
3214
************************************************************************/
3217
/************************************************************************
3219
* Allocation functions *
3221
************************************************************************/
3224
* xmlSchemaNewSchemaForParserCtxt:
3225
* @ctxt: a schema validation context
3227
* Allocate a new Schema structure.
3229
* Returns the newly allocated structure or NULL in case or error
3232
xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
3236
ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
3238
xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
3241
memset(ret, 0, sizeof(xmlSchema));
3242
ret->dict = ctxt->dict;
3243
xmlDictReference(ret->dict);
3249
* xmlSchemaNewFacet:
3251
* Allocate a new Facet structure.
3253
* Returns the newly allocated structure or NULL in case or error
3256
xmlSchemaNewFacet(void)
3258
xmlSchemaFacetPtr ret;
3260
ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
3264
memset(ret, 0, sizeof(xmlSchemaFacet));
3270
* xmlSchemaNewAnnot:
3271
* @ctxt: a schema validation context
3274
* Allocate a new annotation structure.
3276
* Returns the newly allocated structure or NULL in case or error
3278
static xmlSchemaAnnotPtr
3279
xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
3281
xmlSchemaAnnotPtr ret;
3283
ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
3285
xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
3288
memset(ret, 0, sizeof(xmlSchemaAnnot));
3289
ret->content = node;
3293
static xmlSchemaItemListPtr
3294
xmlSchemaItemListCreate(void)
3296
xmlSchemaItemListPtr ret;
3298
ret = xmlMalloc(sizeof(xmlSchemaItemList));
3300
xmlSchemaPErrMemory(NULL,
3301
"allocating an item list structure", NULL);
3304
memset(ret, 0, sizeof(xmlSchemaItemList));
3309
xmlSchemaItemListClear(xmlSchemaItemListPtr list)
3311
if (list->items != NULL) {
3312
xmlFree(list->items);
3316
list->sizeItems = 0;
3320
xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
3322
if (list->items == NULL) {
3323
list->items = (void **) xmlMalloc(
3324
20 * sizeof(void *));
3325
if (list->items == NULL) {
3326
xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3329
list->sizeItems = 20;
3330
} else if (list->sizeItems <= list->nbItems) {
3331
list->sizeItems *= 2;
3332
list->items = (void **) xmlRealloc(list->items,
3333
list->sizeItems * sizeof(void *));
3334
if (list->items == NULL) {
3335
xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3336
list->sizeItems = 0;
3340
list->items[list->nbItems++] = item;
3345
xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
3349
if (list->items == NULL) {
3350
if (initialSize <= 0)
3352
list->items = (void **) xmlMalloc(
3353
initialSize * sizeof(void *));
3354
if (list->items == NULL) {
3355
xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3358
list->sizeItems = initialSize;
3359
} else if (list->sizeItems <= list->nbItems) {
3360
list->sizeItems *= 2;
3361
list->items = (void **) xmlRealloc(list->items,
3362
list->sizeItems * sizeof(void *));
3363
if (list->items == NULL) {
3364
xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3365
list->sizeItems = 0;
3369
list->items[list->nbItems++] = item;
3374
xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
3376
if (list->items == NULL) {
3377
list->items = (void **) xmlMalloc(
3378
20 * sizeof(void *));
3379
if (list->items == NULL) {
3380
xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3383
list->sizeItems = 20;
3384
} else if (list->sizeItems <= list->nbItems) {
3385
list->sizeItems *= 2;
3386
list->items = (void **) xmlRealloc(list->items,
3387
list->sizeItems * sizeof(void *));
3388
if (list->items == NULL) {
3389
xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3390
list->sizeItems = 0;
3395
* Just append if the index is greater/equal than the item count.
3397
if (idx >= list->nbItems) {
3398
list->items[list->nbItems++] = item;
3401
for (i = list->nbItems; i > idx; i--)
3402
list->items[i] = list->items[i-1];
3403
list->items[idx] = item;
3409
#if 0 /* enable if ever needed */
3411
xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
3416
if (list->items == NULL) {
3417
if (initialSize <= 0)
3419
list->items = (void **) xmlMalloc(
3420
initialSize * sizeof(void *));
3421
if (list->items == NULL) {
3422
xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
3425
list->sizeItems = initialSize;
3426
} else if (list->sizeItems <= list->nbItems) {
3427
list->sizeItems *= 2;
3428
list->items = (void **) xmlRealloc(list->items,
3429
list->sizeItems * sizeof(void *));
3430
if (list->items == NULL) {
3431
xmlSchemaPErrMemory(NULL, "growing item list", NULL);
3432
list->sizeItems = 0;
3437
* Just append if the index is greater/equal than the item count.
3439
if (idx >= list->nbItems) {
3440
list->items[list->nbItems++] = item;
3443
for (i = list->nbItems; i > idx; i--)
3444
list->items[i] = list->items[i-1];
3445
list->items[idx] = item;
3453
xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
3456
if ((list->items == NULL) || (idx >= list->nbItems)) {
3457
xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
3462
if (list->nbItems == 1) {
3463
/* TODO: Really free the list? */
3464
xmlFree(list->items);
3467
list->sizeItems = 0;
3468
} else if (list->nbItems -1 == idx) {
3471
for (i = idx; i < list->nbItems -1; i++)
3472
list->items[i] = list->items[i+1];
3479
* xmlSchemaItemListFree:
3480
* @annot: a schema type structure
3482
* Deallocate a annotation structure
3485
xmlSchemaItemListFree(xmlSchemaItemListPtr list)
3489
if (list->items != NULL)
3490
xmlFree(list->items);
3495
xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
3499
if (bucket->globals != NULL) {
3500
xmlSchemaComponentListFree(bucket->globals);
3501
xmlSchemaItemListFree(bucket->globals);
3503
if (bucket->locals != NULL) {
3504
xmlSchemaComponentListFree(bucket->locals);
3505
xmlSchemaItemListFree(bucket->locals);
3507
if (bucket->relations != NULL) {
3508
xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
3513
} while (cur != NULL);
3515
if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
3516
xmlFreeDoc(bucket->doc);
3518
if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
3519
if (WXS_IMPBUCKET(bucket)->schema != NULL)
3520
xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
3525
static xmlSchemaBucketPtr
3526
xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
3527
int type, const xmlChar *targetNamespace)
3529
xmlSchemaBucketPtr ret;
3531
xmlSchemaPtr mainSchema;
3533
if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
3534
PERROR_INT("xmlSchemaBucketCreate",
3535
"no main schema on constructor");
3538
mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
3539
/* Create the schema bucket. */
3540
if (WXS_IS_BUCKET_INCREDEF(type))
3541
size = sizeof(xmlSchemaInclude);
3543
size = sizeof(xmlSchemaImport);
3544
ret = (xmlSchemaBucketPtr) xmlMalloc(size);
3546
xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
3549
memset(ret, 0, size);
3550
ret->targetNamespace = targetNamespace;
3552
ret->globals = xmlSchemaItemListCreate();
3553
if (ret->globals == NULL) {
3557
ret->locals = xmlSchemaItemListCreate();
3558
if (ret->locals == NULL) {
3563
* The following will assure that only the first bucket is marked as
3564
* XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
3565
* For each following import buckets an xmlSchema will be created.
3566
* An xmlSchema will be created for every distinct targetNamespace.
3567
* We assign the targetNamespace to the schemata here.
3569
if (! WXS_HAS_BUCKETS(pctxt)) {
3570
if (WXS_IS_BUCKET_INCREDEF(type)) {
3571
PERROR_INT("xmlSchemaBucketCreate",
3572
"first bucket but it's an include or redefine");
3573
xmlSchemaBucketFree(ret);
3576
/* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
3577
ret->type = XML_SCHEMA_SCHEMA_MAIN;
3578
/* Point to the *main* schema. */
3579
WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
3580
WXS_IMPBUCKET(ret)->schema = mainSchema;
3582
* Ensure that the main schema gets a targetNamespace.
3584
mainSchema->targetNamespace = targetNamespace;
3586
if (type == XML_SCHEMA_SCHEMA_MAIN) {
3587
PERROR_INT("xmlSchemaBucketCreate",
3588
"main bucket but it's not the first one");
3589
xmlSchemaBucketFree(ret);
3591
} else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
3593
* Create a schema for imports and assign the
3596
WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
3597
if (WXS_IMPBUCKET(ret)->schema == NULL) {
3598
xmlSchemaBucketFree(ret);
3601
WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
3604
if (WXS_IS_BUCKET_IMPMAIN(type)) {
3607
* Imports go into the "schemasImports" slot of the main *schema*.
3608
* Note that we create an import entry for the main schema as well; i.e.,
3609
* even if there's only one schema, we'll get an import.
3611
if (mainSchema->schemasImports == NULL) {
3612
mainSchema->schemasImports = xmlHashCreateDict(5,
3613
WXS_CONSTRUCTOR(pctxt)->dict);
3614
if (mainSchema->schemasImports == NULL) {
3615
xmlSchemaBucketFree(ret);
3619
if (targetNamespace == NULL)
3620
res = xmlHashAddEntry(mainSchema->schemasImports,
3621
XML_SCHEMAS_NO_NAMESPACE, ret);
3623
res = xmlHashAddEntry(mainSchema->schemasImports,
3624
targetNamespace, ret);
3626
PERROR_INT("xmlSchemaBucketCreate",
3627
"failed to add the schema bucket to the hash");
3628
xmlSchemaBucketFree(ret);
3632
/* Set the @ownerImport of an include bucket. */
3633
if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
3634
WXS_INCBUCKET(ret)->ownerImport =
3635
WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
3637
WXS_INCBUCKET(ret)->ownerImport =
3638
WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
3640
/* Includes got into the "includes" slot of the *main* schema. */
3641
if (mainSchema->includes == NULL) {
3642
mainSchema->includes = xmlSchemaItemListCreate();
3643
if (mainSchema->includes == NULL) {
3644
xmlSchemaBucketFree(ret);
3648
xmlSchemaItemListAdd(mainSchema->includes, ret);
3651
* Add to list of all buckets; this is used for lookup
3652
* during schema construction time only.
3654
if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
3660
xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
3662
if (*list == NULL) {
3663
*list = xmlSchemaItemListCreate();
3667
xmlSchemaItemListAddSize(*list, initialSize, item);
3672
* xmlSchemaFreeAnnot:
3673
* @annot: a schema type structure
3675
* Deallocate a annotation structure
3678
xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
3682
if (annot->next == NULL) {
3685
xmlSchemaAnnotPtr prev;
3689
annot = annot->next;
3691
} while (annot != NULL);
3696
* xmlSchemaFreeNotation:
3697
* @schema: a schema notation structure
3699
* Deallocate a Schema Notation structure.
3702
xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
3710
* xmlSchemaFreeAttribute:
3711
* @attr: an attribute declaration
3713
* Deallocates an attribute declaration structure.
3716
xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
3720
if (attr->annot != NULL)
3721
xmlSchemaFreeAnnot(attr->annot);
3722
if (attr->defVal != NULL)
3723
xmlSchemaFreeValue(attr->defVal);
3728
* xmlSchemaFreeAttributeUse:
3729
* @use: an attribute use
3731
* Deallocates an attribute use structure.
3734
xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
3738
if (use->annot != NULL)
3739
xmlSchemaFreeAnnot(use->annot);
3740
if (use->defVal != NULL)
3741
xmlSchemaFreeValue(use->defVal);
3746
* xmlSchemaFreeAttributeUseProhib:
3747
* @prohib: an attribute use prohibition
3749
* Deallocates an attribute use structure.
3752
xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
3760
* xmlSchemaFreeWildcardNsSet:
3761
* set: a schema wildcard namespace
3763
* Deallocates a list of wildcard constraint structures.
3766
xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
3768
xmlSchemaWildcardNsPtr next;
3770
while (set != NULL) {
3778
* xmlSchemaFreeWildcard:
3779
* @wildcard: a wildcard structure
3781
* Deallocates a wildcard structure.
3784
xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
3786
if (wildcard == NULL)
3788
if (wildcard->annot != NULL)
3789
xmlSchemaFreeAnnot(wildcard->annot);
3790
if (wildcard->nsSet != NULL)
3791
xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
3792
if (wildcard->negNsSet != NULL)
3793
xmlFree(wildcard->negNsSet);
3798
* xmlSchemaFreeAttributeGroup:
3799
* @schema: a schema attribute group structure
3801
* Deallocate a Schema Attribute Group structure.
3804
xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
3808
if (attrGr->annot != NULL)
3809
xmlSchemaFreeAnnot(attrGr->annot);
3810
if (attrGr->attrUses != NULL)
3811
xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
3816
* xmlSchemaFreeQNameRef:
3817
* @item: a QName reference structure
3819
* Deallocatea a QName reference structure.
3822
xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
3828
* xmlSchemaFreeTypeLinkList:
3829
* @alink: a type link
3831
* Deallocate a list of types.
3834
xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
3836
xmlSchemaTypeLinkPtr next;
3838
while (link != NULL) {
3846
xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
3848
xmlSchemaIDCStateObjPtr next;
3849
while (sto != NULL) {
3851
if (sto->history != NULL)
3852
xmlFree(sto->history);
3853
if (sto->xpathCtxt != NULL)
3854
xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
3862
* @idc: a identity-constraint definition
3864
* Deallocates an identity-constraint definition.
3867
xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
3869
xmlSchemaIDCSelectPtr cur, prev;
3873
if (idcDef->annot != NULL)
3874
xmlSchemaFreeAnnot(idcDef->annot);
3876
if (idcDef->selector != NULL) {
3877
if (idcDef->selector->xpathComp != NULL)
3878
xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
3879
xmlFree(idcDef->selector);
3882
if (idcDef->fields != NULL) {
3883
cur = idcDef->fields;
3887
if (prev->xpathComp != NULL)
3888
xmlFreePattern((xmlPatternPtr) prev->xpathComp);
3890
} while (cur != NULL);
3896
* xmlSchemaFreeElement:
3897
* @schema: a schema element structure
3899
* Deallocate a Schema Element structure.
3902
xmlSchemaFreeElement(xmlSchemaElementPtr elem)
3906
if (elem->annot != NULL)
3907
xmlSchemaFreeAnnot(elem->annot);
3908
if (elem->contModel != NULL)
3909
xmlRegFreeRegexp(elem->contModel);
3910
if (elem->defVal != NULL)
3911
xmlSchemaFreeValue(elem->defVal);
3916
* xmlSchemaFreeFacet:
3917
* @facet: a schema facet structure
3919
* Deallocate a Schema Facet structure.
3922
xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
3926
if (facet->val != NULL)
3927
xmlSchemaFreeValue(facet->val);
3928
if (facet->regexp != NULL)
3929
xmlRegFreeRegexp(facet->regexp);
3930
if (facet->annot != NULL)
3931
xmlSchemaFreeAnnot(facet->annot);
3936
* xmlSchemaFreeType:
3937
* @type: a schema type structure
3939
* Deallocate a Schema Type structure.
3942
xmlSchemaFreeType(xmlSchemaTypePtr type)
3946
if (type->annot != NULL)
3947
xmlSchemaFreeAnnot(type->annot);
3948
if (type->facets != NULL) {
3949
xmlSchemaFacetPtr facet, next;
3951
facet = type->facets;
3952
while (facet != NULL) {
3954
xmlSchemaFreeFacet(facet);
3958
if (type->attrUses != NULL)
3959
xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
3960
if (type->memberTypes != NULL)
3961
xmlSchemaFreeTypeLinkList(type->memberTypes);
3962
if (type->facetSet != NULL) {
3963
xmlSchemaFacetLinkPtr next, link;
3965
link = type->facetSet;
3970
} while (link != NULL);
3972
if (type->contModel != NULL)
3973
xmlRegFreeRegexp(type->contModel);
3978
* xmlSchemaFreeModelGroupDef:
3979
* @item: a schema model group definition
3981
* Deallocates a schema model group definition.
3984
xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
3986
if (item->annot != NULL)
3987
xmlSchemaFreeAnnot(item->annot);
3992
* xmlSchemaFreeModelGroup:
3993
* @item: a schema model group
3995
* Deallocates a schema model group structure.
3998
xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
4000
if (item->annot != NULL)
4001
xmlSchemaFreeAnnot(item->annot);
4006
xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
4008
if ((list == NULL) || (list->nbItems == 0))
4011
xmlSchemaTreeItemPtr item;
4012
xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
4015
for (i = 0; i < list->nbItems; i++) {
4019
switch (item->type) {
4020
case XML_SCHEMA_TYPE_SIMPLE:
4021
case XML_SCHEMA_TYPE_COMPLEX:
4022
xmlSchemaFreeType((xmlSchemaTypePtr) item);
4024
case XML_SCHEMA_TYPE_ATTRIBUTE:
4025
xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
4027
case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
4028
xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
4030
case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
4031
xmlSchemaFreeAttributeUseProhib(
4032
(xmlSchemaAttributeUseProhibPtr) item);
4034
case XML_SCHEMA_TYPE_ELEMENT:
4035
xmlSchemaFreeElement((xmlSchemaElementPtr) item);
4037
case XML_SCHEMA_TYPE_PARTICLE:
4038
if (item->annot != NULL)
4039
xmlSchemaFreeAnnot(item->annot);
4042
case XML_SCHEMA_TYPE_SEQUENCE:
4043
case XML_SCHEMA_TYPE_CHOICE:
4044
case XML_SCHEMA_TYPE_ALL:
4045
xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
4047
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
4048
xmlSchemaFreeAttributeGroup(
4049
(xmlSchemaAttributeGroupPtr) item);
4051
case XML_SCHEMA_TYPE_GROUP:
4052
xmlSchemaFreeModelGroupDef(
4053
(xmlSchemaModelGroupDefPtr) item);
4055
case XML_SCHEMA_TYPE_ANY:
4056
case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
4057
xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
4059
case XML_SCHEMA_TYPE_IDC_KEY:
4060
case XML_SCHEMA_TYPE_IDC_UNIQUE:
4061
case XML_SCHEMA_TYPE_IDC_KEYREF:
4062
xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
4064
case XML_SCHEMA_TYPE_NOTATION:
4065
xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
4067
case XML_SCHEMA_EXTRA_QNAMEREF:
4068
xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
4071
/* TODO: This should never be hit. */
4072
xmlSchemaPSimpleInternalErr(NULL,
4073
"Internal error: xmlSchemaComponentListFree, "
4074
"unexpected component type '%s'\n",
4075
(const xmlChar *) WXS_ITEM_TYPE_NAME(item));
4086
* @schema: a schema structure
4088
* Deallocate a Schema structure.
4091
xmlSchemaFree(xmlSchemaPtr schema)
4095
/* @volatiles is not used anymore :-/ */
4096
if (schema->volatiles != NULL)
4099
* Note that those slots are not responsible for freeing
4100
* schema components anymore; this will now be done by
4101
* the schema buckets.
4103
if (schema->notaDecl != NULL)
4104
xmlHashFree(schema->notaDecl, NULL);
4105
if (schema->attrDecl != NULL)
4106
xmlHashFree(schema->attrDecl, NULL);
4107
if (schema->attrgrpDecl != NULL)
4108
xmlHashFree(schema->attrgrpDecl, NULL);
4109
if (schema->elemDecl != NULL)
4110
xmlHashFree(schema->elemDecl, NULL);
4111
if (schema->typeDecl != NULL)
4112
xmlHashFree(schema->typeDecl, NULL);
4113
if (schema->groupDecl != NULL)
4114
xmlHashFree(schema->groupDecl, NULL);
4115
if (schema->idcDef != NULL)
4116
xmlHashFree(schema->idcDef, NULL);
4118
if (schema->schemasImports != NULL)
4119
xmlHashFree(schema->schemasImports,
4120
(xmlHashDeallocator) xmlSchemaBucketFree);
4121
if (schema->includes != NULL) {
4122
xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
4124
for (i = 0; i < list->nbItems; i++) {
4125
xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
4127
xmlSchemaItemListFree(list);
4129
if (schema->annot != NULL)
4130
xmlSchemaFreeAnnot(schema->annot);
4131
/* Never free the doc here, since this will be done by the buckets. */
4133
xmlDictFree(schema->dict);
4137
/************************************************************************
4141
************************************************************************/
4143
#ifdef LIBXML_OUTPUT_ENABLED
4146
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
4149
* xmlSchemaElementDump:
4151
* @output: the file output
4156
xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
4157
const xmlChar * name ATTRIBUTE_UNUSED,
4158
const xmlChar * namespace ATTRIBUTE_UNUSED,
4159
const xmlChar * context ATTRIBUTE_UNUSED)
4165
fprintf(output, "Element");
4166
if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
4167
fprintf(output, " (global)");
4168
fprintf(output, ": '%s' ", elem->name);
4169
if (namespace != NULL)
4170
fprintf(output, "ns '%s'", namespace);
4171
fprintf(output, "\n");
4173
if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
4174
fprintf(output, " min %d ", elem->minOccurs);
4175
if (elem->maxOccurs >= UNBOUNDED)
4176
fprintf(output, "max: unbounded\n");
4177
else if (elem->maxOccurs != 1)
4178
fprintf(output, "max: %d\n", elem->maxOccurs);
4180
fprintf(output, "\n");
4184
* Misc other properties.
4186
if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
4187
(elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
4188
(elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
4189
(elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
4190
fprintf(output, " props: ");
4191
if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
4192
fprintf(output, "[fixed] ");
4193
if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
4194
fprintf(output, "[default] ");
4195
if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
4196
fprintf(output, "[abstract] ");
4197
if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
4198
fprintf(output, "[nillable] ");
4199
fprintf(output, "\n");
4202
* Default/fixed value.
4204
if (elem->value != NULL)
4205
fprintf(output, " value: '%s'\n", elem->value);
4209
if (elem->namedType != NULL) {
4210
fprintf(output, " type: '%s' ", elem->namedType);
4211
if (elem->namedTypeNs != NULL)
4212
fprintf(output, "ns '%s'\n", elem->namedTypeNs);
4214
fprintf(output, "\n");
4215
} else if (elem->subtypes != NULL) {
4219
xmlSchemaTypeDump(elem->subtypes, output);
4222
* Substitution group.
4224
if (elem->substGroup != NULL) {
4225
fprintf(output, " substitutionGroup: '%s' ", elem->substGroup);
4226
if (elem->substGroupNs != NULL)
4227
fprintf(output, "ns '%s'\n", elem->substGroupNs);
4229
fprintf(output, "\n");
4234
* xmlSchemaAnnotDump:
4235
* @output: the file output
4236
* @annot: a annotation
4238
* Dump the annotation
4241
xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
4248
content = xmlNodeGetContent(annot->content);
4249
if (content != NULL) {
4250
fprintf(output, " Annot: %s\n", content);
4253
fprintf(output, " Annot: empty\n");
4257
* xmlSchemaContentModelDump:
4258
* @particle: the schema particle
4259
* @output: the file output
4260
* @depth: the depth used for intentation
4262
* Dump a SchemaType structure
4265
xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
4267
xmlChar *str = NULL;
4268
xmlSchemaTreeItemPtr term;
4272
if (particle == NULL)
4274
for (i = 0;((i < depth) && (i < 25));i++)
4275
shift[2 * i] = shift[2 * i + 1] = ' ';
4276
shift[2 * i] = shift[2 * i + 1] = 0;
4277
fprintf(output, shift);
4278
if (particle->children == NULL) {
4279
fprintf(output, "MISSING particle term\n");
4282
term = particle->children;
4284
fprintf(output, "(NULL)");
4286
switch (term->type) {
4287
case XML_SCHEMA_TYPE_ELEMENT:
4288
fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
4289
((xmlSchemaElementPtr)term)->targetNamespace,
4290
((xmlSchemaElementPtr)term)->name));
4293
case XML_SCHEMA_TYPE_SEQUENCE:
4294
fprintf(output, "SEQUENCE");
4296
case XML_SCHEMA_TYPE_CHOICE:
4297
fprintf(output, "CHOICE");
4299
case XML_SCHEMA_TYPE_ALL:
4300
fprintf(output, "ALL");
4302
case XML_SCHEMA_TYPE_ANY:
4303
fprintf(output, "ANY");
4306
fprintf(output, "UNKNOWN\n");
4310
if (particle->minOccurs != 1)
4311
fprintf(output, " min: %d", particle->minOccurs);
4312
if (particle->maxOccurs >= UNBOUNDED)
4313
fprintf(output, " max: unbounded");
4314
else if (particle->maxOccurs != 1)
4315
fprintf(output, " max: %d", particle->maxOccurs);
4316
fprintf(output, "\n");
4318
((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
4319
(term->type == XML_SCHEMA_TYPE_CHOICE) ||
4320
(term->type == XML_SCHEMA_TYPE_ALL)) &&
4321
(term->children != NULL)) {
4322
xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
4325
if (particle->next != NULL)
4326
xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
4331
* xmlSchemaAttrUsesDump:
4332
* @uses: attribute uses list
4333
* @output: the file output
4335
* Dumps a list of attribute use components.
4338
xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
4340
xmlSchemaAttributeUsePtr use;
4341
xmlSchemaAttributeUseProhibPtr prohib;
4342
xmlSchemaQNameRefPtr ref;
4343
const xmlChar *name, *tns;
4344
xmlChar *str = NULL;
4347
if ((uses == NULL) || (uses->nbItems == 0))
4350
fprintf(output, " attributes:\n");
4351
for (i = 0; i < uses->nbItems; i++) {
4352
use = uses->items[i];
4353
if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
4354
fprintf(output, " [prohibition] ");
4355
prohib = (xmlSchemaAttributeUseProhibPtr) use;
4356
name = prohib->name;
4357
tns = prohib->targetNamespace;
4358
} else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
4359
fprintf(output, " [reference] ");
4360
ref = (xmlSchemaQNameRefPtr) use;
4362
tns = ref->targetNamespace;
4364
fprintf(output, " [use] ");
4365
name = WXS_ATTRUSE_DECL_NAME(use);
4366
tns = WXS_ATTRUSE_DECL_TNS(use);
4368
fprintf(output, "'%s'\n",
4369
(const char *) xmlSchemaFormatQName(&str, tns, name));
4375
* xmlSchemaTypeDump:
4376
* @output: the file output
4377
* @type: a type structure
4379
* Dump a SchemaType structure
4382
xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
4385
fprintf(output, "Type: NULL\n");
4388
fprintf(output, "Type: ");
4389
if (type->name != NULL)
4390
fprintf(output, "'%s' ", type->name);
4392
fprintf(output, "(no name) ");
4393
if (type->targetNamespace != NULL)
4394
fprintf(output, "ns '%s' ", type->targetNamespace);
4395
switch (type->type) {
4396
case XML_SCHEMA_TYPE_BASIC:
4397
fprintf(output, "[basic] ");
4399
case XML_SCHEMA_TYPE_SIMPLE:
4400
fprintf(output, "[simple] ");
4402
case XML_SCHEMA_TYPE_COMPLEX:
4403
fprintf(output, "[complex] ");
4405
case XML_SCHEMA_TYPE_SEQUENCE:
4406
fprintf(output, "[sequence] ");
4408
case XML_SCHEMA_TYPE_CHOICE:
4409
fprintf(output, "[choice] ");
4411
case XML_SCHEMA_TYPE_ALL:
4412
fprintf(output, "[all] ");
4414
case XML_SCHEMA_TYPE_UR:
4415
fprintf(output, "[ur] ");
4417
case XML_SCHEMA_TYPE_RESTRICTION:
4418
fprintf(output, "[restriction] ");
4420
case XML_SCHEMA_TYPE_EXTENSION:
4421
fprintf(output, "[extension] ");
4424
fprintf(output, "[unknown type %d] ", type->type);
4427
fprintf(output, "content: ");
4428
switch (type->contentType) {
4429
case XML_SCHEMA_CONTENT_UNKNOWN:
4430
fprintf(output, "[unknown] ");
4432
case XML_SCHEMA_CONTENT_EMPTY:
4433
fprintf(output, "[empty] ");
4435
case XML_SCHEMA_CONTENT_ELEMENTS:
4436
fprintf(output, "[element] ");
4438
case XML_SCHEMA_CONTENT_MIXED:
4439
fprintf(output, "[mixed] ");
4441
case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
4444
case XML_SCHEMA_CONTENT_BASIC:
4445
fprintf(output, "[basic] ");
4447
case XML_SCHEMA_CONTENT_SIMPLE:
4448
fprintf(output, "[simple] ");
4450
case XML_SCHEMA_CONTENT_ANY:
4451
fprintf(output, "[any] ");
4454
fprintf(output, "\n");
4455
if (type->base != NULL) {
4456
fprintf(output, " base type: '%s'", type->base);
4457
if (type->baseNs != NULL)
4458
fprintf(output, " ns '%s'\n", type->baseNs);
4460
fprintf(output, "\n");
4462
if (type->attrUses != NULL)
4463
xmlSchemaAttrUsesDump(type->attrUses, output);
4464
if (type->annot != NULL)
4465
xmlSchemaAnnotDump(output, type->annot);
4466
#ifdef DUMP_CONTENT_MODEL
4467
if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
4468
(type->subtypes != NULL)) {
4469
xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
4477
* @output: the file output
4478
* @schema: a schema structure
4480
* Dump a Schema structure.
4483
xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
4487
if (schema == NULL) {
4488
fprintf(output, "Schemas: NULL\n");
4491
fprintf(output, "Schemas: ");
4492
if (schema->name != NULL)
4493
fprintf(output, "%s, ", schema->name);
4495
fprintf(output, "no name, ");
4496
if (schema->targetNamespace != NULL)
4497
fprintf(output, "%s", (const char *) schema->targetNamespace);
4499
fprintf(output, "no target namespace");
4500
fprintf(output, "\n");
4501
if (schema->annot != NULL)
4502
xmlSchemaAnnotDump(output, schema->annot);
4503
xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
4505
xmlHashScanFull(schema->elemDecl,
4506
(xmlHashScannerFull) xmlSchemaElementDump, output);
4509
#ifdef DEBUG_IDC_NODE_TABLE
4511
* xmlSchemaDebugDumpIDCTable:
4512
* @vctxt: the WXS validation context
4514
* Displays the current IDC table for debug purposes.
4517
xmlSchemaDebugDumpIDCTable(FILE * output,
4518
const xmlChar *namespaceName,
4519
const xmlChar *localName,
4520
xmlSchemaPSVIIDCBindingPtr bind)
4522
xmlChar *str = NULL;
4523
const xmlChar *value;
4524
xmlSchemaPSVIIDCNodePtr tab;
4525
xmlSchemaPSVIIDCKeyPtr key;
4528
fprintf(output, "IDC: TABLES on '%s'\n",
4529
xmlSchemaFormatQName(&str, namespaceName, localName));
4535
fprintf(output, "IDC: BINDING '%s' (%d)\n",
4536
xmlSchemaGetComponentQName(&str,
4537
bind->definition), bind->nbNodes);
4539
for (i = 0; i < bind->nbNodes; i++) {
4540
tab = bind->nodeTable[i];
4541
fprintf(output, " ( ");
4542
for (j = 0; j < bind->definition->nbFields; j++) {
4544
if ((key != NULL) && (key->val != NULL)) {
4545
res = xmlSchemaGetCanonValue(key->val, &value);
4547
fprintf(output, "'%s' ", value);
4549
fprintf(output, "CANON-VALUE-FAILED ");
4551
FREE_AND_NULL(value)
4552
} else if (key != NULL)
4553
fprintf(output, "(no val), ");
4555
fprintf(output, "(key missing), ");
4557
fprintf(output, ")\n");
4559
if (bind->dupls && bind->dupls->nbItems) {
4560
fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems);
4561
for (i = 0; i < bind->dupls->nbItems; i++) {
4562
tab = bind->dupls->items[i];
4563
fprintf(output, " ( ");
4564
for (j = 0; j < bind->definition->nbFields; j++) {
4566
if ((key != NULL) && (key->val != NULL)) {
4567
res = xmlSchemaGetCanonValue(key->val, &value);
4569
fprintf(output, "'%s' ", value);
4571
fprintf(output, "CANON-VALUE-FAILED ");
4573
FREE_AND_NULL(value)
4574
} else if (key != NULL)
4575
fprintf(output, "(no val), ");
4577
fprintf(output, "(key missing), ");
4579
fprintf(output, ")\n");
4583
} while (bind != NULL);
4585
#endif /* DEBUG_IDC */
4586
#endif /* LIBXML_OUTPUT_ENABLED */
4588
/************************************************************************
4592
************************************************************************/
4595
* xmlSchemaGetPropNode:
4596
* @node: the element node
4597
* @name: the name of the attribute
4599
* Seeks an attribute with a name of @name in
4602
* Returns the attribute or NULL if not present.
4605
xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
4609
if ((node == NULL) || (name == NULL))
4611
prop = node->properties;
4612
while (prop != NULL) {
4613
if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
4621
* xmlSchemaGetPropNodeNs:
4622
* @node: the element node
4624
* @name: the name of the attribute
4626
* Seeks an attribute with a local name of @name and
4627
* a namespace URI of @uri.
4629
* Returns the attribute or NULL if not present.
4632
xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
4636
if ((node == NULL) || (name == NULL))
4638
prop = node->properties;
4639
while (prop != NULL) {
4640
if ((prop->ns != NULL) &&
4641
xmlStrEqual(prop->name, BAD_CAST name) &&
4642
xmlStrEqual(prop->ns->href, BAD_CAST uri))
4649
static const xmlChar *
4650
xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
4655
val = xmlNodeGetContent(node);
4657
val = xmlStrdup((xmlChar *)"");
4658
ret = xmlDictLookup(ctxt->dict, val, -1);
4663
static const xmlChar *
4664
xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
4666
return((const xmlChar*) xmlNodeGetContent(node));
4671
* @ctxt: the parser context
4673
* @name: the property name
4675
* Read a attribute value and internalize the string
4677
* Returns the string or NULL if not present.
4679
static const xmlChar *
4680
xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
4686
val = xmlGetNoNsProp(node, BAD_CAST name);
4689
ret = xmlDictLookup(ctxt->dict, val, -1);
4694
/************************************************************************
4696
* Parsing functions *
4698
************************************************************************/
4700
#define WXS_FIND_GLOBAL_ITEM(slot) \
4701
if (xmlStrEqual(nsName, schema->targetNamespace)) { \
4702
ret = xmlHashLookup(schema->slot, name); \
4703
if (ret != NULL) goto exit; \
4705
if (xmlHashSize(schema->schemasImports) > 1) { \
4706
xmlSchemaImportPtr import; \
4707
if (nsName == NULL) \
4708
import = xmlHashLookup(schema->schemasImports, \
4709
XML_SCHEMAS_NO_NAMESPACE); \
4711
import = xmlHashLookup(schema->schemasImports, nsName); \
4712
if (import == NULL) \
4714
ret = xmlHashLookup(import->schema->slot, name); \
4719
* @schema: the schema context
4720
* @name: the element name
4721
* @ns: the element namespace
4723
* Lookup a global element declaration in the schema.
4725
* Returns the element declaration or NULL if not found.
4727
static xmlSchemaElementPtr
4728
xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
4729
const xmlChar * nsName)
4731
xmlSchemaElementPtr ret = NULL;
4733
if ((name == NULL) || (schema == NULL))
4735
if (schema != NULL) {
4736
WXS_FIND_GLOBAL_ITEM(elemDecl)
4742
fprintf(stderr, "Unable to lookup element decl. %s", name);
4744
fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
4753
* @schema: the main schema
4754
* @name: the type's name
4755
* nsName: the type's namespace
4757
* Lookup a type in the schemas or the predefined types
4759
* Returns the group definition or NULL if not found.
4761
static xmlSchemaTypePtr
4762
xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
4763
const xmlChar * nsName)
4765
xmlSchemaTypePtr ret = NULL;
4769
/* First try the built-in types. */
4770
if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
4771
ret = xmlSchemaGetPredefinedType(name, nsName);
4775
* Note that we try the parsed schemas as well here
4776
* since one might have parsed the S4S, which contain more
4777
* than the built-in types.
4778
* TODO: Can we optimize this?
4781
if (schema != NULL) {
4782
WXS_FIND_GLOBAL_ITEM(typeDecl)
4789
fprintf(stderr, "Unable to lookup type %s", name);
4791
fprintf(stderr, "Unable to lookup type %s:%s", name,
4799
* xmlSchemaGetAttributeDecl:
4800
* @schema: the context of the schema
4801
* @name: the name of the attribute
4802
* @ns: the target namespace of the attribute
4804
* Lookup a an attribute in the schema or imported schemas
4806
* Returns the attribute declaration or NULL if not found.
4808
static xmlSchemaAttributePtr
4809
xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
4810
const xmlChar * nsName)
4812
xmlSchemaAttributePtr ret = NULL;
4814
if ((name == NULL) || (schema == NULL))
4816
if (schema != NULL) {
4817
WXS_FIND_GLOBAL_ITEM(attrDecl)
4823
fprintf(stderr, "Unable to lookup attribute %s", name);
4825
fprintf(stderr, "Unable to lookup attribute %s:%s", name,
4833
* xmlSchemaGetAttributeGroup:
4834
* @schema: the context of the schema
4835
* @name: the name of the attribute group
4836
* @ns: the target namespace of the attribute group
4838
* Lookup a an attribute group in the schema or imported schemas
4840
* Returns the attribute group definition or NULL if not found.
4842
static xmlSchemaAttributeGroupPtr
4843
xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
4844
const xmlChar * nsName)
4846
xmlSchemaAttributeGroupPtr ret = NULL;
4848
if ((name == NULL) || (schema == NULL))
4850
if (schema != NULL) {
4851
WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
4855
if ((ret != NULL) && (ret->redef != NULL)) {
4856
* Return the last redefinition. *
4863
fprintf(stderr, "Unable to lookup attribute group %s", name);
4865
fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
4873
* xmlSchemaGetGroup:
4874
* @schema: the context of the schema
4875
* @name: the name of the group
4876
* @ns: the target namespace of the group
4878
* Lookup a group in the schema or imported schemas
4880
* Returns the group definition or NULL if not found.
4882
static xmlSchemaModelGroupDefPtr
4883
xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
4884
const xmlChar * nsName)
4886
xmlSchemaModelGroupDefPtr ret = NULL;
4888
if ((name == NULL) || (schema == NULL))
4890
if (schema != NULL) {
4891
WXS_FIND_GLOBAL_ITEM(groupDecl)
4898
fprintf(stderr, "Unable to lookup group %s", name);
4900
fprintf(stderr, "Unable to lookup group %s:%s", name,
4907
static xmlSchemaNotationPtr
4908
xmlSchemaGetNotation(xmlSchemaPtr schema,
4909
const xmlChar *name,
4910
const xmlChar *nsName)
4912
xmlSchemaNotationPtr ret = NULL;
4914
if ((name == NULL) || (schema == NULL))
4916
if (schema != NULL) {
4917
WXS_FIND_GLOBAL_ITEM(notaDecl)
4923
static xmlSchemaIDCPtr
4924
xmlSchemaGetIDC(xmlSchemaPtr schema,
4925
const xmlChar *name,
4926
const xmlChar *nsName)
4928
xmlSchemaIDCPtr ret = NULL;
4930
if ((name == NULL) || (schema == NULL))
4932
if (schema != NULL) {
4933
WXS_FIND_GLOBAL_ITEM(idcDef)
4940
* xmlSchemaGetNamedComponent:
4941
* @schema: the schema
4942
* @name: the name of the group
4943
* @ns: the target namespace of the group
4945
* Lookup a group in the schema or imported schemas
4947
* Returns the group definition or NULL if not found.
4949
static xmlSchemaBasicItemPtr
4950
xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
4951
xmlSchemaTypeType itemType,
4952
const xmlChar *name,
4953
const xmlChar *targetNs)
4956
case XML_SCHEMA_TYPE_GROUP:
4957
return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
4959
case XML_SCHEMA_TYPE_ELEMENT:
4960
return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
4968
/************************************************************************
4970
* Parsing functions *
4972
************************************************************************/
4974
#define IS_BLANK_NODE(n) \
4975
(((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
4980
* @len: the length of the string or -1
4982
* Check if a string is ignorable
4984
* Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
4987
xmlSchemaIsBlank(xmlChar * str, int len)
4993
if (!(IS_BLANK_CH(*str)))
4997
} else while ((*str != 0) && (len != 0)) {
4998
if (!(IS_BLANK_CH(*str)))
5007
#define WXS_COMP_NAME(c, t) ((t) (c))->name
5008
#define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
5010
* xmlSchemaFindRedefCompInGraph:
5011
* ATTENTION TODO: This uses pointer comp. for strings.
5013
static xmlSchemaBasicItemPtr
5014
xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
5015
xmlSchemaTypeType type,
5016
const xmlChar *name,
5017
const xmlChar *nsName)
5019
xmlSchemaBasicItemPtr ret;
5022
if ((bucket == NULL) || (name == NULL))
5024
if ((bucket->globals == NULL) ||
5025
(bucket->globals->nbItems == 0))
5028
* Search in global components.
5030
for (i = 0; i < bucket->globals->nbItems; i++) {
5031
ret = bucket->globals->items[i];
5032
if (ret->type == type) {
5034
case XML_SCHEMA_TYPE_COMPLEX:
5035
case XML_SCHEMA_TYPE_SIMPLE:
5036
if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
5037
(WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
5043
case XML_SCHEMA_TYPE_GROUP:
5044
if ((WXS_COMP_NAME(ret,
5045
xmlSchemaModelGroupDefPtr) == name) &&
5047
xmlSchemaModelGroupDefPtr) == nsName))
5052
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
5053
if ((WXS_COMP_NAME(ret,
5054
xmlSchemaAttributeGroupPtr) == name) &&
5056
xmlSchemaAttributeGroupPtr) == nsName))
5062
/* Should not be hit. */
5069
* Process imported/included schemas.
5071
if (bucket->relations != NULL) {
5072
xmlSchemaSchemaRelationPtr rel = bucket->relations;
5075
* TODO: Marking the bucket will not avoid multiple searches
5076
* in the same schema, but avoids at least circularity.
5078
bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
5080
if ((rel->bucket != NULL) &&
5081
((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
5082
ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
5083
type, name, nsName);
5088
} while (rel != NULL);
5089
bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
5095
* xmlSchemaAddNotation:
5096
* @ctxt: a schema parser context
5097
* @schema: the schema being built
5098
* @name: the item name
5100
* Add an XML schema annotation declaration
5101
* *WARNING* this interface is highly subject to change
5103
* Returns the new struture or NULL in case of error
5105
static xmlSchemaNotationPtr
5106
xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5107
const xmlChar *name, const xmlChar *nsName,
5108
xmlNodePtr node ATTRIBUTE_UNUSED)
5110
xmlSchemaNotationPtr ret = NULL;
5112
if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5115
ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
5117
xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
5120
memset(ret, 0, sizeof(xmlSchemaNotation));
5121
ret->type = XML_SCHEMA_TYPE_NOTATION;
5123
ret->targetNamespace = nsName;
5124
/* TODO: do we need the node to be set?
5125
* ret->node = node;*/
5126
WXS_ADD_GLOBAL(ctxt, ret);
5131
* xmlSchemaAddAttribute:
5132
* @ctxt: a schema parser context
5133
* @schema: the schema being built
5134
* @name: the item name
5135
* @namespace: the namespace
5137
* Add an XML schema Attrribute declaration
5138
* *WARNING* this interface is highly subject to change
5140
* Returns the new struture or NULL in case of error
5142
static xmlSchemaAttributePtr
5143
xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5144
const xmlChar * name, const xmlChar * nsName,
5145
xmlNodePtr node, int topLevel)
5147
xmlSchemaAttributePtr ret = NULL;
5149
if ((ctxt == NULL) || (schema == NULL))
5152
ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
5154
xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
5157
memset(ret, 0, sizeof(xmlSchemaAttribute));
5158
ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
5161
ret->targetNamespace = nsName;
5164
WXS_ADD_GLOBAL(ctxt, ret);
5166
WXS_ADD_LOCAL(ctxt, ret);
5167
WXS_ADD_PENDING(ctxt, ret);
5172
* xmlSchemaAddAttributeUse:
5173
* @ctxt: a schema parser context
5174
* @schema: the schema being built
5175
* @name: the item name
5176
* @namespace: the namespace
5178
* Add an XML schema Attrribute declaration
5179
* *WARNING* this interface is highly subject to change
5181
* Returns the new struture or NULL in case of error
5183
static xmlSchemaAttributeUsePtr
5184
xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
5187
xmlSchemaAttributeUsePtr ret = NULL;
5192
ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
5194
xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
5197
memset(ret, 0, sizeof(xmlSchemaAttributeUse));
5198
ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
5201
WXS_ADD_LOCAL(pctxt, ret);
5206
* xmlSchemaAddRedef:
5208
* Adds a redefinition information. This is used at a later stage to:
5209
* resolve references to the redefined components and to check constraints.
5211
static xmlSchemaRedefPtr
5212
xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
5213
xmlSchemaBucketPtr targetBucket,
5215
const xmlChar *refName,
5216
const xmlChar *refTargetNs)
5218
xmlSchemaRedefPtr ret;
5220
ret = (xmlSchemaRedefPtr)
5221
xmlMalloc(sizeof(xmlSchemaRedef));
5223
xmlSchemaPErrMemory(pctxt,
5224
"allocating redefinition info", NULL);
5227
memset(ret, 0, sizeof(xmlSchemaRedef));
5229
ret->targetBucket = targetBucket;
5230
ret->refName = refName;
5231
ret->refTargetNs = refTargetNs;
5232
if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
5233
WXS_CONSTRUCTOR(pctxt)->redefs = ret;
5235
WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
5236
WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
5242
* xmlSchemaAddAttributeGroupDefinition:
5243
* @ctxt: a schema parser context
5244
* @schema: the schema being built
5245
* @name: the item name
5246
* @nsName: the target namespace
5247
* @node: the corresponding node
5249
* Add an XML schema Attrribute Group definition.
5251
* Returns the new struture or NULL in case of error
5253
static xmlSchemaAttributeGroupPtr
5254
xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
5255
xmlSchemaPtr schema ATTRIBUTE_UNUSED,
5256
const xmlChar *name,
5257
const xmlChar *nsName,
5260
xmlSchemaAttributeGroupPtr ret = NULL;
5262
if ((pctxt == NULL) || (name == NULL))
5265
ret = (xmlSchemaAttributeGroupPtr)
5266
xmlMalloc(sizeof(xmlSchemaAttributeGroup));
5268
xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
5271
memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
5272
ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
5274
ret->targetNamespace = nsName;
5277
/* TODO: Remove the flag. */
5278
ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
5279
if (pctxt->isRedefine) {
5280
pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
5282
if (pctxt->redef == NULL) {
5286
pctxt->redefCounter = 0;
5288
WXS_ADD_GLOBAL(pctxt, ret);
5289
WXS_ADD_PENDING(pctxt, ret);
5294
* xmlSchemaAddElement:
5295
* @ctxt: a schema parser context
5296
* @schema: the schema being built
5297
* @name: the type name
5298
* @namespace: the type namespace
5300
* Add an XML schema Element declaration
5301
* *WARNING* this interface is highly subject to change
5303
* Returns the new struture or NULL in case of error
5305
static xmlSchemaElementPtr
5306
xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
5307
const xmlChar * name, const xmlChar * nsName,
5308
xmlNodePtr node, int topLevel)
5310
xmlSchemaElementPtr ret = NULL;
5312
if ((ctxt == NULL) || (name == NULL))
5315
ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
5317
xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
5320
memset(ret, 0, sizeof(xmlSchemaElement));
5321
ret->type = XML_SCHEMA_TYPE_ELEMENT;
5323
ret->targetNamespace = nsName;
5327
WXS_ADD_GLOBAL(ctxt, ret);
5329
WXS_ADD_LOCAL(ctxt, ret);
5330
WXS_ADD_PENDING(ctxt, ret);
5336
* @ctxt: a schema parser context
5337
* @schema: the schema being built
5338
* @name: the item name
5339
* @namespace: the namespace
5341
* Add an XML schema item
5342
* *WARNING* this interface is highly subject to change
5344
* Returns the new struture or NULL in case of error
5346
static xmlSchemaTypePtr
5347
xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5348
xmlSchemaTypeType type,
5349
const xmlChar * name, const xmlChar * nsName,
5350
xmlNodePtr node, int topLevel)
5352
xmlSchemaTypePtr ret = NULL;
5354
if ((ctxt == NULL) || (schema == NULL))
5357
ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
5359
xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
5362
memset(ret, 0, sizeof(xmlSchemaType));
5365
ret->targetNamespace = nsName;
5368
if (ctxt->isRedefine) {
5369
ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5371
if (ctxt->redef == NULL) {
5375
ctxt->redefCounter = 0;
5377
WXS_ADD_GLOBAL(ctxt, ret);
5379
WXS_ADD_LOCAL(ctxt, ret);
5380
WXS_ADD_PENDING(ctxt, ret);
5384
static xmlSchemaQNameRefPtr
5385
xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
5386
xmlSchemaTypeType refType,
5387
const xmlChar *refName,
5388
const xmlChar *refNs)
5390
xmlSchemaQNameRefPtr ret;
5392
ret = (xmlSchemaQNameRefPtr)
5393
xmlMalloc(sizeof(xmlSchemaQNameRef));
5395
xmlSchemaPErrMemory(pctxt,
5396
"allocating QName reference item", NULL);
5400
ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
5401
ret->name = refName;
5402
ret->targetNamespace = refNs;
5404
ret->itemType = refType;
5406
* Store the reference item in the schema.
5408
WXS_ADD_LOCAL(pctxt, ret);
5412
static xmlSchemaAttributeUseProhibPtr
5413
xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
5415
xmlSchemaAttributeUseProhibPtr ret;
5417
ret = (xmlSchemaAttributeUseProhibPtr)
5418
xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
5420
xmlSchemaPErrMemory(pctxt,
5421
"allocating attribute use prohibition", NULL);
5424
memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
5425
ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
5426
WXS_ADD_LOCAL(pctxt, ret);
5432
* xmlSchemaAddModelGroup:
5433
* @ctxt: a schema parser context
5434
* @schema: the schema being built
5435
* @type: the "compositor" type of the model group
5436
* @node: the node in the schema doc
5438
* Adds a schema model group
5439
* *WARNING* this interface is highly subject to change
5441
* Returns the new struture or NULL in case of error
5443
static xmlSchemaModelGroupPtr
5444
xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
5445
xmlSchemaPtr schema,
5446
xmlSchemaTypeType type,
5449
xmlSchemaModelGroupPtr ret = NULL;
5451
if ((ctxt == NULL) || (schema == NULL))
5454
ret = (xmlSchemaModelGroupPtr)
5455
xmlMalloc(sizeof(xmlSchemaModelGroup));
5457
xmlSchemaPErrMemory(ctxt, "allocating model group component",
5461
memset(ret, 0, sizeof(xmlSchemaModelGroup));
5464
WXS_ADD_LOCAL(ctxt, ret);
5465
if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
5466
(type == XML_SCHEMA_TYPE_CHOICE))
5467
WXS_ADD_PENDING(ctxt, ret);
5473
* xmlSchemaAddParticle:
5474
* @ctxt: a schema parser context
5475
* @schema: the schema being built
5476
* @node: the corresponding node in the schema doc
5477
* @min: the minOccurs
5478
* @max: the maxOccurs
5480
* Adds an XML schema particle component.
5481
* *WARNING* this interface is highly subject to change
5483
* Returns the new struture or NULL in case of error
5485
static xmlSchemaParticlePtr
5486
xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
5487
xmlNodePtr node, int min, int max)
5489
xmlSchemaParticlePtr ret = NULL;
5494
fprintf(stderr, "Adding particle component\n");
5496
ret = (xmlSchemaParticlePtr)
5497
xmlMalloc(sizeof(xmlSchemaParticle));
5499
xmlSchemaPErrMemory(ctxt, "allocating particle component",
5503
ret->type = XML_SCHEMA_TYPE_PARTICLE;
5506
ret->minOccurs = min;
5507
ret->maxOccurs = max;
5509
ret->children = NULL;
5511
WXS_ADD_LOCAL(ctxt, ret);
5513
* Note that addition to pending components will be done locally
5514
* to the specific parsing function, since the most particles
5515
* need not to be fixed up (i.e. the reference to be resolved).
5516
* REMOVED: WXS_ADD_PENDING(ctxt, ret);
5522
* xmlSchemaAddModelGroupDefinition:
5523
* @ctxt: a schema validation context
5524
* @schema: the schema being built
5525
* @name: the group name
5527
* Add an XML schema Group definition
5529
* Returns the new struture or NULL in case of error
5531
static xmlSchemaModelGroupDefPtr
5532
xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
5533
xmlSchemaPtr schema,
5534
const xmlChar *name,
5535
const xmlChar *nsName,
5538
xmlSchemaModelGroupDefPtr ret = NULL;
5540
if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5543
ret = (xmlSchemaModelGroupDefPtr)
5544
xmlMalloc(sizeof(xmlSchemaModelGroupDef));
5546
xmlSchemaPErrMemory(ctxt, "adding group", NULL);
5549
memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
5551
ret->type = XML_SCHEMA_TYPE_GROUP;
5553
ret->targetNamespace = nsName;
5555
if (ctxt->isRedefine) {
5556
ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
5558
if (ctxt->redef == NULL) {
5562
ctxt->redefCounter = 0;
5564
WXS_ADD_GLOBAL(ctxt, ret);
5565
WXS_ADD_PENDING(ctxt, ret);
5570
* xmlSchemaNewWildcardNs:
5571
* @ctxt: a schema validation context
5573
* Creates a new wildcard namespace constraint.
5575
* Returns the new struture or NULL in case of error
5577
static xmlSchemaWildcardNsPtr
5578
xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
5580
xmlSchemaWildcardNsPtr ret;
5582
ret = (xmlSchemaWildcardNsPtr)
5583
xmlMalloc(sizeof(xmlSchemaWildcardNs));
5585
xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
5593
static xmlSchemaIDCPtr
5594
xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5595
const xmlChar *name, const xmlChar *nsName,
5596
int category, xmlNodePtr node)
5598
xmlSchemaIDCPtr ret = NULL;
5600
if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
5603
ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
5605
xmlSchemaPErrMemory(ctxt,
5606
"allocating an identity-constraint definition", NULL);
5609
memset(ret, 0, sizeof(xmlSchemaIDC));
5610
/* The target namespace of the parent element declaration. */
5611
ret->targetNamespace = nsName;
5613
ret->type = category;
5616
WXS_ADD_GLOBAL(ctxt, ret);
5618
* Only keyrefs need to be fixup up.
5620
if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
5621
WXS_ADD_PENDING(ctxt, ret);
5626
* xmlSchemaAddWildcard:
5627
* @ctxt: a schema validation context
5631
* It corresponds to a xsd:anyAttribute and xsd:any.
5633
* Returns the new struture or NULL in case of error
5635
static xmlSchemaWildcardPtr
5636
xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
5637
xmlSchemaTypeType type, xmlNodePtr node)
5639
xmlSchemaWildcardPtr ret = NULL;
5641
if ((ctxt == NULL) || (schema == NULL))
5644
ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
5646
xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
5649
memset(ret, 0, sizeof(xmlSchemaWildcard));
5652
WXS_ADD_LOCAL(ctxt, ret);
5657
xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
5661
if (group->members != NULL)
5662
xmlSchemaItemListFree(group->members);
5666
static xmlSchemaSubstGroupPtr
5667
xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
5668
xmlSchemaElementPtr head)
5670
xmlSchemaSubstGroupPtr ret;
5672
/* Init subst group hash. */
5673
if (WXS_SUBST_GROUPS(pctxt) == NULL) {
5674
WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
5675
if (WXS_SUBST_GROUPS(pctxt) == NULL)
5678
/* Create a new substitution group. */
5679
ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
5681
xmlSchemaPErrMemory(NULL,
5682
"allocating a substitution group container", NULL);
5685
memset(ret, 0, sizeof(xmlSchemaSubstGroup));
5687
/* Create list of members. */
5688
ret->members = xmlSchemaItemListCreate();
5689
if (ret->members == NULL) {
5690
xmlSchemaSubstGroupFree(ret);
5693
/* Add subst group to hash. */
5694
if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
5695
head->name, head->targetNamespace, ret) != 0) {
5696
PERROR_INT("xmlSchemaSubstGroupAdd",
5697
"failed to add a new substitution container");
5698
xmlSchemaSubstGroupFree(ret);
5704
static xmlSchemaSubstGroupPtr
5705
xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
5706
xmlSchemaElementPtr head)
5708
if (WXS_SUBST_GROUPS(pctxt) == NULL)
5710
return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
5711
head->name, head->targetNamespace));
5716
* xmlSchemaAddElementSubstitutionMember:
5717
* @pctxt: a schema parser context
5718
* @head: the head of the substitution group
5719
* @member: the new member of the substitution group
5721
* Allocate a new annotation structure.
5723
* Returns the newly allocated structure or NULL in case or error
5726
xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
5727
xmlSchemaElementPtr head,
5728
xmlSchemaElementPtr member)
5730
xmlSchemaSubstGroupPtr substGroup = NULL;
5732
if ((pctxt == NULL) || (head == NULL) || (member == NULL))
5735
substGroup = xmlSchemaSubstGroupGet(pctxt, head);
5736
if (substGroup == NULL)
5737
substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
5738
if (substGroup == NULL)
5740
if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
5745
/************************************************************************
5747
* Utilities for parsing *
5749
************************************************************************/
5752
* xmlSchemaPValAttrNodeQNameValue:
5753
* @ctxt: a schema parser context
5754
* @schema: the schema context
5755
* @ownerDes: the designation of the parent element
5756
* @ownerItem: the parent as a schema object
5757
* @value: the QName value
5758
* @local: the resulting local part if found, the attribute value otherwise
5759
* @uri: the resulting namespace URI if found
5761
* Extracts the local name and the URI of a QName value and validates it.
5762
* This one is intended to be used on attribute values that
5763
* should resolve to schema components.
5765
* Returns 0, in case the QName is valid, a positive error code
5766
* if not valid and -1 if an internal error occurs.
5769
xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
5770
xmlSchemaPtr schema,
5771
xmlSchemaBasicItemPtr ownerItem,
5773
const xmlChar *value,
5774
const xmlChar **uri,
5775
const xmlChar **local)
5777
const xmlChar *pref;
5783
ret = xmlValidateQName(value, 1);
5785
xmlSchemaPSimpleTypeErr(ctxt,
5786
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5787
ownerItem, (xmlNodePtr) attr,
5788
xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
5789
NULL, value, NULL, NULL, NULL);
5795
if (!strchr((char *) value, ':')) {
5796
ns = xmlSearchNs(attr->doc, attr->parent, NULL);
5798
*uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5799
else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
5800
/* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
5801
* parser context. */
5803
* This one takes care of included schemas with no
5806
*uri = ctxt->targetNamespace;
5808
*local = xmlDictLookup(ctxt->dict, value, -1);
5812
* At this point xmlSplitQName3 has to return a local name.
5814
*local = xmlSplitQName3(value, &len);
5815
*local = xmlDictLookup(ctxt->dict, *local, -1);
5816
pref = xmlDictLookup(ctxt->dict, value, len);
5817
ns = xmlSearchNs(attr->doc, attr->parent, pref);
5819
xmlSchemaPSimpleTypeErr(ctxt,
5820
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5821
ownerItem, (xmlNodePtr) attr,
5822
xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
5823
"The value '%s' of simple type 'xs:QName' has no "
5824
"corresponding namespace declaration in scope", value, NULL);
5827
*uri = xmlDictLookup(ctxt->dict, ns->href, -1);
5833
* xmlSchemaPValAttrNodeQName:
5834
* @ctxt: a schema parser context
5835
* @schema: the schema context
5836
* @ownerDes: the designation of the owner element
5837
* @ownerItem: the owner as a schema object
5838
* @attr: the attribute node
5839
* @local: the resulting local part if found, the attribute value otherwise
5840
* @uri: the resulting namespace URI if found
5842
* Extracts and validates the QName of an attribute value.
5843
* This one is intended to be used on attribute values that
5844
* should resolve to schema components.
5846
* Returns 0, in case the QName is valid, a positive error code
5847
* if not valid and -1 if an internal error occurs.
5850
xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
5851
xmlSchemaPtr schema,
5852
xmlSchemaBasicItemPtr ownerItem,
5854
const xmlChar **uri,
5855
const xmlChar **local)
5857
const xmlChar *value;
5859
value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
5860
return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
5861
ownerItem, attr, value, uri, local));
5865
* xmlSchemaPValAttrQName:
5866
* @ctxt: a schema parser context
5867
* @schema: the schema context
5868
* @ownerDes: the designation of the parent element
5869
* @ownerItem: the owner as a schema object
5870
* @ownerElem: the parent node of the attribute
5871
* @name: the name of the attribute
5872
* @local: the resulting local part if found, the attribute value otherwise
5873
* @uri: the resulting namespace URI if found
5875
* Extracts and validates the QName of an attribute value.
5877
* Returns 0, in case the QName is valid, a positive error code
5878
* if not valid and -1 if an internal error occurs.
5881
xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
5882
xmlSchemaPtr schema,
5883
xmlSchemaBasicItemPtr ownerItem,
5884
xmlNodePtr ownerElem,
5886
const xmlChar **uri,
5887
const xmlChar **local)
5891
attr = xmlSchemaGetPropNode(ownerElem, name);
5897
return (xmlSchemaPValAttrNodeQName(ctxt, schema,
5898
ownerItem, attr, uri, local));
5902
* xmlSchemaPValAttrID:
5903
* @ctxt: a schema parser context
5904
* @schema: the schema context
5905
* @ownerDes: the designation of the parent element
5906
* @ownerItem: the owner as a schema object
5907
* @ownerElem: the parent node of the attribute
5908
* @name: the name of the attribute
5910
* Extracts and validates the ID of an attribute value.
5912
* Returns 0, in case the ID is valid, a positive error code
5913
* if not valid and -1 if an internal error occurs.
5916
xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
5919
const xmlChar *value;
5923
value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
5924
ret = xmlValidateNCName(value, 1);
5927
* NOTE: the IDness might have already be declared in the DTD
5929
if (attr->atype != XML_ATTRIBUTE_ID) {
5934
* TODO: Use xmlSchemaStrip here; it's not exported at this
5937
strip = xmlSchemaCollapseString(value);
5938
if (strip != NULL) {
5939
xmlFree((xmlChar *) value);
5942
res = xmlAddID(NULL, attr->doc, value, attr);
5944
ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5945
xmlSchemaPSimpleTypeErr(ctxt,
5946
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5947
NULL, (xmlNodePtr) attr,
5948
xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5949
NULL, NULL, "Duplicate value '%s' of simple "
5950
"type 'xs:ID'", value, NULL);
5952
attr->atype = XML_ATTRIBUTE_ID;
5954
} else if (ret > 0) {
5955
ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
5956
xmlSchemaPSimpleTypeErr(ctxt,
5957
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
5958
NULL, (xmlNodePtr) attr,
5959
xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
5960
NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
5961
"not a valid 'xs:NCName'",
5965
xmlFree((xmlChar *)value);
5971
xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
5972
xmlNodePtr ownerElem,
5973
const xmlChar *name)
5977
attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
5980
return(xmlSchemaPValAttrNodeID(ctxt, attr));
5986
* @ctxt: a schema validation context
5987
* @node: a subtree containing XML Schema informations
5989
* Get the maxOccurs property
5991
* Returns the default if not found, or the value
5994
xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
5995
int min, int max, int def, const char *expected)
5997
const xmlChar *val, *cur;
6001
attr = xmlSchemaGetPropNode(node, "maxOccurs");
6004
val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6006
if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
6007
if (max != UNBOUNDED) {
6008
xmlSchemaPSimpleTypeErr(ctxt,
6009
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6010
/* XML_SCHEMAP_INVALID_MINOCCURS, */
6011
NULL, (xmlNodePtr) attr, NULL, expected,
6012
val, NULL, NULL, NULL);
6015
return (UNBOUNDED); /* encoding it with -1 might be another option */
6019
while (IS_BLANK_CH(*cur))
6022
xmlSchemaPSimpleTypeErr(ctxt,
6023
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6024
/* XML_SCHEMAP_INVALID_MINOCCURS, */
6025
NULL, (xmlNodePtr) attr, NULL, expected,
6026
val, NULL, NULL, NULL);
6029
while ((*cur >= '0') && (*cur <= '9')) {
6030
ret = ret * 10 + (*cur - '0');
6033
while (IS_BLANK_CH(*cur))
6036
* TODO: Restrict the maximal value to Integer.
6038
if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6039
xmlSchemaPSimpleTypeErr(ctxt,
6040
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6041
/* XML_SCHEMAP_INVALID_MINOCCURS, */
6042
NULL, (xmlNodePtr) attr, NULL, expected,
6043
val, NULL, NULL, NULL);
6051
* @ctxt: a schema validation context
6052
* @node: a subtree containing XML Schema informations
6054
* Get the minOccurs property
6056
* Returns the default if not found, or the value
6059
xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
6060
int min, int max, int def, const char *expected)
6062
const xmlChar *val, *cur;
6066
attr = xmlSchemaGetPropNode(node, "minOccurs");
6069
val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6071
while (IS_BLANK_CH(*cur))
6074
xmlSchemaPSimpleTypeErr(ctxt,
6075
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6076
/* XML_SCHEMAP_INVALID_MINOCCURS, */
6077
NULL, (xmlNodePtr) attr, NULL, expected,
6078
val, NULL, NULL, NULL);
6081
while ((*cur >= '0') && (*cur <= '9')) {
6082
ret = ret * 10 + (*cur - '0');
6085
while (IS_BLANK_CH(*cur))
6088
* TODO: Restrict the maximal value to Integer.
6090
if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
6091
xmlSchemaPSimpleTypeErr(ctxt,
6092
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6093
/* XML_SCHEMAP_INVALID_MINOCCURS, */
6094
NULL, (xmlNodePtr) attr, NULL, expected,
6095
val, NULL, NULL, NULL);
6102
* xmlSchemaPGetBoolNodeValue:
6103
* @ctxt: a schema validation context
6104
* @ownerDes: owner designation
6105
* @ownerItem: the owner as a schema item
6106
* @node: the node holding the value
6108
* Converts a boolean string value into 1 or 0.
6113
xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
6114
xmlSchemaBasicItemPtr ownerItem,
6117
xmlChar *value = NULL;
6120
value = xmlNodeGetContent(node);
6122
* 3.2.2.1 Lexical representation
6123
* An instance of a datatype that is defined as ļæ½booleanļæ½
6124
* can have the following legal literals {true, false, 1, 0}.
6126
if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
6128
else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
6130
else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
6132
else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
6135
xmlSchemaPSimpleTypeErr(ctxt,
6136
XML_SCHEMAP_INVALID_BOOLEAN,
6138
xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6139
NULL, BAD_CAST value,
6148
* xmlGetBooleanProp:
6149
* @ctxt: a schema validation context
6150
* @node: a subtree containing XML Schema informations
6151
* @name: the attribute name
6152
* @def: the default value
6154
* Evaluate if a boolean property is set
6156
* Returns the default if not found, 0 if found to be false,
6157
* 1 if found to be true
6160
xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
6162
const char *name, int def)
6166
val = xmlSchemaGetProp(ctxt, node, name);
6170
* 3.2.2.1 Lexical representation
6171
* An instance of a datatype that is defined as ļæ½booleanļæ½
6172
* can have the following legal literals {true, false, 1, 0}.
6174
if (xmlStrEqual(val, BAD_CAST "true"))
6176
else if (xmlStrEqual(val, BAD_CAST "false"))
6178
else if (xmlStrEqual(val, BAD_CAST "1"))
6180
else if (xmlStrEqual(val, BAD_CAST "0"))
6183
xmlSchemaPSimpleTypeErr(ctxt,
6184
XML_SCHEMAP_INVALID_BOOLEAN,
6186
(xmlNodePtr) xmlSchemaGetPropNode(node, name),
6187
xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
6188
NULL, val, NULL, NULL, NULL);
6193
/************************************************************************
6195
* Shema extraction from an Infoset *
6197
************************************************************************/
6198
static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
6199
ctxt, xmlSchemaPtr schema,
6202
static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
6204
xmlSchemaPtr schema,
6207
static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
6209
xmlSchemaPtr schema,
6211
xmlSchemaTypeType parentType);
6212
static xmlSchemaBasicItemPtr
6213
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
6214
xmlSchemaPtr schema,
6216
xmlSchemaItemListPtr uses,
6218
static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
6219
xmlSchemaPtr schema,
6221
static xmlSchemaWildcardPtr
6222
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
6223
xmlSchemaPtr schema, xmlNodePtr node);
6226
* xmlSchemaPValAttrNodeValue:
6228
* @ctxt: a schema parser context
6229
* @ownerDes: the designation of the parent element
6230
* @ownerItem: the schema object owner if existent
6231
* @attr: the schema attribute node being validated
6233
* @type: the built-in type to be validated against
6235
* Validates a value against the given built-in type.
6236
* This one is intended to be used internally for validation
6237
* of schema attribute values during parsing of the schema.
6239
* Returns 0 if the value is valid, a positive error code
6240
* number otherwise and -1 in case of an internal or API error.
6243
xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
6244
xmlSchemaBasicItemPtr ownerItem,
6246
const xmlChar *value,
6247
xmlSchemaTypePtr type)
6253
* NOTE: Should we move this to xmlschematypes.c? Hmm, but this
6254
* one is really meant to be used internally, so better not.
6256
if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
6258
if (type->type != XML_SCHEMA_TYPE_BASIC) {
6259
PERROR_INT("xmlSchemaPValAttrNodeValue",
6260
"the given type is not a built-in type");
6263
switch (type->builtInType) {
6264
case XML_SCHEMAS_NCNAME:
6265
case XML_SCHEMAS_QNAME:
6266
case XML_SCHEMAS_ANYURI:
6267
case XML_SCHEMAS_TOKEN:
6268
case XML_SCHEMAS_LANGUAGE:
6269
ret = xmlSchemaValPredefTypeNode(type, value, NULL,
6273
PERROR_INT("xmlSchemaPValAttrNodeValue",
6274
"validation using the given type is not supported while "
6275
"parsing a schema");
6280
* TODO: Should we use the S4S error codes instead?
6283
PERROR_INT("xmlSchemaPValAttrNodeValue",
6284
"failed to validate a schema attribute value");
6286
} else if (ret > 0) {
6287
if (WXS_IS_LIST(type))
6288
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
6290
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
6291
xmlSchemaPSimpleTypeErr(pctxt,
6292
ret, ownerItem, (xmlNodePtr) attr,
6293
type, NULL, value, NULL, NULL, NULL);
6299
* xmlSchemaPValAttrNode:
6301
* @ctxt: a schema parser context
6302
* @ownerDes: the designation of the parent element
6303
* @ownerItem: the schema object owner if existent
6304
* @attr: the schema attribute node being validated
6305
* @type: the built-in type to be validated against
6306
* @value: the resulting value if any
6308
* Extracts and validates a value against the given built-in type.
6309
* This one is intended to be used internally for validation
6310
* of schema attribute values during parsing of the schema.
6312
* Returns 0 if the value is valid, a positive error code
6313
* number otherwise and -1 in case of an internal or API error.
6316
xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
6317
xmlSchemaBasicItemPtr ownerItem,
6319
xmlSchemaTypePtr type,
6320
const xmlChar **value)
6324
if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
6327
val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6331
return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
6336
* xmlSchemaPValAttr:
6338
* @ctxt: a schema parser context
6339
* @node: the element node of the attribute
6340
* @ownerDes: the designation of the parent element
6341
* @ownerItem: the schema object owner if existent
6342
* @ownerElem: the owner element node
6343
* @name: the name of the schema attribute node
6344
* @type: the built-in type to be validated against
6345
* @value: the resulting value if any
6347
* Extracts and validates a value against the given built-in type.
6348
* This one is intended to be used internally for validation
6349
* of schema attribute values during parsing of the schema.
6351
* Returns 0 if the value is valid, a positive error code
6352
* number otherwise and -1 in case of an internal or API error.
6355
xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
6356
xmlSchemaBasicItemPtr ownerItem,
6357
xmlNodePtr ownerElem,
6359
xmlSchemaTypePtr type,
6360
const xmlChar **value)
6364
if ((ctxt == NULL) || (type == NULL)) {
6369
if (type->type != XML_SCHEMA_TYPE_BASIC) {
6372
xmlSchemaPErr(ctxt, ownerElem,
6373
XML_SCHEMAP_INTERNAL,
6374
"Internal error: xmlSchemaPValAttr, the given "
6375
"type '%s' is not a built-in type.\n",
6379
attr = xmlSchemaGetPropNode(ownerElem, name);
6385
return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
6390
xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
6391
xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6394
const xmlChar *namespaceName)
6396
/* TODO: Pointer comparison instead? */
6397
if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
6399
if (xmlStrEqual(xmlSchemaNs, namespaceName))
6402
* Check if the referenced namespace was <import>ed.
6404
if (WXS_BUCKET(pctxt)->relations != NULL) {
6405
xmlSchemaSchemaRelationPtr rel;
6407
rel = WXS_BUCKET(pctxt)->relations;
6409
if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
6410
xmlStrEqual(namespaceName, rel->importNamespace))
6413
} while (rel != NULL);
6416
* No matching <import>ed namespace found.
6419
xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
6421
if (namespaceName == NULL)
6422
xmlSchemaCustomErr(ACTXT_CAST pctxt,
6423
XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6424
"References from this schema to components in no "
6425
"namespace are not allowed, since not indicated by an "
6426
"import statement", NULL, NULL);
6428
xmlSchemaCustomErr(ACTXT_CAST pctxt,
6429
XML_SCHEMAP_SRC_RESOLVE, n, NULL,
6430
"References from this schema to components in the "
6431
"namespace '%s' are not allowed, since not indicated by an "
6432
"import statement", namespaceName, NULL);
6434
return (XML_SCHEMAP_SRC_RESOLVE);
6438
* xmlSchemaParseLocalAttributes:
6439
* @ctxt: a schema validation context
6440
* @schema: the schema being built
6441
* @node: a subtree containing XML Schema informations
6442
* @type: the hosting type where the attributes will be anchored
6444
* Parses attribute uses and attribute declarations and
6445
* attribute group references.
6448
xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6449
xmlNodePtr *child, xmlSchemaItemListPtr *list,
6450
int parentType, int *hasRefs)
6454
while ((IS_SCHEMA((*child), "attribute")) ||
6455
(IS_SCHEMA((*child), "attributeGroup"))) {
6456
if (IS_SCHEMA((*child), "attribute")) {
6457
item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
6460
item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
6461
if ((item != NULL) && (hasRefs != NULL))
6465
if (*list == NULL) {
6466
/* TODO: Customize grow factor. */
6467
*list = xmlSchemaItemListCreate();
6471
if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
6474
*child = (*child)->next;
6480
* xmlSchemaParseAnnotation:
6481
* @ctxt: a schema validation context
6482
* @schema: the schema being built
6483
* @node: a subtree containing XML Schema informations
6485
* parse a XML schema Attrribute declaration
6486
* *WARNING* this interface is highly subject to change
6488
* Returns -1 in case of error, 0 if the declaration is improper and
6489
* 1 in case of success.
6491
static xmlSchemaAnnotPtr
6492
xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
6494
xmlSchemaAnnotPtr ret;
6495
xmlNodePtr child = NULL;
6500
* INFO: S4S completed.
6504
* {any attributes with non-schema namespace . . .}>
6505
* Content: (appinfo | documentation)*
6507
if ((ctxt == NULL) || (node == NULL))
6510
ret = xmlSchemaNewAnnot(ctxt, node);
6513
attr = node->properties;
6514
while (attr != NULL) {
6515
if (((attr->ns == NULL) &&
6516
(!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
6517
((attr->ns != NULL) &&
6518
xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6520
xmlSchemaPIllegalAttrErr(ctxt,
6521
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6525
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6527
* And now for the children...
6529
child = node->children;
6530
while (child != NULL) {
6531
if (IS_SCHEMA(child, "appinfo")) {
6532
/* TODO: make available the content of "appinfo". */
6535
* {any attributes with non-schema namespace . . .}>
6538
attr = child->properties;
6539
while (attr != NULL) {
6540
if (((attr->ns == NULL) &&
6541
(!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
6542
((attr->ns != NULL) &&
6543
xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
6545
xmlSchemaPIllegalAttrErr(ctxt,
6546
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6550
xmlSchemaPValAttr(ctxt, NULL, child, "source",
6551
xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
6552
child = child->next;
6553
} else if (IS_SCHEMA(child, "documentation")) {
6554
/* TODO: make available the content of "documentation". */
6557
* {any attributes with non-schema namespace . . .}>
6560
attr = child->properties;
6561
while (attr != NULL) {
6562
if (attr->ns == NULL) {
6563
if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
6564
xmlSchemaPIllegalAttrErr(ctxt,
6565
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6568
if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
6569
(xmlStrEqual(attr->name, BAD_CAST "lang") &&
6570
(!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
6572
xmlSchemaPIllegalAttrErr(ctxt,
6573
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6579
* Attribute "xml:lang".
6581
attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
6583
xmlSchemaPValAttrNode(ctxt, NULL, attr,
6584
xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
6585
child = child->next;
6588
xmlSchemaPContentErr(ctxt,
6589
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6590
NULL, node, child, NULL, "(appinfo | documentation)*");
6592
child = child->next;
6600
* xmlSchemaParseFacet:
6601
* @ctxt: a schema validation context
6602
* @schema: the schema being built
6603
* @node: a subtree containing XML Schema informations
6605
* parse a XML schema Facet declaration
6606
* *WARNING* this interface is highly subject to change
6608
* Returns the new type structure or NULL in case of error
6610
static xmlSchemaFacetPtr
6611
xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6614
xmlSchemaFacetPtr facet;
6615
xmlNodePtr child = NULL;
6616
const xmlChar *value;
6618
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6621
facet = xmlSchemaNewFacet();
6622
if (facet == NULL) {
6623
xmlSchemaPErrMemory(ctxt, "allocating facet", node);
6627
value = xmlSchemaGetProp(ctxt, node, "value");
6628
if (value == NULL) {
6629
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
6630
"Facet %s has no value\n", node->name, NULL);
6631
xmlSchemaFreeFacet(facet);
6634
if (IS_SCHEMA(node, "minInclusive")) {
6635
facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
6636
} else if (IS_SCHEMA(node, "minExclusive")) {
6637
facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
6638
} else if (IS_SCHEMA(node, "maxInclusive")) {
6639
facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
6640
} else if (IS_SCHEMA(node, "maxExclusive")) {
6641
facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
6642
} else if (IS_SCHEMA(node, "totalDigits")) {
6643
facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
6644
} else if (IS_SCHEMA(node, "fractionDigits")) {
6645
facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
6646
} else if (IS_SCHEMA(node, "pattern")) {
6647
facet->type = XML_SCHEMA_FACET_PATTERN;
6648
} else if (IS_SCHEMA(node, "enumeration")) {
6649
facet->type = XML_SCHEMA_FACET_ENUMERATION;
6650
} else if (IS_SCHEMA(node, "whiteSpace")) {
6651
facet->type = XML_SCHEMA_FACET_WHITESPACE;
6652
} else if (IS_SCHEMA(node, "length")) {
6653
facet->type = XML_SCHEMA_FACET_LENGTH;
6654
} else if (IS_SCHEMA(node, "maxLength")) {
6655
facet->type = XML_SCHEMA_FACET_MAXLENGTH;
6656
} else if (IS_SCHEMA(node, "minLength")) {
6657
facet->type = XML_SCHEMA_FACET_MINLENGTH;
6659
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
6660
"Unknown facet type %s\n", node->name, NULL);
6661
xmlSchemaFreeFacet(facet);
6664
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6665
facet->value = value;
6666
if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
6667
(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
6668
const xmlChar *fixed;
6670
fixed = xmlSchemaGetProp(ctxt, node, "fixed");
6671
if (fixed != NULL) {
6672
if (xmlStrEqual(fixed, BAD_CAST "true"))
6676
child = node->children;
6678
if (IS_SCHEMA(child, "annotation")) {
6679
facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6680
child = child->next;
6682
if (child != NULL) {
6683
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
6684
"Facet %s has unexpected child content\n",
6691
* xmlSchemaParseWildcardNs:
6692
* @ctxt: a schema parser context
6693
* @wildc: the wildcard, already created
6694
* @node: a subtree containing XML Schema informations
6696
* Parses the attribute "processContents" and "namespace"
6697
* of a xsd:anyAttribute and xsd:any.
6698
* *WARNING* this interface is highly subject to change
6700
* Returns 0 if everything goes fine, a positive error code
6701
* if something is not valid and -1 if an internal error occurs.
6704
xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
6705
xmlSchemaPtr schema ATTRIBUTE_UNUSED,
6706
xmlSchemaWildcardPtr wildc,
6709
const xmlChar *pc, *ns, *dictnsItem;
6712
xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
6715
pc = xmlSchemaGetProp(ctxt, node, "processContents");
6717
|| (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
6718
wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6719
} else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
6720
wildc->processContents = XML_SCHEMAS_ANY_SKIP;
6721
} else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
6722
wildc->processContents = XML_SCHEMAS_ANY_LAX;
6724
xmlSchemaPSimpleTypeErr(ctxt,
6725
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
6727
NULL, "(strict | skip | lax)", pc,
6729
wildc->processContents = XML_SCHEMAS_ANY_STRICT;
6730
ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
6733
* Build the namespace constraints.
6735
attr = xmlSchemaGetPropNode(node, "namespace");
6736
ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
6737
if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
6739
else if (xmlStrEqual(ns, BAD_CAST "##other")) {
6740
wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
6741
if (wildc->negNsSet == NULL) {
6744
wildc->negNsSet->value = ctxt->targetNamespace;
6746
const xmlChar *end, *cur;
6750
while (IS_BLANK_CH(*cur))
6753
while ((*end != 0) && (!(IS_BLANK_CH(*end))))
6757
nsItem = xmlStrndup(cur, end - cur);
6758
if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
6759
(xmlStrEqual(nsItem, BAD_CAST "##any"))) {
6760
xmlSchemaPSimpleTypeErr(ctxt,
6761
XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
6762
NULL, (xmlNodePtr) attr,
6764
"((##any | ##other) | List of (xs:anyURI | "
6765
"(##targetNamespace | ##local)))",
6766
nsItem, NULL, NULL, NULL);
6767
ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
6769
if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
6770
dictnsItem = ctxt->targetNamespace;
6771
} else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
6775
* Validate the item (anyURI).
6777
xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
6778
nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
6779
dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
6782
* Avoid dublicate namespaces.
6785
while (tmp != NULL) {
6786
if (dictnsItem == tmp->value)
6791
tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
6796
tmp->value = dictnsItem;
6798
if (wildc->nsSet == NULL)
6808
} while (*cur != 0);
6814
xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
6815
xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
6820
if ((maxOccurs == 0) && ( minOccurs == 0))
6822
if (maxOccurs != UNBOUNDED) {
6824
* TODO: Maybe we should better not create the particle,
6825
* if min/max is invalid, since it could confuse the build of the
6829
* 3.9.6 Schema Component Constraint: Particle Correct
6832
if (maxOccurs < 1) {
6834
* 2.2 {max occurs} must be greater than or equal to 1.
6836
xmlSchemaPCustomAttrErr(ctxt,
6837
XML_SCHEMAP_P_PROPS_CORRECT_2_2,
6839
xmlSchemaGetPropNode(node, "maxOccurs"),
6840
"The value must be greater than or equal to 1");
6841
return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
6842
} else if (minOccurs > maxOccurs) {
6844
* 2.1 {min occurs} must not be greater than {max occurs}.
6846
xmlSchemaPCustomAttrErr(ctxt,
6847
XML_SCHEMAP_P_PROPS_CORRECT_2_1,
6849
xmlSchemaGetPropNode(node, "minOccurs"),
6850
"The value must not be greater than the value of 'maxOccurs'");
6851
return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
6858
* xmlSchemaParseAny:
6859
* @ctxt: a schema validation context
6860
* @schema: the schema being built
6861
* @node: a subtree containing XML Schema informations
6863
* Parsea a XML schema <any> element. A particle and wildcard
6864
* will be created (except if minOccurs==maxOccurs==0, in this case
6865
* nothing will be created).
6866
* *WARNING* this interface is highly subject to change
6868
* Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
6870
static xmlSchemaParticlePtr
6871
xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6874
xmlSchemaParticlePtr particle;
6875
xmlNodePtr child = NULL;
6876
xmlSchemaWildcardPtr wild;
6879
xmlSchemaAnnotPtr annot = NULL;
6881
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6884
* Check for illegal attributes.
6886
attr = node->properties;
6887
while (attr != NULL) {
6888
if (attr->ns == NULL) {
6889
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
6890
(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
6891
(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
6892
(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
6893
(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
6894
xmlSchemaPIllegalAttrErr(ctxt,
6895
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6897
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
6898
xmlSchemaPIllegalAttrErr(ctxt,
6899
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
6903
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6905
* minOccurs/maxOccurs.
6907
max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
6908
"(xs:nonNegativeInteger | unbounded)");
6909
min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
6910
"xs:nonNegativeInteger");
6911
xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
6913
* Create & parse the wildcard.
6915
wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
6918
xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
6920
* And now for the children...
6922
child = node->children;
6923
if (IS_SCHEMA(child, "annotation")) {
6924
annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6925
child = child->next;
6927
if (child != NULL) {
6928
xmlSchemaPContentErr(ctxt,
6929
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6931
NULL, "(annotation?)");
6934
* No component if minOccurs==maxOccurs==0.
6936
if ((min == 0) && (max == 0)) {
6937
/* Don't free the wildcard, since it's already on the list. */
6941
* Create the particle.
6943
particle = xmlSchemaAddParticle(ctxt, node, min, max);
6944
if (particle == NULL)
6946
particle->annot = annot;
6947
particle->children = (xmlSchemaTreeItemPtr) wild;
6953
* xmlSchemaParseNotation:
6954
* @ctxt: a schema validation context
6955
* @schema: the schema being built
6956
* @node: a subtree containing XML Schema informations
6958
* parse a XML schema Notation declaration
6960
* Returns the new structure or NULL in case of error
6962
static xmlSchemaNotationPtr
6963
xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
6966
const xmlChar *name;
6967
xmlSchemaNotationPtr ret;
6968
xmlNodePtr child = NULL;
6970
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
6972
name = xmlSchemaGetProp(ctxt, node, "name");
6974
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
6975
"Notation has no name\n", NULL, NULL);
6978
ret = xmlSchemaAddNotation(ctxt, schema, name,
6979
ctxt->targetNamespace, node);
6982
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
6984
child = node->children;
6985
if (IS_SCHEMA(child, "annotation")) {
6986
ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
6987
child = child->next;
6989
if (child != NULL) {
6990
xmlSchemaPContentErr(ctxt,
6991
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
6993
NULL, "(annotation?)");
7000
* xmlSchemaParseAnyAttribute:
7001
* @ctxt: a schema validation context
7002
* @schema: the schema being built
7003
* @node: a subtree containing XML Schema informations
7005
* parse a XML schema AnyAttrribute declaration
7006
* *WARNING* this interface is highly subject to change
7008
* Returns a wildcard or NULL.
7010
static xmlSchemaWildcardPtr
7011
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
7012
xmlSchemaPtr schema, xmlNodePtr node)
7014
xmlSchemaWildcardPtr ret;
7015
xmlNodePtr child = NULL;
7018
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
7021
ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
7027
* Check for illegal attributes.
7029
attr = node->properties;
7030
while (attr != NULL) {
7031
if (attr->ns == NULL) {
7032
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7033
(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
7034
(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
7035
xmlSchemaPIllegalAttrErr(ctxt,
7036
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7038
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7039
xmlSchemaPIllegalAttrErr(ctxt,
7040
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7044
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
7046
* Parse the namespace list.
7048
if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
7051
* And now for the children...
7053
child = node->children;
7054
if (IS_SCHEMA(child, "annotation")) {
7055
ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
7056
child = child->next;
7058
if (child != NULL) {
7059
xmlSchemaPContentErr(ctxt,
7060
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7062
NULL, "(annotation?)");
7070
* xmlSchemaParseAttribute:
7071
* @ctxt: a schema validation context
7072
* @schema: the schema being built
7073
* @node: a subtree containing XML Schema informations
7075
* parse a XML schema Attrribute declaration
7076
* *WARNING* this interface is highly subject to change
7078
* Returns the attribute declaration.
7080
static xmlSchemaBasicItemPtr
7081
xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
7082
xmlSchemaPtr schema,
7084
xmlSchemaItemListPtr uses,
7087
const xmlChar *attrValue, *name = NULL, *ns = NULL;
7088
xmlSchemaAttributeUsePtr use = NULL;
7089
xmlNodePtr child = NULL;
7091
const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
7092
int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7093
int nberrors, hasForm = 0, defValueType = 0;
7095
#define WXS_ATTR_DEF_VAL_DEFAULT 1
7096
#define WXS_ATTR_DEF_VAL_FIXED 2
7099
* 3.2.3 Constraints on XML Representations of Attribute Declarations
7102
if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7104
attr = xmlSchemaGetPropNode(node, "ref");
7106
if (xmlSchemaPValAttrNodeQName(pctxt, schema,
7107
NULL, attr, &tmpNs, &tmpName) != 0) {
7110
if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
7114
nberrors = pctxt->nberrors;
7116
* Check for illegal attributes.
7118
attr = node->properties;
7119
while (attr != NULL) {
7120
if (attr->ns == NULL) {
7122
if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7123
xmlSchemaPValAttrNodeID(pctxt, attr);
7125
} else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
7129
if (xmlStrEqual(attr->name, BAD_CAST "name")) {
7131
} else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
7132
xmlSchemaPValAttrNodeID(pctxt, attr);
7134
} else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
7135
xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
7136
attr, &tmpNs, &tmpName);
7138
} else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
7140
* Evaluate the target namespace
7143
attrValue = xmlSchemaGetNodeContent(pctxt,
7145
if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
7146
ns = pctxt->targetNamespace;
7147
} else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
7149
xmlSchemaPSimpleTypeErr(pctxt,
7150
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
7151
NULL, (xmlNodePtr) attr,
7152
NULL, "(qualified | unqualified)",
7153
attrValue, NULL, NULL, NULL);
7158
if (xmlStrEqual(attr->name, BAD_CAST "use")) {
7160
attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7161
/* TODO: Maybe we need to normalize the value beforehand. */
7162
if (xmlStrEqual(attrValue, BAD_CAST "optional"))
7163
occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
7164
else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
7165
occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
7166
else if (xmlStrEqual(attrValue, BAD_CAST "required"))
7167
occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
7169
xmlSchemaPSimpleTypeErr(pctxt,
7170
XML_SCHEMAP_INVALID_ATTR_USE,
7171
NULL, (xmlNodePtr) attr,
7172
NULL, "(optional | prohibited | required)",
7173
attrValue, NULL, NULL, NULL);
7176
} else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
7179
* default and fixed must not both be present.
7182
xmlSchemaPMutualExclAttrErr(pctxt,
7183
XML_SCHEMAP_SRC_ATTRIBUTE_1,
7184
NULL, attr, "default", "fixed");
7186
defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7187
defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
7190
} else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
7193
* default and fixed must not both be present.
7196
xmlSchemaPMutualExclAttrErr(pctxt,
7197
XML_SCHEMAP_SRC_ATTRIBUTE_1,
7198
NULL, attr, "default", "fixed");
7200
defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7201
defValueType = WXS_ATTR_DEF_VAL_FIXED;
7205
} else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
7208
xmlSchemaPIllegalAttrErr(pctxt,
7209
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7216
* If default and use are both present, use must have
7217
* the actual value optional.
7219
if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
7220
(occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
7221
xmlSchemaPSimpleTypeErr(pctxt,
7222
XML_SCHEMAP_SRC_ATTRIBUTE_2,
7224
"(optional | prohibited | required)", NULL,
7225
"The value of the attribute 'use' must be 'optional' "
7226
"if the attribute 'default' is present",
7230
* We want correct attributes.
7232
if (nberrors != pctxt->nberrors)
7235
xmlSchemaAttributePtr attrDecl;
7237
/* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
7238
if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
7239
ns = pctxt->targetNamespace;
7241
* 3.2.6 Schema Component Constraint: xsi: Not Allowed
7242
* TODO: Move this to the component layer.
7244
if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
7245
xmlSchemaCustomErr(ACTXT_CAST pctxt,
7248
"The target namespace must not match '%s'",
7249
xmlSchemaInstanceNs, NULL);
7251
attr = xmlSchemaGetPropNode(node, "name");
7253
xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7254
NULL, node, "name", NULL);
7257
if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7258
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7262
* 3.2.6 Schema Component Constraint: xmlns Not Allowed
7263
* TODO: Move this to the component layer.
7265
if (xmlStrEqual(name, BAD_CAST "xmlns")) {
7266
xmlSchemaPSimpleTypeErr(pctxt,
7267
XML_SCHEMAP_NO_XMLNS,
7268
NULL, (xmlNodePtr) attr,
7269
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7270
"The value of the attribute must not match 'xmlns'",
7274
if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
7275
goto check_children;
7277
* Create the attribute use component.
7279
use = xmlSchemaAddAttributeUse(pctxt, node);
7282
use->occurs = occurs;
7284
* Create the attribute declaration.
7286
attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
7287
if (attrDecl == NULL)
7289
if (tmpName != NULL) {
7290
attrDecl->typeName = tmpName;
7291
attrDecl->typeNs = tmpNs;
7293
use->attrDecl = attrDecl;
7297
if (defValue != NULL) {
7298
attrDecl->defValue = defValue;
7299
if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7300
attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
7302
} else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7303
xmlSchemaQNameRefPtr ref;
7306
* Create the attribute use component.
7308
use = xmlSchemaAddAttributeUse(pctxt, node);
7312
* We need to resolve the reference at later stage.
7314
WXS_ADD_PENDING(pctxt, use);
7315
use->occurs = occurs;
7317
* Create a QName reference to the attribute declaration.
7319
ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
7324
* Assign the reference. This will be substituted for the
7325
* referenced attribute declaration when the QName is resolved.
7327
use->attrDecl = WXS_ATTR_CAST ref;
7331
if (defValue != NULL)
7332
use->defValue = defValue;
7333
if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
7334
use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
7339
* And now for the children...
7341
child = node->children;
7342
if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
7343
xmlSchemaAttributeUseProhibPtr prohib;
7345
if (IS_SCHEMA(child, "annotation")) {
7346
xmlSchemaParseAnnotation(pctxt, child, 0);
7347
child = child->next;
7349
if (child != NULL) {
7350
xmlSchemaPContentErr(pctxt,
7351
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7352
NULL, node, child, NULL,
7356
* Check for pointlessness of attribute prohibitions.
7358
if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
7359
xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7360
XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7362
"Skipping attribute use prohibition, since it is "
7363
"pointless inside an <attributeGroup>",
7366
} else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
7367
xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7368
XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7370
"Skipping attribute use prohibition, since it is "
7371
"pointless when extending a type",
7380
* Check for duplicate attribute prohibitions.
7385
for (i = 0; i < uses->nbItems; i++) {
7386
use = uses->items[i];
7387
if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
7388
(tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
7389
(tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
7391
xmlChar *str = NULL;
7393
xmlSchemaCustomWarning(ACTXT_CAST pctxt,
7394
XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
7396
"Skipping duplicate attribute use prohibition '%s'",
7397
xmlSchemaFormatQName(&str, tmpNs, tmpName),
7405
* Create the attribute prohibition helper component.
7407
prohib = xmlSchemaAddAttributeUseProhib(pctxt);
7410
prohib->node = node;
7411
prohib->name = tmpName;
7412
prohib->targetNamespace = tmpNs;
7415
* We need at least to resolve to the attribute declaration.
7417
WXS_ADD_PENDING(pctxt, prohib);
7419
return(WXS_BASIC_CAST prohib);
7421
if (IS_SCHEMA(child, "annotation")) {
7423
* TODO: Should this go into the attr decl?
7425
use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7426
child = child->next;
7429
if (child != NULL) {
7430
if (IS_SCHEMA(child, "simpleType"))
7433
* If ref is present, then all of <simpleType>,
7434
* form and type must be absent.
7436
xmlSchemaPContentErr(pctxt,
7437
XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
7438
NULL, node, child, NULL,
7441
xmlSchemaPContentErr(pctxt,
7442
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7443
NULL, node, child, NULL,
7447
if (IS_SCHEMA(child, "simpleType")) {
7448
if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
7451
* type and <simpleType> must not both be present.
7453
xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7455
"The attribute 'type' and the <simpleType> child "
7456
"are mutually exclusive", NULL);
7458
WXS_ATTRUSE_TYPEDEF(use) =
7459
xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7460
child = child->next;
7463
xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7464
NULL, node, child, NULL,
7465
"(annotation?, simpleType?)");
7468
return (WXS_BASIC_CAST use);
7472
static xmlSchemaAttributePtr
7473
xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
7474
xmlSchemaPtr schema,
7477
const xmlChar *attrValue;
7478
xmlSchemaAttributePtr ret;
7479
xmlNodePtr child = NULL;
7483
* Note that the w3c spec assumes the schema to be validated with schema
7484
* for schemas beforehand.
7486
* 3.2.3 Constraints on XML Representations of Attribute Declarations
7488
if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7492
* One of ref or name must be present, but not both
7494
attr = xmlSchemaGetPropNode(node, "name");
7496
xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
7497
NULL, node, "name", NULL);
7500
if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
7501
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
7505
* 3.2.6 Schema Component Constraint: xmlns Not Allowed
7506
* TODO: Move this to the component layer.
7508
if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
7509
xmlSchemaPSimpleTypeErr(pctxt,
7510
XML_SCHEMAP_NO_XMLNS,
7511
NULL, (xmlNodePtr) attr,
7512
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
7513
"The value of the attribute must not match 'xmlns'",
7518
* 3.2.6 Schema Component Constraint: xsi: Not Allowed
7519
* TODO: Move this to the component layer.
7520
* Or better leave it here and add it to the component layer
7521
* if we have a schema construction API.
7523
if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
7524
xmlSchemaCustomErr(ACTXT_CAST pctxt,
7525
XML_SCHEMAP_NO_XSI, node, NULL,
7526
"The target namespace must not match '%s'",
7527
xmlSchemaInstanceNs, NULL);
7530
ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
7531
pctxt->targetNamespace, node, 1);
7534
ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
7537
* Check for illegal attributes.
7539
attr = node->properties;
7540
while (attr != NULL) {
7541
if (attr->ns == NULL) {
7542
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
7543
(!xmlStrEqual(attr->name, BAD_CAST "default")) &&
7544
(!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
7545
(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7546
(!xmlStrEqual(attr->name, BAD_CAST "type")))
7548
xmlSchemaPIllegalAttrErr(pctxt,
7549
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7551
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7552
xmlSchemaPIllegalAttrErr(pctxt,
7553
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7557
xmlSchemaPValAttrQName(pctxt, schema, NULL,
7558
node, "type", &ret->typeNs, &ret->typeName);
7560
xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7562
* Attribute "fixed".
7564
ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
7565
if (ret->defValue != NULL)
7566
ret->flags |= XML_SCHEMAS_ATTR_FIXED;
7568
* Attribute "default".
7570
attr = xmlSchemaGetPropNode(node, "default");
7574
* default and fixed must not both be present.
7576
if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
7577
xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
7578
WXS_BASIC_CAST ret, attr, "default", "fixed");
7580
ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
7583
* And now for the children...
7585
child = node->children;
7586
if (IS_SCHEMA(child, "annotation")) {
7587
ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7588
child = child->next;
7590
if (IS_SCHEMA(child, "simpleType")) {
7591
if (ret->typeName != NULL) {
7594
* type and <simpleType> must not both be present.
7596
xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
7598
"The attribute 'type' and the <simpleType> child "
7599
"are mutually exclusive", NULL);
7601
ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
7602
child = child->next;
7605
xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7606
NULL, node, child, NULL,
7607
"(annotation?, simpleType?)");
7613
* xmlSchemaParseAttributeGroupRef:
7614
* @ctxt: a schema validation context
7615
* @schema: the schema being built
7616
* @node: a subtree containing XML Schema informations
7618
* Parse an attribute group definition reference.
7619
* Note that a reference to an attribute group does not
7620
* correspond to any component at all.
7621
* *WARNING* this interface is highly subject to change
7623
* Returns the attribute group or NULL in case of error.
7625
static xmlSchemaQNameRefPtr
7626
xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
7627
xmlSchemaPtr schema,
7630
xmlSchemaQNameRefPtr ret;
7631
xmlNodePtr child = NULL;
7633
const xmlChar *refNs = NULL, *ref = NULL;
7635
if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7638
attr = xmlSchemaGetPropNode(node, "ref");
7640
xmlSchemaPMissingAttrErr(pctxt,
7641
XML_SCHEMAP_S4S_ATTR_MISSING,
7642
NULL, node, "ref", NULL);
7645
xmlSchemaPValAttrNodeQName(pctxt, schema,
7646
NULL, attr, &refNs, &ref);
7647
if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
7651
* Check for illegal attributes.
7653
attr = node->properties;
7654
while (attr != NULL) {
7655
if (attr->ns == NULL) {
7656
if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
7657
(!xmlStrEqual(attr->name, BAD_CAST "id")))
7659
xmlSchemaPIllegalAttrErr(pctxt,
7660
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7662
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7663
xmlSchemaPIllegalAttrErr(pctxt,
7664
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7669
xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7672
* And now for the children...
7674
child = node->children;
7675
if (IS_SCHEMA(child, "annotation")) {
7677
* TODO: We do not have a place to store the annotation, do we?
7679
xmlSchemaParseAnnotation(pctxt, child, 0);
7680
child = child->next;
7682
if (child != NULL) {
7683
xmlSchemaPContentErr(pctxt,
7684
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7685
NULL, node, child, NULL,
7690
* Handle attribute group redefinitions.
7692
if (pctxt->isRedefine && pctxt->redef &&
7693
(pctxt->redef->item->type ==
7694
XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
7695
(ref == pctxt->redef->refName) &&
7696
(refNs == pctxt->redef->refTargetNs))
7699
* SPEC src-redefine:
7700
* (7.1) "If it has an <attributeGroup> among its contents
7701
* the ļæ½actual valueļæ½ of whose ref [attribute] is the same
7702
* as the ļæ½actual valueļæ½ of its own name attribute plus
7703
* target namespace, then it must have exactly one such group."
7705
if (pctxt->redefCounter != 0) {
7706
xmlChar *str = NULL;
7708
xmlSchemaCustomErr(ACTXT_CAST pctxt,
7709
XML_SCHEMAP_SRC_REDEFINE, node, NULL,
7710
"The redefining attribute group definition "
7711
"'%s' must not contain more than one "
7712
"reference to the redefined definition",
7713
xmlSchemaFormatQName(&str, refNs, ref), NULL);
7717
pctxt->redefCounter++;
7719
* URGENT TODO: How to ensure that the reference will not be
7720
* handled by the normal component resolution mechanism?
7722
ret = xmlSchemaNewQNameRef(pctxt,
7723
XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7727
pctxt->redef->reference = WXS_BASIC_CAST ret;
7730
* Create a QName-reference helper component. We will substitute this
7731
* component for the attribute uses of the referenced attribute group
7734
ret = xmlSchemaNewQNameRef(pctxt,
7735
XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
7739
/* Add to pending items, to be able to resolve the reference. */
7740
WXS_ADD_PENDING(pctxt, ret);
7746
* xmlSchemaParseAttributeGroupDefinition:
7747
* @pctxt: a schema validation context
7748
* @schema: the schema being built
7749
* @node: a subtree containing XML Schema informations
7751
* parse a XML schema Attribute Group declaration
7752
* *WARNING* this interface is highly subject to change
7754
* Returns the attribute group definition or NULL in case of error.
7756
static xmlSchemaAttributeGroupPtr
7757
xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
7758
xmlSchemaPtr schema,
7761
const xmlChar *name;
7762
xmlSchemaAttributeGroupPtr ret;
7763
xmlNodePtr child = NULL;
7767
if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
7770
attr = xmlSchemaGetPropNode(node, "name");
7772
xmlSchemaPMissingAttrErr(pctxt,
7773
XML_SCHEMAP_S4S_ATTR_MISSING,
7774
NULL, node, "name", NULL);
7778
* The name is crucial, exit if invalid.
7780
if (xmlSchemaPValAttrNode(pctxt,
7782
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
7785
ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
7786
name, pctxt->targetNamespace, node);
7790
* Check for illegal attributes.
7792
attr = node->properties;
7793
while (attr != NULL) {
7794
if (attr->ns == NULL) {
7795
if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
7796
(!xmlStrEqual(attr->name, BAD_CAST "id")))
7798
xmlSchemaPIllegalAttrErr(pctxt,
7799
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7801
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
7802
xmlSchemaPIllegalAttrErr(pctxt,
7803
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
7808
xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
7810
* And now for the children...
7812
child = node->children;
7813
if (IS_SCHEMA(child, "annotation")) {
7814
ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
7815
child = child->next;
7818
* Parse contained attribute decls/refs.
7820
if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
7821
(xmlSchemaItemListPtr *) &(ret->attrUses),
7822
XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
7825
ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
7827
* Parse the attribute wildcard.
7829
if (IS_SCHEMA(child, "anyAttribute")) {
7830
ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
7832
child = child->next;
7834
if (child != NULL) {
7835
xmlSchemaPContentErr(pctxt,
7836
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
7837
NULL, node, child, NULL,
7838
"(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
7844
* xmlSchemaPValAttrFormDefault:
7846
* @flags: the flags to be modified
7847
* @flagQualified: the specific flag for "qualified"
7849
* Returns 0 if the value is valid, 1 otherwise.
7852
xmlSchemaPValAttrFormDefault(const xmlChar *value,
7856
if (xmlStrEqual(value, BAD_CAST "qualified")) {
7857
if ((*flags & flagQualified) == 0)
7858
*flags |= flagQualified;
7859
} else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
7866
* xmlSchemaPValAttrBlockFinal:
7868
* @flags: the flags to be modified
7869
* @flagAll: the specific flag for "#all"
7870
* @flagExtension: the specific flag for "extension"
7871
* @flagRestriction: the specific flag for "restriction"
7872
* @flagSubstitution: the specific flag for "substitution"
7873
* @flagList: the specific flag for "list"
7874
* @flagUnion: the specific flag for "union"
7876
* Validates the value of the attribute "final" and "block". The value
7877
* is converted into the specified flag values and returned in @flags.
7879
* Returns 0 if the value is valid, 1 otherwise.
7883
xmlSchemaPValAttrBlockFinal(const xmlChar *value,
7887
int flagRestriction,
7888
int flagSubstitution,
7895
* TODO: This does not check for dublicate entries.
7897
if ((flags == NULL) || (value == NULL))
7901
if (xmlStrEqual(value, BAD_CAST "#all")) {
7905
if (flagExtension != -1)
7906
*flags |= flagExtension;
7907
if (flagRestriction != -1)
7908
*flags |= flagRestriction;
7909
if (flagSubstitution != -1)
7910
*flags |= flagSubstitution;
7913
if (flagUnion != -1)
7914
*flags |= flagUnion;
7917
const xmlChar *end, *cur = value;
7921
while (IS_BLANK_CH(*cur))
7924
while ((*end != 0) && (!(IS_BLANK_CH(*end))))
7928
item = xmlStrndup(cur, end - cur);
7929
if (xmlStrEqual(item, BAD_CAST "extension")) {
7930
if (flagExtension != -1) {
7931
if ((*flags & flagExtension) == 0)
7932
*flags |= flagExtension;
7935
} else if (xmlStrEqual(item, BAD_CAST "restriction")) {
7936
if (flagRestriction != -1) {
7937
if ((*flags & flagRestriction) == 0)
7938
*flags |= flagRestriction;
7941
} else if (xmlStrEqual(item, BAD_CAST "substitution")) {
7942
if (flagSubstitution != -1) {
7943
if ((*flags & flagSubstitution) == 0)
7944
*flags |= flagSubstitution;
7947
} else if (xmlStrEqual(item, BAD_CAST "list")) {
7948
if (flagList != -1) {
7949
if ((*flags & flagList) == 0)
7953
} else if (xmlStrEqual(item, BAD_CAST "union")) {
7954
if (flagUnion != -1) {
7955
if ((*flags & flagUnion) == 0)
7956
*flags |= flagUnion;
7964
} while ((ret == 0) && (*cur != 0));
7971
xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
7972
xmlSchemaIDCPtr idc,
7973
xmlSchemaIDCSelectPtr selector,
7981
* Schema Component Constraint: Selector Value OK
7983
* TODO: 1 The {selector} must be a valid XPath expression, as defined
7986
if (selector == NULL) {
7987
xmlSchemaPErr(ctxt, idc->node,
7988
XML_SCHEMAP_INTERNAL,
7989
"Internal error: xmlSchemaCheckCSelectorXPath, "
7990
"the selector is not specified.\n", NULL, NULL);
7996
node = (xmlNodePtr) attr;
7997
if (selector->xpath == NULL) {
7998
xmlSchemaPCustomErr(ctxt,
7999
/* TODO: Adjust error code. */
8000
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8002
"The XPath expression of the selector is not valid", NULL);
8003
return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
8005
const xmlChar **nsArray = NULL;
8006
xmlNsPtr *nsList = NULL;
8008
* Compile the XPath expression.
8011
* TODO: We need the array of in-scope namespaces for compilation.
8012
* TODO: Call xmlPatterncompile with different options for selector/
8018
nsList = xmlGetNsList(attr->doc, attr->parent);
8020
* Build an array of prefixes and namespaces.
8022
if (nsList != NULL) {
8025
for (i = 0; nsList[i] != NULL; i++)
8028
nsArray = (const xmlChar **) xmlMalloc(
8029
(count * 2 + 1) * sizeof(const xmlChar *));
8030
if (nsArray == NULL) {
8031
xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
8036
for (i = 0; i < count; i++) {
8037
nsArray[2 * i] = nsList[i]->href;
8038
nsArray[2 * i + 1] = nsList[i]->prefix;
8040
nsArray[count * 2] = NULL;
8044
* TODO: Differentiate between "selector" and "field".
8047
selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8048
NULL, XML_PATTERN_XSFIELD, nsArray);
8050
selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
8051
NULL, XML_PATTERN_XSSEL, nsArray);
8052
if (nsArray != NULL)
8053
xmlFree((xmlChar **) nsArray);
8055
if (selector->xpathComp == NULL) {
8056
xmlSchemaPCustomErr(ctxt,
8057
/* TODO: Adjust error code? */
8058
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8060
"The XPath expression '%s' could not be "
8061
"compiled", selector->xpath);
8062
return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
8068
#define ADD_ANNOTATION(annot) \
8069
xmlSchemaAnnotPtr cur = item->annot; \
8070
if (item->annot == NULL) { \
8071
item->annot = annot; \
8074
cur = item->annot; \
8075
if (cur->next != NULL) { \
8081
* xmlSchemaAssignAnnotation:
8082
* @item: the schema component
8083
* @annot: the annotation
8085
* Adds the annotation to the given schema component.
8087
* Returns the given annotaion.
8089
static xmlSchemaAnnotPtr
8090
xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
8091
xmlSchemaAnnotPtr annot)
8093
if ((annItem == NULL) || (annot == NULL))
8095
switch (annItem->type) {
8096
case XML_SCHEMA_TYPE_ELEMENT: {
8097
xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
8098
ADD_ANNOTATION(annot)
8101
case XML_SCHEMA_TYPE_ATTRIBUTE: {
8102
xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
8103
ADD_ANNOTATION(annot)
8106
case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
8107
case XML_SCHEMA_TYPE_ANY: {
8108
xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
8109
ADD_ANNOTATION(annot)
8112
case XML_SCHEMA_TYPE_PARTICLE:
8113
case XML_SCHEMA_TYPE_IDC_KEY:
8114
case XML_SCHEMA_TYPE_IDC_KEYREF:
8115
case XML_SCHEMA_TYPE_IDC_UNIQUE: {
8116
xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
8117
ADD_ANNOTATION(annot)
8120
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
8121
xmlSchemaAttributeGroupPtr item =
8122
(xmlSchemaAttributeGroupPtr) annItem;
8123
ADD_ANNOTATION(annot)
8126
case XML_SCHEMA_TYPE_NOTATION: {
8127
xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
8128
ADD_ANNOTATION(annot)
8131
case XML_SCHEMA_FACET_MININCLUSIVE:
8132
case XML_SCHEMA_FACET_MINEXCLUSIVE:
8133
case XML_SCHEMA_FACET_MAXINCLUSIVE:
8134
case XML_SCHEMA_FACET_MAXEXCLUSIVE:
8135
case XML_SCHEMA_FACET_TOTALDIGITS:
8136
case XML_SCHEMA_FACET_FRACTIONDIGITS:
8137
case XML_SCHEMA_FACET_PATTERN:
8138
case XML_SCHEMA_FACET_ENUMERATION:
8139
case XML_SCHEMA_FACET_WHITESPACE:
8140
case XML_SCHEMA_FACET_LENGTH:
8141
case XML_SCHEMA_FACET_MAXLENGTH:
8142
case XML_SCHEMA_FACET_MINLENGTH: {
8143
xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
8144
ADD_ANNOTATION(annot)
8147
case XML_SCHEMA_TYPE_SIMPLE:
8148
case XML_SCHEMA_TYPE_COMPLEX: {
8149
xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
8150
ADD_ANNOTATION(annot)
8153
case XML_SCHEMA_TYPE_GROUP: {
8154
xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
8155
ADD_ANNOTATION(annot)
8158
case XML_SCHEMA_TYPE_SEQUENCE:
8159
case XML_SCHEMA_TYPE_CHOICE:
8160
case XML_SCHEMA_TYPE_ALL: {
8161
xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
8162
ADD_ANNOTATION(annot)
8166
xmlSchemaPCustomErr(NULL,
8167
XML_SCHEMAP_INTERNAL,
8169
"Internal error: xmlSchemaAddAnnotation, "
8170
"The item is not a annotated schema component", NULL);
8177
* xmlSchemaParseIDCSelectorAndField:
8178
* @ctxt: a schema validation context
8179
* @schema: the schema being built
8180
* @node: a subtree containing XML Schema informations
8182
* Parses a XML Schema identity-contraint definition's
8183
* <selector> and <field> elements.
8185
* Returns the parsed identity-constraint definition.
8187
static xmlSchemaIDCSelectPtr
8188
xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
8189
xmlSchemaIDCPtr idc,
8193
xmlSchemaIDCSelectPtr item;
8194
xmlNodePtr child = NULL;
8198
* Check for illegal attributes.
8200
attr = node->properties;
8201
while (attr != NULL) {
8202
if (attr->ns == NULL) {
8203
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8204
(!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
8205
xmlSchemaPIllegalAttrErr(ctxt,
8206
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8208
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8209
xmlSchemaPIllegalAttrErr(ctxt,
8210
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8217
item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
8219
xmlSchemaPErrMemory(ctxt,
8220
"allocating a 'selector' of an identity-constraint definition",
8224
memset(item, 0, sizeof(xmlSchemaIDCSelect));
8226
* Attribute "xpath" (mandatory).
8228
attr = xmlSchemaGetPropNode(node, "xpath");
8230
xmlSchemaPMissingAttrErr(ctxt,
8231
XML_SCHEMAP_S4S_ATTR_MISSING,
8235
item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8237
* URGENT TODO: "field"s have an other syntax than "selector"s.
8240
if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
8244
XML_SCHEMAP_INTERNAL,
8245
"Internal error: xmlSchemaParseIDCSelectorAndField, "
8246
"validating the XPath expression of a IDC selector.\n",
8251
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8253
* And now for the children...
8255
child = node->children;
8256
if (IS_SCHEMA(child, "annotation")) {
8258
* Add the annotation to the parent IDC.
8260
xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
8261
xmlSchemaParseAnnotation(ctxt, child, 1));
8262
child = child->next;
8264
if (child != NULL) {
8265
xmlSchemaPContentErr(ctxt,
8266
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8268
NULL, "(annotation?)");
8275
* xmlSchemaParseIDC:
8276
* @ctxt: a schema validation context
8277
* @schema: the schema being built
8278
* @node: a subtree containing XML Schema informations
8280
* Parses a XML Schema identity-contraint definition.
8282
* Returns the parsed identity-constraint definition.
8284
static xmlSchemaIDCPtr
8285
xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
8286
xmlSchemaPtr schema,
8288
xmlSchemaTypeType idcCategory,
8289
const xmlChar *targetNamespace)
8291
xmlSchemaIDCPtr item = NULL;
8292
xmlNodePtr child = NULL;
8294
const xmlChar *name = NULL;
8295
xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
8298
* Check for illegal attributes.
8300
attr = node->properties;
8301
while (attr != NULL) {
8302
if (attr->ns == NULL) {
8303
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8304
(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8305
((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
8306
(!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
8307
xmlSchemaPIllegalAttrErr(ctxt,
8308
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8310
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8311
xmlSchemaPIllegalAttrErr(ctxt,
8312
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8317
* Attribute "name" (mandatory).
8319
attr = xmlSchemaGetPropNode(node, "name");
8321
xmlSchemaPMissingAttrErr(ctxt,
8322
XML_SCHEMAP_S4S_ATTR_MISSING,
8326
} else if (xmlSchemaPValAttrNode(ctxt,
8328
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
8331
/* Create the component. */
8332
item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
8337
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8338
if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
8340
* Attribute "refer" (mandatory).
8342
attr = xmlSchemaGetPropNode(node, "refer");
8344
xmlSchemaPMissingAttrErr(ctxt,
8345
XML_SCHEMAP_S4S_ATTR_MISSING,
8350
* Create a reference item.
8352
item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
8354
if (item->ref == NULL)
8356
xmlSchemaPValAttrNodeQName(ctxt, schema,
8358
&(item->ref->targetNamespace),
8359
&(item->ref->name));
8360
xmlSchemaCheckReference(ctxt, schema, node, attr,
8361
item->ref->targetNamespace);
8365
* And now for the children...
8367
child = node->children;
8368
if (IS_SCHEMA(child, "annotation")) {
8369
item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8370
child = child->next;
8372
if (child == NULL) {
8373
xmlSchemaPContentErr(ctxt,
8374
XML_SCHEMAP_S4S_ELEM_MISSING,
8376
"A child element is missing",
8377
"(annotation?, (selector, field+))");
8380
* Child element <selector>.
8382
if (IS_SCHEMA(child, "selector")) {
8383
item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
8385
child = child->next;
8387
* Child elements <field>.
8389
if (IS_SCHEMA(child, "field")) {
8391
field = xmlSchemaParseIDCSelectorAndField(ctxt,
8393
if (field != NULL) {
8394
field->index = item->nbFields;
8396
if (lastField != NULL)
8397
lastField->next = field;
8399
item->fields = field;
8402
child = child->next;
8403
} while (IS_SCHEMA(child, "field"));
8405
xmlSchemaPContentErr(ctxt,
8406
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8408
NULL, "(annotation?, (selector, field+))");
8411
if (child != NULL) {
8412
xmlSchemaPContentErr(ctxt,
8413
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8415
NULL, "(annotation?, (selector, field+))");
8422
* xmlSchemaParseElement:
8423
* @ctxt: a schema validation context
8424
* @schema: the schema being built
8425
* @node: a subtree containing XML Schema informations
8426
* @topLevel: indicates if this is global declaration
8428
* Parses a XML schema element declaration.
8429
* *WARNING* this interface is highly subject to change
8431
* Returns the element declaration or a particle; NULL in case
8432
* of an error or if the particle has minOccurs==maxOccurs==0.
8434
static xmlSchemaBasicItemPtr
8435
xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8436
xmlNodePtr node, int *isElemRef, int topLevel)
8438
xmlSchemaElementPtr decl = NULL;
8439
xmlSchemaParticlePtr particle = NULL;
8440
xmlSchemaAnnotPtr annot = NULL;
8441
xmlNodePtr child = NULL;
8442
xmlAttrPtr attr, nameAttr;
8443
int min, max, isRef = 0;
8444
xmlChar *des = NULL;
8446
/* 3.3.3 Constraints on XML Representations of Element Declarations */
8447
/* TODO: Complete implementation of 3.3.6 */
8449
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8452
if (isElemRef != NULL)
8455
* If we get a "ref" attribute on a local <element> we will assume it's
8456
* a reference - even if there's a "name" attribute; this seems to be more
8459
nameAttr = xmlSchemaGetPropNode(node, "name");
8460
attr = xmlSchemaGetPropNode(node, "ref");
8461
if ((topLevel) || (attr == NULL)) {
8462
if (nameAttr == NULL) {
8463
xmlSchemaPMissingAttrErr(ctxt,
8464
XML_SCHEMAP_S4S_ATTR_MISSING,
8465
NULL, node, "name", NULL);
8471
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8472
child = node->children;
8473
if (IS_SCHEMA(child, "annotation")) {
8474
annot = xmlSchemaParseAnnotation(ctxt, child, 1);
8475
child = child->next;
8478
* Skip particle part if a global declaration.
8481
goto declaration_part;
8483
* The particle part ==================================================
8485
min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
8486
max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
8487
xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
8488
particle = xmlSchemaAddParticle(ctxt, node, min, max);
8489
if (particle == NULL)
8492
/* ret->flags |= XML_SCHEMAS_ELEM_REF; */
8495
const xmlChar *refNs = NULL, *ref = NULL;
8496
xmlSchemaQNameRefPtr refer = NULL;
8498
* The reference part =============================================
8500
if (isElemRef != NULL)
8503
xmlSchemaPValAttrNodeQName(ctxt, schema,
8504
NULL, attr, &refNs, &ref);
8505
xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
8507
* SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
8509
if (nameAttr != NULL) {
8510
xmlSchemaPMutualExclAttrErr(ctxt,
8511
XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
8514
* Check for illegal attributes.
8516
attr = node->properties;
8517
while (attr != NULL) {
8518
if (attr->ns == NULL) {
8519
if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
8520
xmlStrEqual(attr->name, BAD_CAST "name") ||
8521
xmlStrEqual(attr->name, BAD_CAST "id") ||
8522
xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
8523
xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
8528
/* SPEC (3.3.3 : 2.2) */
8529
xmlSchemaPCustomAttrErr(ctxt,
8530
XML_SCHEMAP_SRC_ELEMENT_2_2,
8532
"Only the attributes 'minOccurs', 'maxOccurs' and "
8533
"'id' are allowed in addition to 'ref'");
8536
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8537
xmlSchemaPIllegalAttrErr(ctxt,
8538
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8543
* No children except <annotation> expected.
8545
if (child != NULL) {
8546
xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8547
NULL, node, child, NULL, "(annotation?)");
8549
if ((min == 0) && (max == 0))
8552
* Create the reference item and attach it to the particle.
8554
refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
8558
particle->children = (xmlSchemaTreeItemPtr) refer;
8559
particle->annot = annot;
8561
* Add the particle to pending components, since the reference
8562
* need to be resolved.
8564
WXS_ADD_PENDING(ctxt, particle);
8565
return ((xmlSchemaBasicItemPtr) particle);
8568
* The declaration part ===============================================
8572
const xmlChar *ns = NULL, *fixed, *name, *attrValue;
8573
xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
8575
if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
8576
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
8579
* Evaluate the target namespace.
8582
ns = ctxt->targetNamespace;
8584
attr = xmlSchemaGetPropNode(node, "form");
8586
attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8587
if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
8588
ns = ctxt->targetNamespace;
8589
} else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
8590
xmlSchemaPSimpleTypeErr(ctxt,
8591
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8592
NULL, (xmlNodePtr) attr,
8593
NULL, "(qualified | unqualified)",
8594
attrValue, NULL, NULL, NULL);
8596
} else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
8597
ns = ctxt->targetNamespace;
8599
decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
8604
* Check for illegal attributes.
8606
attr = node->properties;
8607
while (attr != NULL) {
8608
if (attr->ns == NULL) {
8609
if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
8610
(!xmlStrEqual(attr->name, BAD_CAST "type")) &&
8611
(!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8612
(!xmlStrEqual(attr->name, BAD_CAST "default")) &&
8613
(!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
8614
(!xmlStrEqual(attr->name, BAD_CAST "block")) &&
8615
(!xmlStrEqual(attr->name, BAD_CAST "nillable")))
8617
if (topLevel == 0) {
8618
if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
8619
(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
8620
(!xmlStrEqual(attr->name, BAD_CAST "form")))
8622
xmlSchemaPIllegalAttrErr(ctxt,
8623
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8625
} else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
8626
(!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
8627
(!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
8629
xmlSchemaPIllegalAttrErr(ctxt,
8630
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8633
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8635
xmlSchemaPIllegalAttrErr(ctxt,
8636
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8641
* Extract/validate attributes.
8645
* Process top attributes of global element declarations here.
8647
decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
8648
decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
8649
xmlSchemaPValAttrQName(ctxt, schema,
8650
NULL, node, "substitutionGroup",
8651
&(decl->substGroupNs), &(decl->substGroup));
8652
if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
8653
decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
8655
* Attribute "final".
8657
attr = xmlSchemaGetPropNode(node, "final");
8659
if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
8660
decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
8661
if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
8662
decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
8664
attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8665
if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8667
XML_SCHEMAS_ELEM_FINAL_EXTENSION,
8668
XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
8669
xmlSchemaPSimpleTypeErr(ctxt,
8670
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8671
NULL, (xmlNodePtr) attr,
8672
NULL, "(#all | List of (extension | restriction))",
8673
attrValue, NULL, NULL, NULL);
8678
* Attribute "block".
8680
attr = xmlSchemaGetPropNode(node, "block");
8683
* Apply default "block" values.
8685
if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
8686
decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
8687
if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
8688
decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
8689
if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
8690
decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
8692
attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8693
if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
8695
XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
8696
XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
8697
XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
8698
xmlSchemaPSimpleTypeErr(ctxt,
8699
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
8700
NULL, (xmlNodePtr) attr,
8701
NULL, "(#all | List of (extension | "
8702
"restriction | substitution))", attrValue,
8706
if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
8707
decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
8709
attr = xmlSchemaGetPropNode(node, "type");
8711
xmlSchemaPValAttrNodeQName(ctxt, schema,
8713
&(decl->namedTypeNs), &(decl->namedType));
8714
xmlSchemaCheckReference(ctxt, schema, node,
8715
attr, decl->namedTypeNs);
8717
decl->value = xmlSchemaGetProp(ctxt, node, "default");
8718
attr = xmlSchemaGetPropNode(node, "fixed");
8720
fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8721
if (decl->value != NULL) {
8724
* default and fixed must not both be present.
8726
xmlSchemaPMutualExclAttrErr(ctxt,
8727
XML_SCHEMAP_SRC_ELEMENT_1,
8728
NULL, attr, "default", "fixed");
8730
decl->flags |= XML_SCHEMAS_ELEM_FIXED;
8731
decl->value = fixed;
8735
* And now for the children...
8737
if (IS_SCHEMA(child, "complexType")) {
8740
* "type" and either <simpleType> or <complexType> are mutually
8743
if (decl->namedType != NULL) {
8744
xmlSchemaPContentErr(ctxt,
8745
XML_SCHEMAP_SRC_ELEMENT_3,
8747
"The attribute 'type' and the <complexType> child are "
8748
"mutually exclusive", NULL);
8750
WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
8751
child = child->next;
8752
} else if (IS_SCHEMA(child, "simpleType")) {
8755
* "type" and either <simpleType> or <complexType> are
8756
* mutually exclusive
8758
if (decl->namedType != NULL) {
8759
xmlSchemaPContentErr(ctxt,
8760
XML_SCHEMAP_SRC_ELEMENT_3,
8762
"The attribute 'type' and the <simpleType> child are "
8763
"mutually exclusive", NULL);
8765
WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8766
child = child->next;
8768
while ((IS_SCHEMA(child, "unique")) ||
8769
(IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
8770
if (IS_SCHEMA(child, "unique")) {
8771
curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8772
XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
8773
} else if (IS_SCHEMA(child, "key")) {
8774
curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8775
XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
8776
} else if (IS_SCHEMA(child, "keyref")) {
8777
curIDC = xmlSchemaParseIDC(ctxt, schema, child,
8778
XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
8780
if (lastIDC != NULL)
8781
lastIDC->next = curIDC;
8783
decl->idcs = (void *) curIDC;
8785
child = child->next;
8787
if (child != NULL) {
8788
xmlSchemaPContentErr(ctxt,
8789
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8791
NULL, "(annotation?, ((simpleType | complexType)?, "
8792
"(unique | key | keyref)*))");
8794
decl->annot = annot;
8797
* NOTE: Element Declaration Representation OK 4. will be checked at a
8802
return ((xmlSchemaBasicItemPtr) decl);
8804
particle->children = (xmlSchemaTreeItemPtr) decl;
8805
return ((xmlSchemaBasicItemPtr) particle);
8810
if (annot != NULL) {
8811
if (particle != NULL)
8812
particle->annot = NULL;
8815
xmlSchemaFreeAnnot(annot);
8821
* xmlSchemaParseUnion:
8822
* @ctxt: a schema validation context
8823
* @schema: the schema being built
8824
* @node: a subtree containing XML Schema informations
8826
* parse a XML schema Union definition
8827
* *WARNING* this interface is highly subject to change
8829
* Returns -1 in case of internal error, 0 in case of success and a positive
8830
* error code otherwise.
8833
xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
8836
xmlSchemaTypePtr type;
8837
xmlNodePtr child = NULL;
8839
const xmlChar *cur = NULL;
8841
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
8843
/* Not a component, don't create it. */
8844
type = ctxt->ctxtType;
8846
* Mark the simple type as being of variety "union".
8848
type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
8850
* SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
8851
* then the ļæ½simple ur-type definitionļæ½."
8853
type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
8855
* Check for illegal attributes.
8857
attr = node->properties;
8858
while (attr != NULL) {
8859
if (attr->ns == NULL) {
8860
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
8861
(!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
8862
xmlSchemaPIllegalAttrErr(ctxt,
8863
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8865
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
8866
xmlSchemaPIllegalAttrErr(ctxt,
8867
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
8871
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
8873
* Attribute "memberTypes". This is a list of QNames.
8874
* TODO: Check the value to contain anything.
8876
attr = xmlSchemaGetPropNode(node, "memberTypes");
8880
const xmlChar *localName, *nsName;
8881
xmlSchemaTypeLinkPtr link, lastLink = NULL;
8882
xmlSchemaQNameRefPtr ref;
8884
cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
8887
while (IS_BLANK_CH(*cur))
8890
while ((*end != 0) && (!(IS_BLANK_CH(*end))))
8894
tmp = xmlStrndup(cur, end - cur);
8895
if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
8896
NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
8898
* Create the member type link.
8900
link = (xmlSchemaTypeLinkPtr)
8901
xmlMalloc(sizeof(xmlSchemaTypeLink));
8903
xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
8904
"allocating a type link", NULL);
8909
if (lastLink == NULL)
8910
type->memberTypes = link;
8912
lastLink->next = link;
8915
* Create a reference item.
8917
ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
8924
* Assign the reference to the link, it will be resolved
8925
* later during fixup of the union simple type.
8927
link->type = (xmlSchemaTypePtr) ref;
8931
} while (*cur != 0);
8935
* And now for the children...
8937
child = node->children;
8938
if (IS_SCHEMA(child, "annotation")) {
8940
* Add the annotation to the simple type ancestor.
8942
xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
8943
xmlSchemaParseAnnotation(ctxt, child, 1));
8944
child = child->next;
8946
if (IS_SCHEMA(child, "simpleType")) {
8947
xmlSchemaTypePtr subtype, last = NULL;
8950
* Anchor the member types in the "subtypes" field of the
8953
while (IS_SCHEMA(child, "simpleType")) {
8954
subtype = (xmlSchemaTypePtr)
8955
xmlSchemaParseSimpleType(ctxt, schema, child, 0);
8956
if (subtype != NULL) {
8958
type->subtypes = subtype;
8961
last->next = subtype;
8966
child = child->next;
8969
if (child != NULL) {
8970
xmlSchemaPContentErr(ctxt,
8971
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
8972
NULL, node, child, NULL, "(annotation?, simpleType*)");
8974
if ((attr == NULL) && (type->subtypes == NULL)) {
8976
* src-union-memberTypes-or-simpleTypes
8977
* Either the memberTypes [attribute] of the <union> element must
8978
* be non-empty or there must be at least one simpleType [child].
8980
xmlSchemaPCustomErr(ctxt,
8981
XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
8983
"Either the attribute 'memberTypes' or "
8984
"at least one <simpleType> child must be present", NULL);
8990
* xmlSchemaParseList:
8991
* @ctxt: a schema validation context
8992
* @schema: the schema being built
8993
* @node: a subtree containing XML Schema informations
8995
* parse a XML schema List definition
8996
* *WARNING* this interface is highly subject to change
8998
* Returns -1 in case of error, 0 if the declaration is improper and
8999
* 1 in case of success.
9001
static xmlSchemaTypePtr
9002
xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9005
xmlSchemaTypePtr type;
9006
xmlNodePtr child = NULL;
9009
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9011
/* Not a component, don't create it. */
9012
type = ctxt->ctxtType;
9014
* Mark the type as being of variety "list".
9016
type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
9018
* SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
9019
* then the ļæ½simple ur-type definitionļæ½."
9021
type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
9023
* Check for illegal attributes.
9025
attr = node->properties;
9026
while (attr != NULL) {
9027
if (attr->ns == NULL) {
9028
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9029
(!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
9030
xmlSchemaPIllegalAttrErr(ctxt,
9031
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9033
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9034
xmlSchemaPIllegalAttrErr(ctxt,
9035
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9040
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9043
* Attribute "itemType". NOTE that we will use the "ref" and "refNs"
9044
* fields for holding the reference to the itemType.
9046
* REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
9049
xmlSchemaPValAttrQName(ctxt, schema, NULL,
9050
node, "itemType", &(type->baseNs), &(type->base));
9052
* And now for the children...
9054
child = node->children;
9055
if (IS_SCHEMA(child, "annotation")) {
9056
xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
9057
xmlSchemaParseAnnotation(ctxt, child, 1));
9058
child = child->next;
9060
if (IS_SCHEMA(child, "simpleType")) {
9062
* src-list-itemType-or-simpleType
9063
* Either the itemType [attribute] or the <simpleType> [child] of
9064
* the <list> element must be present, but not both.
9066
if (type->base != NULL) {
9067
xmlSchemaPCustomErr(ctxt,
9068
XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9070
"The attribute 'itemType' and the <simpleType> child "
9071
"are mutually exclusive", NULL);
9073
type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
9075
child = child->next;
9076
} else if (type->base == NULL) {
9077
xmlSchemaPCustomErr(ctxt,
9078
XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9080
"Either the attribute 'itemType' or the <simpleType> child "
9081
"must be present", NULL);
9083
if (child != NULL) {
9084
xmlSchemaPContentErr(ctxt,
9085
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9086
NULL, node, child, NULL, "(annotation?, simpleType?)");
9088
if ((type->base == NULL) &&
9089
(type->subtypes == NULL) &&
9090
(xmlSchemaGetPropNode(node, "itemType") == NULL)) {
9091
xmlSchemaPCustomErr(ctxt,
9092
XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
9094
"Either the attribute 'itemType' or the <simpleType> child "
9095
"must be present", NULL);
9101
* xmlSchemaParseSimpleType:
9102
* @ctxt: a schema validation context
9103
* @schema: the schema being built
9104
* @node: a subtree containing XML Schema informations
9106
* parse a XML schema Simple Type definition
9107
* *WARNING* this interface is highly subject to change
9109
* Returns -1 in case of error, 0 if the declaration is improper and
9110
* 1 in case of success.
9112
static xmlSchemaTypePtr
9113
xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
9114
xmlNodePtr node, int topLevel)
9116
xmlSchemaTypePtr type, oldCtxtType;
9117
xmlNodePtr child = NULL;
9118
const xmlChar *attrValue = NULL;
9120
int hasRestriction = 0;
9122
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9126
attr = xmlSchemaGetPropNode(node, "name");
9128
xmlSchemaPMissingAttrErr(ctxt,
9129
XML_SCHEMAP_S4S_ATTR_MISSING,
9134
if (xmlSchemaPValAttrNode(ctxt,
9136
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
9139
* Skip built-in types.
9142
xmlSchemaTypePtr biType;
9144
if (ctxt->isRedefine) {
9146
* REDEFINE: Disallow redefinition of built-in-types.
9147
* TODO: It seems that the spec does not say anything
9150
xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9152
"Redefinition of built-in simple types is not "
9156
biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
9164
* SPEC "The ļæ½actual valueļæ½ of the targetNamespace [attribute]
9165
* of the <schema> ancestor element information item if present,
9166
* otherwise ļæ½absentļæ½.
9168
if (topLevel == 0) {
9169
#ifdef ENABLE_NAMED_LOCALS
9173
* Parse as local simple type definition.
9175
#ifdef ENABLE_NAMED_LOCALS
9176
snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
9177
type = xmlSchemaAddType(ctxt, schema,
9178
XML_SCHEMA_TYPE_SIMPLE,
9179
xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
9180
ctxt->targetNamespace, node, 0);
9182
type = xmlSchemaAddType(ctxt, schema,
9183
XML_SCHEMA_TYPE_SIMPLE,
9184
NULL, ctxt->targetNamespace, node, 0);
9188
type->type = XML_SCHEMA_TYPE_SIMPLE;
9189
type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9191
* Check for illegal attributes.
9193
attr = node->properties;
9194
while (attr != NULL) {
9195
if (attr->ns == NULL) {
9196
if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
9197
xmlSchemaPIllegalAttrErr(ctxt,
9198
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9200
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9201
xmlSchemaPIllegalAttrErr(ctxt,
9202
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9208
* Parse as global simple type definition.
9210
* Note that attrValue is the value of the attribute "name" here.
9212
type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
9213
attrValue, ctxt->targetNamespace, node, 1);
9216
type->type = XML_SCHEMA_TYPE_SIMPLE;
9217
type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
9218
type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
9220
* Check for illegal attributes.
9222
attr = node->properties;
9223
while (attr != NULL) {
9224
if (attr->ns == NULL) {
9225
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9226
(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9227
(!xmlStrEqual(attr->name, BAD_CAST "final"))) {
9228
xmlSchemaPIllegalAttrErr(ctxt,
9229
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9231
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9232
xmlSchemaPIllegalAttrErr(ctxt,
9233
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9238
* Attribute "final".
9240
attr = xmlSchemaGetPropNode(node, "final");
9242
if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9243
type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
9244
if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9245
type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
9246
if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9247
type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
9249
attrValue = xmlSchemaGetProp(ctxt, node, "final");
9250
if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
9251
-1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
9252
XML_SCHEMAS_TYPE_FINAL_LIST,
9253
XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
9255
xmlSchemaPSimpleTypeErr(ctxt,
9256
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9257
WXS_BASIC_CAST type, (xmlNodePtr) attr,
9258
NULL, "(#all | List of (list | union | restriction)",
9259
attrValue, NULL, NULL, NULL);
9263
type->targetNamespace = ctxt->targetNamespace;
9264
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9266
* And now for the children...
9268
oldCtxtType = ctxt->ctxtType;
9270
ctxt->ctxtType = type;
9272
child = node->children;
9273
if (IS_SCHEMA(child, "annotation")) {
9274
type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9275
child = child->next;
9277
if (child == NULL) {
9278
xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
9279
NULL, node, child, NULL,
9280
"(annotation?, (restriction | list | union))");
9281
} else if (IS_SCHEMA(child, "restriction")) {
9282
xmlSchemaParseRestriction(ctxt, schema, child,
9283
XML_SCHEMA_TYPE_SIMPLE);
9285
child = child->next;
9286
} else if (IS_SCHEMA(child, "list")) {
9287
xmlSchemaParseList(ctxt, schema, child);
9288
child = child->next;
9289
} else if (IS_SCHEMA(child, "union")) {
9290
xmlSchemaParseUnion(ctxt, schema, child);
9291
child = child->next;
9293
if (child != NULL) {
9294
xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9295
NULL, node, child, NULL,
9296
"(annotation?, (restriction | list | union))");
9299
* REDEFINE: SPEC src-redefine (5)
9300
* "Within the [children], each <simpleType> must have a
9301
* <restriction> among its [children] ... the ļæ½actual valueļæ½ of whose
9302
* base [attribute] must be the same as the ļæ½actual valueļæ½ of its own
9303
* name attribute plus target namespace;"
9305
if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
9306
xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
9307
NULL, node, "This is a redefinition, thus the "
9308
"<simpleType> must have a <restriction> child", NULL);
9311
ctxt->ctxtType = oldCtxtType;
9316
* xmlSchemaParseModelGroupDefRef:
9317
* @ctxt: the parser context
9318
* @schema: the schema being built
9321
* Parses a reference to a model group definition.
9323
* We will return a particle component with a qname-component or
9324
* NULL in case of an error.
9326
static xmlSchemaTreeItemPtr
9327
xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
9328
xmlSchemaPtr schema,
9331
xmlSchemaParticlePtr item;
9332
xmlNodePtr child = NULL;
9334
const xmlChar *ref = NULL, *refNs = NULL;
9337
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9340
attr = xmlSchemaGetPropNode(node, "ref");
9342
xmlSchemaPMissingAttrErr(ctxt,
9343
XML_SCHEMAP_S4S_ATTR_MISSING,
9344
NULL, node, "ref", NULL);
9346
} else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
9347
attr, &refNs, &ref) != 0) {
9350
xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
9351
min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
9352
max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
9353
"(xs:nonNegativeInteger | unbounded)");
9355
* Check for illegal attributes.
9357
attr = node->properties;
9358
while (attr != NULL) {
9359
if (attr->ns == NULL) {
9360
if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
9361
(!xmlStrEqual(attr->name, BAD_CAST "id")) &&
9362
(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
9363
(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
9364
xmlSchemaPIllegalAttrErr(ctxt,
9365
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9367
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9368
xmlSchemaPIllegalAttrErr(ctxt,
9369
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9373
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9374
item = xmlSchemaAddParticle(ctxt, node, min, max);
9378
* Create a qname-reference and set as the term; it will be substituted
9379
* for the model group after the reference has been resolved.
9381
item->children = (xmlSchemaTreeItemPtr)
9382
xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
9383
xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
9385
* And now for the children...
9387
child = node->children;
9388
/* TODO: Is annotation even allowed for a model group reference? */
9389
if (IS_SCHEMA(child, "annotation")) {
9391
* TODO: What to do exactly with the annotation?
9393
item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9394
child = child->next;
9396
if (child != NULL) {
9397
xmlSchemaPContentErr(ctxt,
9398
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9399
NULL, node, child, NULL,
9403
* Corresponds to no component at all if minOccurs==maxOccurs==0.
9405
if ((min == 0) && (max == 0))
9408
return ((xmlSchemaTreeItemPtr) item);
9412
* xmlSchemaParseModelGroupDefinition:
9413
* @ctxt: a schema validation context
9414
* @schema: the schema being built
9415
* @node: a subtree containing XML Schema informations
9417
* Parses a XML schema model group definition.
9419
* Note that the contraint src-redefine (6.2) can't be applied until
9420
* references have been resolved. So we will do this at the
9421
* component fixup level.
9423
* *WARNING* this interface is highly subject to change
9425
* Returns -1 in case of error, 0 if the declaration is improper and
9426
* 1 in case of success.
9428
static xmlSchemaModelGroupDefPtr
9429
xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
9430
xmlSchemaPtr schema,
9433
xmlSchemaModelGroupDefPtr item;
9434
xmlNodePtr child = NULL;
9436
const xmlChar *name;
9438
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
9441
attr = xmlSchemaGetPropNode(node, "name");
9443
xmlSchemaPMissingAttrErr(ctxt,
9444
XML_SCHEMAP_S4S_ATTR_MISSING,
9448
} else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
9449
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
9452
item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
9453
ctxt->targetNamespace, node);
9457
* Check for illegal attributes.
9459
attr = node->properties;
9460
while (attr != NULL) {
9461
if (attr->ns == NULL) {
9462
if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
9463
(!xmlStrEqual(attr->name, BAD_CAST "id"))) {
9464
xmlSchemaPIllegalAttrErr(ctxt,
9465
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9467
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
9468
xmlSchemaPIllegalAttrErr(ctxt,
9469
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
9473
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9475
* And now for the children...
9477
child = node->children;
9478
if (IS_SCHEMA(child, "annotation")) {
9479
item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9480
child = child->next;
9482
if (IS_SCHEMA(child, "all")) {
9483
item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9484
XML_SCHEMA_TYPE_ALL, 0);
9485
child = child->next;
9486
} else if (IS_SCHEMA(child, "choice")) {
9487
item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9488
XML_SCHEMA_TYPE_CHOICE, 0);
9489
child = child->next;
9490
} else if (IS_SCHEMA(child, "sequence")) {
9491
item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
9492
XML_SCHEMA_TYPE_SEQUENCE, 0);
9493
child = child->next;
9498
if (child != NULL) {
9499
xmlSchemaPContentErr(ctxt,
9500
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9501
NULL, node, child, NULL,
9502
"(annotation?, (all | choice | sequence)?)");
9508
* xmlSchemaCleanupDoc:
9509
* @ctxt: a schema validation context
9510
* @node: the root of the document.
9512
* removes unwanted nodes in a schemas document tree
9515
xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
9517
xmlNodePtr delete, cur;
9519
if ((ctxt == NULL) || (root == NULL)) return;
9522
* Remove all the blank text nodes
9526
while (cur != NULL) {
9527
if (delete != NULL) {
9528
xmlUnlinkNode(delete);
9529
xmlFreeNode(delete);
9532
if (cur->type == XML_TEXT_NODE) {
9533
if (IS_BLANK_NODE(cur)) {
9534
if (xmlNodeGetSpacePreserve(cur) != 1) {
9538
} else if ((cur->type != XML_ELEMENT_NODE) &&
9539
(cur->type != XML_CDATA_SECTION_NODE)) {
9547
if (cur->children != NULL) {
9548
if ((cur->children->type != XML_ENTITY_DECL) &&
9549
(cur->children->type != XML_ENTITY_REF_NODE) &&
9550
(cur->children->type != XML_ENTITY_NODE)) {
9551
cur = cur->children;
9556
if (cur->next != NULL) {
9569
if (cur->next != NULL) {
9573
} while (cur != NULL);
9575
if (delete != NULL) {
9576
xmlUnlinkNode(delete);
9577
xmlFreeNode(delete);
9584
xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
9586
if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
9587
schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
9589
if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
9590
schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
9592
if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
9593
schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
9594
if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
9595
schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
9596
if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
9597
schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
9598
if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
9599
schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
9601
if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
9602
schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
9603
if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
9604
schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
9605
if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
9606
schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
9610
xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
9611
xmlSchemaPtr schema,
9616
int res = 0, oldErrs = ctxt->nberrors;
9619
* Those flags should be moved to the parser context flags,
9620
* since they are not visible at the component level. I.e.
9621
* they are used if processing schema *documents* only.
9623
res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
9627
* Since the version is of type xs:token, we won't bother to
9631
attr = xmlSchemaGetPropNode(node, "version");
9633
res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
9634
xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
9638
attr = xmlSchemaGetPropNode(node, "targetNamespace");
9640
res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
9641
xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
9644
ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
9648
attr = xmlSchemaGetPropNode(node, "elementFormDefault");
9650
val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9651
res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9652
XML_SCHEMAS_QUALIF_ELEM);
9655
xmlSchemaPSimpleTypeErr(ctxt,
9656
XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
9657
NULL, (xmlNodePtr) attr, NULL,
9658
"(qualified | unqualified)", val, NULL, NULL, NULL);
9661
attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
9663
val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9664
res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
9665
XML_SCHEMAS_QUALIF_ATTR);
9668
xmlSchemaPSimpleTypeErr(ctxt,
9669
XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
9670
NULL, (xmlNodePtr) attr, NULL,
9671
"(qualified | unqualified)", val, NULL, NULL, NULL);
9674
attr = xmlSchemaGetPropNode(node, "finalDefault");
9676
val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9677
res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9678
XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
9679
XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
9681
XML_SCHEMAS_FINAL_DEFAULT_LIST,
9682
XML_SCHEMAS_FINAL_DEFAULT_UNION);
9685
xmlSchemaPSimpleTypeErr(ctxt,
9686
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9687
NULL, (xmlNodePtr) attr, NULL,
9688
"(#all | List of (extension | restriction | list | union))",
9689
val, NULL, NULL, NULL);
9692
attr = xmlSchemaGetPropNode(node, "blockDefault");
9694
val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
9695
res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
9696
XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
9697
XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
9698
XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
9701
xmlSchemaPSimpleTypeErr(ctxt,
9702
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
9703
NULL, (xmlNodePtr) attr, NULL,
9704
"(#all | List of (extension | restriction | substitution))",
9705
val, NULL, NULL, NULL);
9710
if (oldErrs != ctxt->nberrors)
9718
* xmlSchemaParseSchemaTopLevel:
9719
* @ctxt: a schema validation context
9720
* @schema: the schemas
9721
* @nodes: the list of top level nodes
9723
* Returns the internal XML Schema structure built from the resource or
9724
* NULL in case of error
9727
xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
9728
xmlSchemaPtr schema, xmlNodePtr nodes)
9731
xmlSchemaAnnotPtr annot;
9732
int res = 0, oldErrs, tmpOldErrs;
9734
if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
9737
oldErrs = ctxt->nberrors;
9739
while ((IS_SCHEMA(child, "include")) ||
9740
(IS_SCHEMA(child, "import")) ||
9741
(IS_SCHEMA(child, "redefine")) ||
9742
(IS_SCHEMA(child, "annotation"))) {
9743
if (IS_SCHEMA(child, "annotation")) {
9744
annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9745
if (schema->annot == NULL)
9746
schema->annot = annot;
9748
xmlSchemaFreeAnnot(annot);
9749
} else if (IS_SCHEMA(child, "import")) {
9750
tmpOldErrs = ctxt->nberrors;
9751
res = xmlSchemaParseImport(ctxt, schema, child);
9754
if (tmpOldErrs != ctxt->nberrors)
9756
} else if (IS_SCHEMA(child, "include")) {
9757
tmpOldErrs = ctxt->nberrors;
9758
res = xmlSchemaParseInclude(ctxt, schema, child);
9761
if (tmpOldErrs != ctxt->nberrors)
9763
} else if (IS_SCHEMA(child, "redefine")) {
9764
tmpOldErrs = ctxt->nberrors;
9765
res = xmlSchemaParseRedefine(ctxt, schema, child);
9768
if (tmpOldErrs != ctxt->nberrors)
9771
child = child->next;
9774
* URGENT TODO: Change the functions to return int results.
9775
* We need especially to catch internal errors.
9777
while (child != NULL) {
9778
if (IS_SCHEMA(child, "complexType")) {
9779
xmlSchemaParseComplexType(ctxt, schema, child, 1);
9780
child = child->next;
9781
} else if (IS_SCHEMA(child, "simpleType")) {
9782
xmlSchemaParseSimpleType(ctxt, schema, child, 1);
9783
child = child->next;
9784
} else if (IS_SCHEMA(child, "element")) {
9785
xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
9786
child = child->next;
9787
} else if (IS_SCHEMA(child, "attribute")) {
9788
xmlSchemaParseGlobalAttribute(ctxt, schema, child);
9789
child = child->next;
9790
} else if (IS_SCHEMA(child, "attributeGroup")) {
9791
xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
9792
child = child->next;
9793
} else if (IS_SCHEMA(child, "group")) {
9794
xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
9795
child = child->next;
9796
} else if (IS_SCHEMA(child, "notation")) {
9797
xmlSchemaParseNotation(ctxt, schema, child);
9798
child = child->next;
9800
xmlSchemaPContentErr(ctxt,
9801
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
9802
NULL, child->parent, child,
9803
NULL, "((include | import | redefine | annotation)*, "
9804
"(((simpleType | complexType | group | attributeGroup) "
9805
"| element | attribute | notation), annotation*)*)");
9806
child = child->next;
9808
while (IS_SCHEMA(child, "annotation")) {
9810
* TODO: We should add all annotations.
9812
annot = xmlSchemaParseAnnotation(ctxt, child, 1);
9813
if (schema->annot == NULL)
9814
schema->annot = annot;
9816
xmlSchemaFreeAnnot(annot);
9817
child = child->next;
9821
ctxt->ctxtType = NULL;
9822
if (oldErrs != ctxt->nberrors)
9829
static xmlSchemaSchemaRelationPtr
9830
xmlSchemaSchemaRelationCreate(void)
9832
xmlSchemaSchemaRelationPtr ret;
9834
ret = (xmlSchemaSchemaRelationPtr)
9835
xmlMalloc(sizeof(xmlSchemaSchemaRelation));
9837
xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
9840
memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
9846
xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
9853
xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
9855
xmlSchemaRedefPtr prev;
9857
while (redef != NULL) {
9859
redef = redef->next;
9865
xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
9868
* After the construction context has been freed, there will be
9869
* no schema graph available any more. Only the schema buckets
9870
* will stay alive, which are put into the "schemasImports" and
9871
* "includes" slots of the xmlSchema.
9873
if (con->buckets != NULL)
9874
xmlSchemaItemListFree(con->buckets);
9875
if (con->pending != NULL)
9876
xmlSchemaItemListFree(con->pending);
9877
if (con->substGroups != NULL)
9878
xmlHashFree(con->substGroups,
9879
(xmlHashDeallocator) xmlSchemaSubstGroupFree);
9880
if (con->redefs != NULL)
9881
xmlSchemaRedefListFree(con->redefs);
9882
if (con->dict != NULL)
9883
xmlDictFree(con->dict);
9887
static xmlSchemaConstructionCtxtPtr
9888
xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
9890
xmlSchemaConstructionCtxtPtr ret;
9892
ret = (xmlSchemaConstructionCtxtPtr)
9893
xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
9895
xmlSchemaPErrMemory(NULL,
9896
"allocating schema construction context", NULL);
9899
memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
9901
ret->buckets = xmlSchemaItemListCreate();
9902
if (ret->buckets == NULL) {
9903
xmlSchemaPErrMemory(NULL,
9904
"allocating list of schema buckets", NULL);
9908
ret->pending = xmlSchemaItemListCreate();
9909
if (ret->pending == NULL) {
9910
xmlSchemaPErrMemory(NULL,
9911
"allocating list of pending global components", NULL);
9912
xmlSchemaConstructionCtxtFree(ret);
9916
xmlDictReference(dict);
9920
static xmlSchemaParserCtxtPtr
9921
xmlSchemaParserCtxtCreate(void)
9923
xmlSchemaParserCtxtPtr ret;
9925
ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
9927
xmlSchemaPErrMemory(NULL, "allocating schema parser context",
9931
memset(ret, 0, sizeof(xmlSchemaParserCtxt));
9932
ret->type = XML_SCHEMA_CTXT_PARSER;
9933
ret->attrProhibs = xmlSchemaItemListCreate();
9934
if (ret->attrProhibs == NULL) {
9942
* xmlSchemaNewParserCtxtUseDict:
9943
* @URL: the location of the schema
9944
* @dict: the dictionary to be used
9946
* Create an XML Schemas parse context for that file/resource expected
9947
* to contain an XML Schemas file.
9949
* Returns the parser context or NULL in case of error
9951
static xmlSchemaParserCtxtPtr
9952
xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
9954
xmlSchemaParserCtxtPtr ret;
9956
ret = xmlSchemaParserCtxtCreate();
9960
xmlDictReference(dict);
9962
ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
9967
xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
9969
if (vctxt->pctxt == NULL) {
9970
if (vctxt->schema != NULL)
9972
xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
9974
vctxt->pctxt = xmlSchemaNewParserCtxt("*");
9975
if (vctxt->pctxt == NULL) {
9976
VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
9977
"failed to create a temp. parser context");
9980
/* TODO: Pass user data. */
9981
xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
9982
vctxt->warning, vctxt->errCtxt);
9983
xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
9990
* xmlSchemaGetSchemaBucket:
9991
* @pctxt: the schema parser context
9992
* @schemaLocation: the URI of the schema document
9994
* Returns a schema bucket if it was already parsed.
9996
* Returns a schema bucket if it was already parsed from
9997
* @schemaLocation, NULL otherwise.
9999
static xmlSchemaBucketPtr
10000
xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10001
const xmlChar *schemaLocation)
10003
xmlSchemaBucketPtr cur;
10004
xmlSchemaItemListPtr list;
10006
list = pctxt->constructor->buckets;
10007
if (list->nbItems == 0)
10011
for (i = 0; i < list->nbItems; i++) {
10012
cur = (xmlSchemaBucketPtr) list->items[i];
10013
/* Pointer comparison! */
10014
if (cur->schemaLocation == schemaLocation)
10021
static xmlSchemaBucketPtr
10022
xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10023
const xmlChar *schemaLocation,
10024
const xmlChar *targetNamespace)
10026
xmlSchemaBucketPtr cur;
10027
xmlSchemaItemListPtr list;
10029
list = pctxt->constructor->buckets;
10030
if (list->nbItems == 0)
10034
for (i = 0; i < list->nbItems; i++) {
10035
cur = (xmlSchemaBucketPtr) list->items[i];
10036
/* Pointer comparison! */
10037
if ((cur->origTargetNamespace == NULL) &&
10038
(cur->schemaLocation == schemaLocation) &&
10039
(cur->targetNamespace == targetNamespace))
10047
#define IS_BAD_SCHEMA_DOC(b) \
10048
(((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10050
static xmlSchemaBucketPtr
10051
xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
10052
const xmlChar *targetNamespace,
10055
xmlSchemaBucketPtr cur;
10056
xmlSchemaItemListPtr list;
10058
list = pctxt->constructor->buckets;
10059
if (list->nbItems == 0)
10063
for (i = 0; i < list->nbItems; i++) {
10064
cur = (xmlSchemaBucketPtr) list->items[i];
10065
if ((! IS_BAD_SCHEMA_DOC(cur)) &&
10066
(cur->origTargetNamespace == targetNamespace) &&
10067
((imported && cur->imported) ||
10068
((!imported) && (!cur->imported))))
10076
xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
10077
xmlSchemaPtr schema,
10078
xmlSchemaBucketPtr bucket)
10084
xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
10087
* Save old values; reset the *main* schema.
10088
* URGENT TODO: This is not good; move the per-document information
10089
* to the parser. Get rid of passing the main schema to the
10090
* parsing functions.
10092
oldFlags = schema->flags;
10093
oldDoc = schema->doc;
10094
if (schema->flags != 0)
10095
xmlSchemaClearSchemaDefaults(schema);
10096
schema->doc = bucket->doc;
10097
pctxt->schema = schema;
10099
* Keep the current target namespace on the parser *not* on the
10102
pctxt->targetNamespace = bucket->targetNamespace;
10103
WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
10105
if ((bucket->targetNamespace != NULL) &&
10106
xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
10108
* We are parsing the schema for schemas!
10112
/* Mark it as parsed, even if parsing fails. */
10114
/* Compile the schema doc. */
10115
node = xmlDocGetRootElement(bucket->doc);
10116
ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
10119
/* An empty schema; just get out. */
10120
if (node->children == NULL)
10122
oldErrs = pctxt->nberrors;
10123
ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
10127
* TODO: Not nice, but I'm not 100% sure we will get always an error
10128
* as a result of the obove functions; so better rely on pctxt->err
10131
if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
10137
WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
10138
/* Restore schema values. */
10139
schema->doc = oldDoc;
10140
schema->flags = oldFlags;
10145
xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
10146
xmlSchemaPtr schema,
10147
xmlSchemaBucketPtr bucket)
10149
xmlSchemaParserCtxtPtr newpctxt;
10152
if (bucket == NULL)
10154
if (bucket->parsed) {
10155
PERROR_INT("xmlSchemaParseNewDoc",
10156
"reparsing a schema doc");
10159
if (bucket->doc == NULL) {
10160
PERROR_INT("xmlSchemaParseNewDoc",
10161
"parsing a schema doc, but there's no doc");
10164
if (pctxt->constructor == NULL) {
10165
PERROR_INT("xmlSchemaParseNewDoc",
10169
/* Create and init the temporary parser context. */
10170
newpctxt = xmlSchemaNewParserCtxtUseDict(
10171
(const char *) bucket->schemaLocation, pctxt->dict);
10172
if (newpctxt == NULL)
10174
newpctxt->constructor = pctxt->constructor;
10176
* TODO: Can we avoid that the parser knows about the main schema?
10177
* It would be better if he knows about the current schema bucket
10180
newpctxt->schema = schema;
10181
xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
10183
xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
10185
newpctxt->counter = pctxt->counter;
10188
res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
10190
/* Channel back errors and cleanup the temporary parser context. */
10193
pctxt->nberrors += newpctxt->nberrors;
10194
pctxt->counter = newpctxt->counter;
10195
newpctxt->constructor = NULL;
10196
/* Free the parser context. */
10197
xmlSchemaFreeParserCtxt(newpctxt);
10202
xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
10203
xmlSchemaSchemaRelationPtr rel)
10205
xmlSchemaSchemaRelationPtr cur = bucket->relations;
10208
bucket->relations = rel;
10211
while (cur->next != NULL)
10217
static const xmlChar *
10218
xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
10219
xmlNodePtr ctxtNode)
10222
* Build an absolue location URI.
10224
if (location != NULL) {
10225
if (ctxtNode == NULL)
10228
xmlChar *base, *URI;
10229
const xmlChar *ret = NULL;
10231
base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
10232
if (base == NULL) {
10233
URI = xmlBuildURI(location, ctxtNode->doc->URL);
10235
URI = xmlBuildURI(location, base);
10239
ret = xmlDictLookup(dict, URI, -1);
10251
* xmlSchemaAddSchemaDoc:
10252
* @pctxt: a schema validation context
10253
* @schema: the schema being built
10254
* @node: a subtree containing XML Schema informations
10256
* Parse an included (and to-be-redefined) XML schema document.
10258
* Returns 0 on success, a positive error code on errors and
10259
* -1 in case of an internal or API error.
10263
xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
10264
int type, /* import or include or redefine */
10265
const xmlChar *schemaLocation,
10266
xmlDocPtr schemaDoc,
10267
const char *schemaBuffer,
10268
int schemaBufferLen,
10269
xmlNodePtr invokingNode,
10270
const xmlChar *sourceTargetNamespace,
10271
const xmlChar *importNamespace,
10272
xmlSchemaBucketPtr *bucket)
10274
const xmlChar *targetNamespace = NULL;
10275
xmlSchemaSchemaRelationPtr relation = NULL;
10276
xmlDocPtr doc = NULL;
10277
int res = 0, err = 0, located = 0, preserveDoc = 0;
10278
xmlSchemaBucketPtr bkt = NULL;
10280
if (bucket != NULL)
10284
case XML_SCHEMA_SCHEMA_IMPORT:
10285
case XML_SCHEMA_SCHEMA_MAIN:
10286
err = XML_SCHEMAP_SRC_IMPORT;
10288
case XML_SCHEMA_SCHEMA_INCLUDE:
10289
err = XML_SCHEMAP_SRC_INCLUDE;
10291
case XML_SCHEMA_SCHEMA_REDEFINE:
10292
err = XML_SCHEMAP_SRC_REDEFINE;
10297
/* Special handling for the main schema:
10298
* skip the location and relation logic and just parse the doc.
10299
* We need just a bucket to be returned in this case.
10301
if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
10304
/* Note that we expect the location to be an absulute URI. */
10305
if (schemaLocation != NULL) {
10306
bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
10307
if ((bkt != NULL) &&
10308
(pctxt->constructor->bucket == bkt)) {
10309
/* Report self-imports/inclusions/redefinitions. */
10311
xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10312
invokingNode, NULL,
10313
"The schema must not import/include/redefine itself",
10319
* Create a relation for the graph of schemas.
10321
relation = xmlSchemaSchemaRelationCreate();
10322
if (relation == NULL)
10324
xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10326
relation->type = type;
10329
* Save the namespace import information.
10331
if (WXS_IS_BUCKET_IMPMAIN(type)) {
10332
relation->importNamespace = importNamespace;
10333
if (schemaLocation == NULL) {
10335
* No location; this is just an import of the namespace.
10336
* Note that we don't assign a bucket to the relation
10341
targetNamespace = importNamespace;
10344
/* Did we already fetch the doc? */
10346
/* TODO: The following nasty cases will produce an error. */
10347
if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
10348
/* We included/redefined and then try to import a schema. */
10349
if (schemaLocation == NULL)
10350
schemaLocation = BAD_CAST "in_memory_buffer";
10351
xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10352
invokingNode, NULL,
10353
"The schema document '%s' cannot be imported, since "
10354
"it was already included or redefined",
10355
schemaLocation, NULL);
10357
} else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
10358
/* We imported and then try to include/redefine a schema. */
10359
if (schemaLocation == NULL)
10360
schemaLocation = BAD_CAST "in_memory_buffer";
10361
xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10362
invokingNode, NULL,
10363
"The schema document '%s' cannot be included or "
10364
"redefined, since it was already imported",
10365
schemaLocation, NULL);
10370
if (WXS_IS_BUCKET_IMPMAIN(type)) {
10372
* Given that the schemaLocation [attribute] is only a hint, it is open
10373
* to applications to ignore all but the first <import> for a given
10374
* namespace, regardless of the ļæ½actual valueļæ½ of schemaLocation, but
10375
* such a strategy risks missing useful information when new
10376
* schemaLocations are offered.
10378
* We will use the first <import> that comes with a location.
10379
* Further <import>s *with* a location, will result in an error.
10380
* TODO: Better would be to just report a warning here, but
10381
* we'll try it this way until someone complains.
10383
* Schema Document Location Strategy:
10384
* 3 Based on the namespace name, identify an existing schema document,
10385
* either as a resource which is an XML document or a <schema> element
10386
* information item, in some local schema repository;
10387
* 5 Attempt to resolve the namespace name to locate such a resource.
10389
* NOTE: (3) and (5) are not supported.
10392
relation->bucket = bkt;
10395
bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10396
importNamespace, 1);
10399
relation->bucket = bkt;
10400
if (bkt->schemaLocation == NULL) {
10401
/* First given location of the schema; load the doc. */
10402
bkt->schemaLocation = schemaLocation;
10404
if (!xmlStrEqual(schemaLocation,
10405
bkt->schemaLocation)) {
10407
* Additional location given; just skip it.
10408
* URGENT TODO: We should report a warning here.
10409
* res = XML_SCHEMAP_SRC_IMPORT;
10411
if (schemaLocation == NULL)
10412
schemaLocation = BAD_CAST "in_memory_buffer";
10414
xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10415
XML_SCHEMAP_WARN_SKIP_SCHEMA,
10416
invokingNode, NULL,
10417
"Skipping import of schema located at '%s' for the "
10418
"namespace '%s', since this namespace was already "
10419
"imported with the schema located at '%s'",
10420
schemaLocation, importNamespace, bkt->schemaLocation);
10426
* No bucket + first location: load the doc and create a
10430
/* <include> and <redefine> */
10433
if ((bkt->origTargetNamespace == NULL) &&
10434
(bkt->targetNamespace != sourceTargetNamespace)) {
10435
xmlSchemaBucketPtr chamel;
10438
* Chameleon include/redefine: skip loading only if it was
10439
* aleady build for the targetNamespace of the including
10443
* URGENT TODO: If the schema is a chameleon-include then copy
10444
* the components into the including schema and modify the
10445
* targetNamespace of those components, do nothing otherwise.
10446
* NOTE: This is currently worked-around by compiling the
10447
* chameleon for every destinct including targetNamespace; thus
10448
* not performant at the moment.
10449
* TODO: Check when the namespace in wildcards for chameleons
10450
* needs to be converted: before we built wildcard intersections
10454
chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10455
schemaLocation, sourceTargetNamespace);
10456
if (chamel != NULL) {
10457
/* A fitting chameleon was already parsed; NOP. */
10458
relation->bucket = chamel;
10462
* We need to parse the chameleon again for a different
10464
* CHAMELEON TODO: Optimize this by only parsing the
10465
* chameleon once, and then copying the components to
10466
* the new targetNamespace.
10470
relation->bucket = bkt;
10475
if ((bkt != NULL) && (bkt->doc != NULL)) {
10476
PERROR_INT("xmlSchemaAddSchemaDoc",
10477
"trying to load a schema doc, but a doc is already "
10478
"assigned to the schema bucket");
10484
* Load the document.
10486
if (schemaDoc != NULL) {
10488
/* Don' free this one, since it was provided by the caller. */
10490
/* TODO: Does the context or the doc hold the location? */
10491
if (schemaDoc->URL != NULL)
10492
schemaLocation = xmlDictLookup(pctxt->dict,
10493
schemaDoc->URL, -1);
10495
schemaLocation = BAD_CAST "in_memory_buffer";
10496
} else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
10497
xmlParserCtxtPtr parserCtxt;
10499
parserCtxt = xmlNewParserCtxt();
10500
if (parserCtxt == NULL) {
10501
xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
10502
"allocating a parser context", NULL);
10505
if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
10507
* TODO: Do we have to burden the schema parser dict with all
10508
* the content of the schema doc?
10510
xmlDictFree(parserCtxt->dict);
10511
parserCtxt->dict = pctxt->dict;
10512
xmlDictReference(parserCtxt->dict);
10514
if (schemaLocation != NULL) {
10515
/* Parse from file. */
10516
doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
10517
NULL, SCHEMAS_PARSE_OPTIONS);
10518
} else if (schemaBuffer != NULL) {
10519
/* Parse from memory buffer. */
10520
doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
10521
NULL, NULL, SCHEMAS_PARSE_OPTIONS);
10522
schemaLocation = xmlStrdup(BAD_CAST "in_memory_buffer");
10524
doc->URL = schemaLocation;
10528
* 2.1 The referent is (a fragment of) a resource which is an
10529
* XML document (see clause 1.1), which in turn corresponds to
10530
* a <schema> element information item in a well-formed information
10531
* set, which in turn corresponds to a valid schema.
10532
* TODO: (2.1) fragments of XML documents are not supported.
10534
* 2.2 The referent is a <schema> element information item in
10535
* a well-formed information set, which in turn corresponds
10536
* to a valid schema.
10537
* TODO: (2.2) is not supported.
10541
lerr = xmlGetLastError();
10543
* Check if this a parser error, or if the document could
10544
* just not be located.
10545
* TODO: Try to find specific error codes to react only on
10546
* localisation failures.
10548
if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
10550
* We assume a parser error here.
10553
/* TODO: Error code ?? */
10554
res = XML_SCHEMAP_SRC_IMPORT_2_1;
10555
xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10556
invokingNode, NULL,
10557
"Failed to parse the XML resource '%s'",
10558
schemaLocation, NULL);
10561
xmlFreeParserCtxt(parserCtxt);
10562
if ((doc == NULL) && located)
10565
xmlSchemaPErr(pctxt, NULL,
10566
XML_SCHEMAP_NOTHING_TO_PARSE,
10567
"No information for parsing was provided with the "
10568
"given schema parser context.\n",
10573
* Preprocess the document.
10576
xmlNodePtr docElem = NULL;
10579
docElem = xmlDocGetRootElement(doc);
10580
if (docElem == NULL) {
10581
xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
10582
invokingNode, NULL,
10583
"The document '%s' has no document element",
10584
schemaLocation, NULL);
10588
* Remove all the blank text nodes.
10590
xmlSchemaCleanupDoc(pctxt, docElem);
10592
* Check the schema's top level element.
10594
if (!IS_SCHEMA(docElem, "schema")) {
10595
xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
10596
invokingNode, NULL,
10597
"The XML document '%s' is not a schema document",
10598
schemaLocation, NULL);
10602
* Note that we don't apply a type check for the
10603
* targetNamespace value here.
10605
targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10606
"targetNamespace");
10609
/* after_doc_loading: */
10610
if ((bkt == NULL) && located) {
10611
/* Only create a bucket if the schema was located. */
10612
bkt = xmlSchemaBucketCreate(pctxt, type,
10618
bkt->schemaLocation = schemaLocation;
10619
bkt->located = located;
10622
bkt->targetNamespace = targetNamespace;
10623
bkt->origTargetNamespace = targetNamespace;
10625
bkt->preserveDoc = 1;
10627
if (WXS_IS_BUCKET_IMPMAIN(type))
10630
* Add it to the graph of schemas.
10632
if (relation != NULL)
10633
relation->bucket = bkt;
10638
* Return the bucket explicitely; this is needed for the
10641
if (bucket != NULL)
10646
if ((doc != NULL) && (! preserveDoc)) {
10651
return(pctxt->err);
10654
if ((doc != NULL) && (! preserveDoc)) {
10663
* xmlSchemaParseImport:
10664
* @ctxt: a schema validation context
10665
* @schema: the schema being built
10666
* @node: a subtree containing XML Schema informations
10668
* parse a XML schema Import definition
10669
* *WARNING* this interface is highly subject to change
10671
* Returns 0 in case of success, a positive error code if
10672
* not valid and -1 in case of an internal error.
10675
xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10679
const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
10680
const xmlChar *thisTargetNamespace;
10683
xmlSchemaBucketPtr bucket = NULL;
10685
if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10689
* Check for illegal attributes.
10691
attr = node->properties;
10692
while (attr != NULL) {
10693
if (attr->ns == NULL) {
10694
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10695
(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
10696
(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10697
xmlSchemaPIllegalAttrErr(pctxt,
10698
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10700
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10701
xmlSchemaPIllegalAttrErr(pctxt,
10702
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10707
* Extract and validate attributes.
10709
if (xmlSchemaPValAttr(pctxt, NULL, node,
10710
"namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10711
&namespaceName) != 0) {
10712
xmlSchemaPSimpleTypeErr(pctxt,
10713
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10715
xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10716
NULL, namespaceName, NULL, NULL, NULL);
10717
return (pctxt->err);
10720
if (xmlSchemaPValAttr(pctxt, NULL, node,
10721
"schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10722
&schemaLocation) != 0) {
10723
xmlSchemaPSimpleTypeErr(pctxt,
10724
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10726
xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10727
NULL, namespaceName, NULL, NULL, NULL);
10728
return (pctxt->err);
10731
* And now for the children...
10733
child = node->children;
10734
if (IS_SCHEMA(child, "annotation")) {
10736
* the annotation here is simply discarded ...
10739
child = child->next;
10741
if (child != NULL) {
10742
xmlSchemaPContentErr(pctxt,
10743
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
10744
NULL, node, child, NULL,
10748
* Apply additional constraints.
10750
* Note that it is important to use the original @targetNamespace
10751
* (or none at all), to rule out imports of schemas _with_ a
10752
* @targetNamespace if the importing schema is a chameleon schema
10753
* (with no @targetNamespace).
10755
thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
10756
if (namespaceName != NULL) {
10758
* 1.1 If the namespace [attribute] is present, then its ļæ½actual valueļæ½
10759
* must not match the ļæ½actual valueļæ½ of the enclosing <schema>'s
10760
* targetNamespace [attribute].
10762
if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10763
xmlSchemaPCustomErr(pctxt,
10764
XML_SCHEMAP_SRC_IMPORT_1_1,
10766
"The value of the attribute 'namespace' must not match "
10767
"the target namespace '%s' of the importing schema",
10768
thisTargetNamespace);
10769
return (pctxt->err);
10773
* 1.2 If the namespace [attribute] is not present, then the enclosing
10774
* <schema> must have a targetNamespace [attribute].
10776
if (thisTargetNamespace == NULL) {
10777
xmlSchemaPCustomErr(pctxt,
10778
XML_SCHEMAP_SRC_IMPORT_1_2,
10780
"The attribute 'namespace' must be existent if "
10781
"the importing schema has no target namespace",
10783
return (pctxt->err);
10787
* Locate and acquire the schema document.
10789
if (schemaLocation != NULL)
10790
schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
10791
schemaLocation, node);
10792
ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
10793
schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
10794
namespaceName, &bucket);
10800
* For <import>: "It is *not* an error for the application
10801
* schema reference strategy to fail."
10802
* So just don't parse if no schema document was found.
10803
* Note that we will get no bucket if the schema could not be
10804
* located or if there was no schemaLocation.
10806
if ((bucket == NULL) && (schemaLocation != NULL)) {
10807
xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10808
XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
10810
"Failed to locate a schema at location '%s'. "
10811
"Skipping the import", schemaLocation, NULL, NULL);
10814
if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
10815
ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10822
xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10823
xmlSchemaPtr schema,
10825
xmlChar **schemaLocation,
10830
if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
10831
(schemaLocation == NULL))
10834
*schemaLocation = NULL;
10836
* Check for illegal attributes.
10837
* Applies for both <include> and <redefine>.
10839
attr = node->properties;
10840
while (attr != NULL) {
10841
if (attr->ns == NULL) {
10842
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10843
(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10844
xmlSchemaPIllegalAttrErr(pctxt,
10845
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10847
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10848
xmlSchemaPIllegalAttrErr(pctxt,
10849
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10853
xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
10855
* Preliminary step, extract the URI-Reference and make an URI
10859
* Attribute "schemaLocation" is mandatory.
10861
attr = xmlSchemaGetPropNode(node, "schemaLocation");
10862
if (attr != NULL) {
10863
xmlChar *base = NULL;
10864
xmlChar *uri = NULL;
10866
if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
10867
xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10868
(const xmlChar **) schemaLocation) != 0)
10870
base = xmlNodeGetBase(node->doc, node);
10871
if (base == NULL) {
10872
uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10874
uri = xmlBuildURI(*schemaLocation, base);
10878
PERROR_INT("xmlSchemaParseIncludeOrRedefine",
10879
"could not build an URI from the schemaLocation")
10882
(*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
10885
xmlSchemaPMissingAttrErr(pctxt,
10886
XML_SCHEMAP_S4S_ATTR_MISSING,
10887
NULL, node, "schemaLocation", NULL);
10891
* Report self-inclusion and self-redefinition.
10893
if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
10894
if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
10895
xmlSchemaPCustomErr(pctxt,
10896
XML_SCHEMAP_SRC_REDEFINE,
10898
"The schema document '%s' cannot redefine itself.",
10901
xmlSchemaPCustomErr(pctxt,
10902
XML_SCHEMAP_SRC_INCLUDE,
10904
"The schema document '%s' cannot include itself.",
10912
return(pctxt->err);
10918
xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
10919
xmlSchemaPtr schema,
10923
xmlNodePtr child = NULL;
10924
const xmlChar *schemaLocation = NULL;
10925
int res = 0; /* hasRedefinitions = 0 */
10926
int isChameleon = 0, wasChameleon = 0;
10927
xmlSchemaBucketPtr bucket = NULL;
10929
if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10933
* Parse attributes. Note that the returned schemaLocation will
10934
* be already converted to an absolute URI.
10936
res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
10937
node, (xmlChar **) (&schemaLocation), type);
10941
* Load and add the schema document.
10943
res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
10944
NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
10948
* If we get no schema bucket back, then this means that the schema
10949
* document could not be located or was broken XML or was not
10950
* a schema document.
10952
if ((bucket == NULL) || (bucket->doc == NULL)) {
10953
if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
10955
* WARNING for <include>:
10956
* We will raise an error if the schema cannot be located
10957
* for inclusions, since the that was the feedback from the
10958
* schema people. I.e. the following spec piece will *not* be
10960
* SPEC src-include: "It is not an error for the ļæ½actual valueļæ½ of the
10961
* schemaLocation [attribute] to fail to resolve it all, in which
10962
* case no corresponding inclusion is performed.
10963
* So do we need a warning report here?"
10965
res = XML_SCHEMAP_SRC_INCLUDE;
10966
xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10968
"Failed to load the document '%s' for inclusion",
10969
schemaLocation, NULL);
10972
* NOTE: This was changed to raise an error even if no redefinitions
10975
* SPEC src-redefine (1)
10976
* "If there are any element information items among the [children]
10977
* other than <annotation> then the ļæ½actual valueļæ½ of the
10978
* schemaLocation [attribute] must successfully resolve."
10979
* TODO: Ask the WG if a the location has always to resolve
10982
res = XML_SCHEMAP_SRC_REDEFINE;
10983
xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10985
"Failed to load the document '%s' for redefinition",
10986
schemaLocation, NULL);
10990
* Check targetNamespace sanity before parsing the new schema.
10991
* TODO: Note that we won't check further content if the
10992
* targetNamespace was bad.
10994
if (bucket->origTargetNamespace != NULL) {
10996
* SPEC src-include (2.1)
10997
* "SII has a targetNamespace [attribute], and its ļæ½actual
10998
* valueļæ½ is identical to the ļæ½actual valueļæ½ of the targetNamespace
10999
* [attribute] of SIIļæ½ (which must have such an [attribute])."
11001
if (pctxt->targetNamespace == NULL) {
11002
xmlSchemaCustomErr(ACTXT_CAST pctxt,
11003
XML_SCHEMAP_SRC_INCLUDE,
11005
"The target namespace of the included/redefined schema "
11006
"'%s' has to be absent, since the including/redefining "
11007
"schema has no target namespace",
11008
schemaLocation, NULL);
11010
} else if (!xmlStrEqual(bucket->origTargetNamespace,
11011
pctxt->targetNamespace)) {
11012
/* TODO: Change error function. */
11013
xmlSchemaPCustomErrExt(pctxt,
11014
XML_SCHEMAP_SRC_INCLUDE,
11016
"The target namespace '%s' of the included/redefined "
11017
"schema '%s' differs from '%s' of the "
11018
"including/redefining schema",
11019
bucket->origTargetNamespace, schemaLocation,
11020
pctxt->targetNamespace);
11023
} else if (pctxt->targetNamespace != NULL) {
11025
* Chameleons: the original target namespace will
11026
* differ from the resulting namespace.
11029
if (bucket->parsed &&
11030
(bucket->targetNamespace != pctxt->targetNamespace)) {
11032
* This is a sanity check, I dunno yet if this can happen.
11034
PERROR_INT("xmlSchemaParseIncludeOrRedefine",
11035
"trying to use an already parsed schema for a "
11036
"different targetNamespace");
11039
bucket->targetNamespace = pctxt->targetNamespace;
11043
* Parse the schema.
11045
if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
11047
/* TODO: Get rid of this flag on the schema itself. */
11048
if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
11049
schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11053
xmlSchemaParseNewDoc(pctxt, schema, bucket);
11054
/* Restore chameleon flag. */
11055
if (isChameleon && (!wasChameleon))
11056
schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11059
* And now for the children...
11061
child = node->children;
11062
if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11064
* Parse (simpleType | complexType | group | attributeGroup))*
11066
pctxt->redefined = bucket;
11068
* How to proceed if the redefined schema was not located?
11070
pctxt->isRedefine = 1;
11071
while (IS_SCHEMA(child, "annotation") ||
11072
IS_SCHEMA(child, "simpleType") ||
11073
IS_SCHEMA(child, "complexType") ||
11074
IS_SCHEMA(child, "group") ||
11075
IS_SCHEMA(child, "attributeGroup")) {
11076
if (IS_SCHEMA(child, "annotation")) {
11078
* TODO: discard or not?
11080
} else if (IS_SCHEMA(child, "simpleType")) {
11081
xmlSchemaParseSimpleType(pctxt, schema, child, 1);
11082
} else if (IS_SCHEMA(child, "complexType")) {
11083
xmlSchemaParseComplexType(pctxt, schema, child, 1);
11084
/* hasRedefinitions = 1; */
11085
} else if (IS_SCHEMA(child, "group")) {
11086
/* hasRedefinitions = 1; */
11087
xmlSchemaParseModelGroupDefinition(pctxt,
11089
} else if (IS_SCHEMA(child, "attributeGroup")) {
11090
/* hasRedefinitions = 1; */
11091
xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
11094
child = child->next;
11096
pctxt->redefined = NULL;
11097
pctxt->isRedefine = 0;
11099
if (IS_SCHEMA(child, "annotation")) {
11101
* TODO: discard or not?
11103
child = child->next;
11106
if (child != NULL) {
11107
res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
11108
if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11109
xmlSchemaPContentErr(pctxt, res,
11110
NULL, node, child, NULL,
11111
"(annotation | (simpleType | complexType | group | attributeGroup))*");
11113
xmlSchemaPContentErr(pctxt, res,
11114
NULL, node, child, NULL,
11121
return(pctxt->err);
11125
xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11129
#ifndef ENABLE_REDEFINE
11133
res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11134
XML_SCHEMA_SCHEMA_REDEFINE);
11141
xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11146
res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11147
XML_SCHEMA_SCHEMA_INCLUDE);
11154
* xmlSchemaParseModelGroup:
11155
* @ctxt: a schema validation context
11156
* @schema: the schema being built
11157
* @node: a subtree containing XML Schema informations
11158
* @type: the "compositor" type
11159
* @particleNeeded: if a a model group with a particle
11161
* parse a XML schema Sequence definition.
11162
* Applies parts of:
11163
* Schema Representation Constraint:
11164
* Redefinition Constraints and Semantics (src-redefine)
11165
* (6.1), (6.1.1), (6.1.2)
11167
* Schema Component Constraint:
11168
* All Group Limited (cos-all-limited) (2)
11169
* TODO: Actually this should go to component-level checks,
11170
* but is done here due to performance. Move it to an other layer
11171
* is schema construction via an API is implemented.
11173
* *WARNING* this interface is highly subject to change
11175
* Returns -1 in case of error, 0 if the declaration is improper and
11176
* 1 in case of success.
11178
static xmlSchemaTreeItemPtr
11179
xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11180
xmlNodePtr node, xmlSchemaTypeType type,
11183
xmlSchemaModelGroupPtr item;
11184
xmlSchemaParticlePtr particle = NULL;
11185
xmlNodePtr child = NULL;
11187
int min = 1, max = 1, isElemRef, hasRefs = 0;
11189
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11192
* Create a model group with the given compositor.
11194
item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
11198
if (withParticle) {
11199
if (type == XML_SCHEMA_TYPE_ALL) {
11200
min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
11201
max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
11203
/* choice + sequence */
11204
min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
11205
max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
11206
"(xs:nonNegativeInteger | unbounded)");
11208
xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
11210
* Create a particle
11212
particle = xmlSchemaAddParticle(ctxt, node, min, max);
11213
if (particle == NULL)
11215
particle->children = (xmlSchemaTreeItemPtr) item;
11217
* Check for illegal attributes.
11219
attr = node->properties;
11220
while (attr != NULL) {
11221
if (attr->ns == NULL) {
11222
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11223
(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
11224
(!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
11225
xmlSchemaPIllegalAttrErr(ctxt,
11226
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11228
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11229
xmlSchemaPIllegalAttrErr(ctxt,
11230
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11236
* Check for illegal attributes.
11238
attr = node->properties;
11239
while (attr != NULL) {
11240
if (attr->ns == NULL) {
11241
if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
11242
xmlSchemaPIllegalAttrErr(ctxt,
11243
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11245
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11246
xmlSchemaPIllegalAttrErr(ctxt,
11247
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11254
* Extract and validate attributes.
11256
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11258
* And now for the children...
11260
child = node->children;
11261
if (IS_SCHEMA(child, "annotation")) {
11262
item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11263
child = child->next;
11265
if (type == XML_SCHEMA_TYPE_ALL) {
11266
xmlSchemaParticlePtr part, last = NULL;
11268
while (IS_SCHEMA(child, "element")) {
11269
part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11270
schema, child, &isElemRef, 0);
11272
* SPEC cos-all-limited (2)
11273
* "The {max occurs} of all the particles in the {particles}
11274
* of the ('all') group must be 0 or 1.
11276
if (part != NULL) {
11279
if (part->minOccurs > 1) {
11280
xmlSchemaPCustomErr(ctxt,
11281
XML_SCHEMAP_COS_ALL_LIMITED,
11283
"Invalid value for minOccurs (must be 0 or 1)",
11286
part->minOccurs = 1;
11288
if (part->maxOccurs > 1) {
11289
xmlSchemaPCustomErr(ctxt,
11290
XML_SCHEMAP_COS_ALL_LIMITED,
11292
"Invalid value for maxOccurs (must be 0 or 1)",
11295
part->maxOccurs = 1;
11298
item->children = (xmlSchemaTreeItemPtr) part;
11300
last->next = (xmlSchemaTreeItemPtr) part;
11303
child = child->next;
11305
if (child != NULL) {
11306
xmlSchemaPContentErr(ctxt,
11307
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11308
NULL, node, child, NULL,
11309
"(annotation?, (annotation?, element*)");
11312
/* choice + sequence */
11313
xmlSchemaTreeItemPtr part = NULL, last = NULL;
11315
while ((IS_SCHEMA(child, "element")) ||
11316
(IS_SCHEMA(child, "group")) ||
11317
(IS_SCHEMA(child, "any")) ||
11318
(IS_SCHEMA(child, "choice")) ||
11319
(IS_SCHEMA(child, "sequence"))) {
11321
if (IS_SCHEMA(child, "element")) {
11322
part = (xmlSchemaTreeItemPtr)
11323
xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11324
if (part && isElemRef)
11326
} else if (IS_SCHEMA(child, "group")) {
11328
xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11332
* Handle redefinitions.
11334
if (ctxt->isRedefine && ctxt->redef &&
11335
(ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11336
part && part->children)
11338
if ((xmlSchemaGetQNameRefName(part->children) ==
11339
ctxt->redef->refName) &&
11340
(xmlSchemaGetQNameRefTargetNs(part->children) ==
11341
ctxt->redef->refTargetNs))
11344
* SPEC src-redefine:
11345
* (6.1) "If it has a <group> among its contents at
11346
* some level the ļæ½actual valueļæ½ of whose ref
11347
* [attribute] is the same as the ļæ½actual valueļæ½ of
11348
* its own name attribute plus target namespace, then
11349
* all of the following must be true:"
11350
* (6.1.1) "It must have exactly one such group."
11352
if (ctxt->redefCounter != 0) {
11353
xmlChar *str = NULL;
11355
xmlSchemaCustomErr(ACTXT_CAST ctxt,
11356
XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11357
"The redefining model group definition "
11358
"'%s' must not contain more than one "
11359
"reference to the redefined definition",
11360
xmlSchemaFormatQName(&str,
11361
ctxt->redef->refTargetNs,
11362
ctxt->redef->refName),
11366
} else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
11367
((WXS_PARTICLE(part))->maxOccurs != 1))
11369
xmlChar *str = NULL;
11371
* SPEC src-redefine:
11372
* (6.1.2) "The ļæ½actual valueļæ½ of both that
11373
* group's minOccurs and maxOccurs [attribute]
11374
* must be 1 (or ļæ½absentļæ½).
11376
xmlSchemaCustomErr(ACTXT_CAST ctxt,
11377
XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11378
"The redefining model group definition "
11379
"'%s' must not contain a reference to the "
11380
"redefined definition with a "
11381
"maxOccurs/minOccurs other than 1",
11382
xmlSchemaFormatQName(&str,
11383
ctxt->redef->refTargetNs,
11384
ctxt->redef->refName),
11389
ctxt->redef->reference = WXS_BASIC_CAST part;
11390
ctxt->redefCounter++;
11393
} else if (IS_SCHEMA(child, "any")) {
11394
part = (xmlSchemaTreeItemPtr)
11395
xmlSchemaParseAny(ctxt, schema, child);
11396
} else if (IS_SCHEMA(child, "choice")) {
11397
part = xmlSchemaParseModelGroup(ctxt, schema, child,
11398
XML_SCHEMA_TYPE_CHOICE, 1);
11399
} else if (IS_SCHEMA(child, "sequence")) {
11400
part = xmlSchemaParseModelGroup(ctxt, schema, child,
11401
XML_SCHEMA_TYPE_SEQUENCE, 1);
11403
if (part != NULL) {
11405
item->children = part;
11410
child = child->next;
11412
if (child != NULL) {
11413
xmlSchemaPContentErr(ctxt,
11414
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11415
NULL, node, child, NULL,
11416
"(annotation?, (element | group | choice | sequence | any)*)");
11419
if ((max == 0) && (min == 0))
11423
* We need to resolve references.
11425
WXS_ADD_PENDING(ctxt, item);
11428
return ((xmlSchemaTreeItemPtr) particle);
11430
return ((xmlSchemaTreeItemPtr) item);
11434
* xmlSchemaParseRestriction:
11435
* @ctxt: a schema validation context
11436
* @schema: the schema being built
11437
* @node: a subtree containing XML Schema informations
11439
* parse a XML schema Restriction definition
11440
* *WARNING* this interface is highly subject to change
11442
* Returns the type definition or NULL in case of error
11444
static xmlSchemaTypePtr
11445
xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11446
xmlNodePtr node, xmlSchemaTypeType parentType)
11448
xmlSchemaTypePtr type;
11449
xmlNodePtr child = NULL;
11452
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11454
/* Not a component, don't create it. */
11455
type = ctxt->ctxtType;
11456
type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
11459
* Check for illegal attributes.
11461
attr = node->properties;
11462
while (attr != NULL) {
11463
if (attr->ns == NULL) {
11464
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11465
(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11466
xmlSchemaPIllegalAttrErr(ctxt,
11467
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11469
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11470
xmlSchemaPIllegalAttrErr(ctxt,
11471
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11476
* Extract and validate attributes.
11478
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11483
* Extract the base type. The "base" attribute is mandatory if inside
11484
* a complex type or if redefining.
11486
* SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11487
* among its [children]), the simple type definition which is
11488
* the {content type} of the type definition ļæ½resolvedļæ½ to by
11489
* the ļæ½actual valueļæ½ of the base [attribute]"
11491
if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
11492
&(type->baseNs), &(type->base)) == 0)
11494
if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
11495
xmlSchemaPMissingAttrErr(ctxt,
11496
XML_SCHEMAP_S4S_ATTR_MISSING,
11497
NULL, node, "base", NULL);
11498
} else if ((ctxt->isRedefine) &&
11499
(type->flags & XML_SCHEMAS_TYPE_GLOBAL))
11501
if (type->base == NULL) {
11502
xmlSchemaPMissingAttrErr(ctxt,
11503
XML_SCHEMAP_S4S_ATTR_MISSING,
11504
NULL, node, "base", NULL);
11505
} else if ((! xmlStrEqual(type->base, type->name)) ||
11506
(! xmlStrEqual(type->baseNs, type->targetNamespace)))
11508
xmlChar *str1 = NULL, *str2 = NULL;
11510
* REDEFINE: SPEC src-redefine (5)
11511
* "Within the [children], each <simpleType> must have a
11512
* <restriction> among its [children] ... the ļæ½actual valueļæ½ of
11513
* whose base [attribute] must be the same as the ļæ½actual valueļæ½
11514
* of its own name attribute plus target namespace;"
11516
xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
11517
NULL, node, "This is a redefinition, but the QName "
11518
"value '%s' of the 'base' attribute does not match the "
11519
"type's designation '%s'",
11520
xmlSchemaFormatQName(&str1, type->baseNs, type->base),
11521
xmlSchemaFormatQName(&str2, type->targetNamespace,
11522
type->name), NULL);
11523
FREE_AND_NULL(str1);
11524
FREE_AND_NULL(str2);
11525
/* Avoid confusion and erase the values. */
11527
type->baseNs = NULL;
11532
* And now for the children...
11534
child = node->children;
11535
if (IS_SCHEMA(child, "annotation")) {
11537
* Add the annotation to the simple type ancestor.
11539
xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11540
xmlSchemaParseAnnotation(ctxt, child, 1));
11541
child = child->next;
11543
if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11545
* Corresponds to <simpleType><restriction><simpleType>.
11547
if (IS_SCHEMA(child, "simpleType")) {
11548
if (type->base != NULL) {
11550
* src-restriction-base-or-simpleType
11551
* Either the base [attribute] or the simpleType [child] of the
11552
* <restriction> element must be present, but not both.
11554
xmlSchemaPContentErr(ctxt,
11555
XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11557
"The attribute 'base' and the <simpleType> child are "
11558
"mutually exclusive", NULL);
11560
type->baseType = (xmlSchemaTypePtr)
11561
xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11563
child = child->next;
11564
} else if (type->base == NULL) {
11565
xmlSchemaPContentErr(ctxt,
11566
XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11568
"Either the attribute 'base' or a <simpleType> child "
11569
"must be present", NULL);
11571
} else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11573
* Corresponds to <complexType><complexContent><restriction>...
11576
* Model groups <all>, <choice> and <sequence>.
11578
if (IS_SCHEMA(child, "all")) {
11579
type->subtypes = (xmlSchemaTypePtr)
11580
xmlSchemaParseModelGroup(ctxt, schema, child,
11581
XML_SCHEMA_TYPE_ALL, 1);
11582
child = child->next;
11583
} else if (IS_SCHEMA(child, "choice")) {
11584
type->subtypes = (xmlSchemaTypePtr)
11585
xmlSchemaParseModelGroup(ctxt,
11586
schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
11587
child = child->next;
11588
} else if (IS_SCHEMA(child, "sequence")) {
11589
type->subtypes = (xmlSchemaTypePtr)
11590
xmlSchemaParseModelGroup(ctxt, schema, child,
11591
XML_SCHEMA_TYPE_SEQUENCE, 1);
11592
child = child->next;
11594
* Model group reference <group>.
11596
} else if (IS_SCHEMA(child, "group")) {
11597
type->subtypes = (xmlSchemaTypePtr)
11598
xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11600
* Note that the reference will be resolved in
11601
* xmlSchemaResolveTypeReferences();
11603
child = child->next;
11605
} else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11607
* Corresponds to <complexType><simpleContent><restriction>...
11609
* "1.1 the simple type definition corresponding to the <simpleType>
11610
* among the [children] of <restriction> if there is one;"
11612
if (IS_SCHEMA(child, "simpleType")) {
11614
* We will store the to-be-restricted simple type in
11615
* type->contentTypeDef *temporarily*.
11617
type->contentTypeDef = (xmlSchemaTypePtr)
11618
xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11619
if ( type->contentTypeDef == NULL)
11621
child = child->next;
11625
if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11626
(parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11627
xmlSchemaFacetPtr facet, lastfacet = NULL;
11629
* Corresponds to <complexType><simpleContent><restriction>...
11630
* <simpleType><restriction>...
11634
* Add the facets to the simple type ancestor.
11637
* TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11638
* Simple Type Definition Schema Representation Constraint:
11639
* *Single Facet Value*
11641
while ((IS_SCHEMA(child, "minInclusive")) ||
11642
(IS_SCHEMA(child, "minExclusive")) ||
11643
(IS_SCHEMA(child, "maxInclusive")) ||
11644
(IS_SCHEMA(child, "maxExclusive")) ||
11645
(IS_SCHEMA(child, "totalDigits")) ||
11646
(IS_SCHEMA(child, "fractionDigits")) ||
11647
(IS_SCHEMA(child, "pattern")) ||
11648
(IS_SCHEMA(child, "enumeration")) ||
11649
(IS_SCHEMA(child, "whiteSpace")) ||
11650
(IS_SCHEMA(child, "length")) ||
11651
(IS_SCHEMA(child, "maxLength")) ||
11652
(IS_SCHEMA(child, "minLength"))) {
11653
facet = xmlSchemaParseFacet(ctxt, schema, child);
11654
if (facet != NULL) {
11655
if (lastfacet == NULL)
11656
type->facets = facet;
11658
lastfacet->next = facet;
11660
lastfacet->next = NULL;
11662
child = child->next;
11665
* Create links for derivation and validation.
11667
if (type->facets != NULL) {
11668
xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
11670
facet = type->facets;
11672
facetLink = (xmlSchemaFacetLinkPtr)
11673
xmlMalloc(sizeof(xmlSchemaFacetLink));
11674
if (facetLink == NULL) {
11675
xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
11676
xmlFree(facetLink);
11679
facetLink->facet = facet;
11680
facetLink->next = NULL;
11681
if (lastFacetLink == NULL)
11682
type->facetSet = facetLink;
11684
lastFacetLink->next = facetLink;
11685
lastFacetLink = facetLink;
11686
facet = facet->next;
11687
} while (facet != NULL);
11690
if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11692
* Attribute uses/declarations.
11694
if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11695
(xmlSchemaItemListPtr *) &(type->attrUses),
11696
XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
11699
* Attribute wildcard.
11701
if (IS_SCHEMA(child, "anyAttribute")) {
11702
type->attributeWildcard =
11703
xmlSchemaParseAnyAttribute(ctxt, schema, child);
11704
child = child->next;
11707
if (child != NULL) {
11708
if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11709
xmlSchemaPContentErr(ctxt,
11710
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11711
NULL, node, child, NULL,
11712
"annotation?, (group | all | choice | sequence)?, "
11713
"((attribute | attributeGroup)*, anyAttribute?))");
11714
} else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11715
xmlSchemaPContentErr(ctxt,
11716
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11717
NULL, node, child, NULL,
11718
"(annotation?, (simpleType?, (minExclusive | minInclusive | "
11719
"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11720
"length | minLength | maxLength | enumeration | whiteSpace | "
11721
"pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11724
xmlSchemaPContentErr(ctxt,
11725
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11726
NULL, node, child, NULL,
11727
"(annotation?, (simpleType?, (minExclusive | minInclusive | "
11728
"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11729
"length | minLength | maxLength | enumeration | whiteSpace | "
11737
* xmlSchemaParseExtension:
11738
* @ctxt: a schema validation context
11739
* @schema: the schema being built
11740
* @node: a subtree containing XML Schema informations
11742
* Parses an <extension>, which is found inside a
11743
* <simpleContent> or <complexContent>.
11744
* *WARNING* this interface is highly subject to change.
11746
* TODO: Returns the type definition or NULL in case of error
11748
static xmlSchemaTypePtr
11749
xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11750
xmlNodePtr node, xmlSchemaTypeType parentType)
11752
xmlSchemaTypePtr type;
11753
xmlNodePtr child = NULL;
11756
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11758
/* Not a component, don't create it. */
11759
type = ctxt->ctxtType;
11760
type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
11763
* Check for illegal attributes.
11765
attr = node->properties;
11766
while (attr != NULL) {
11767
if (attr->ns == NULL) {
11768
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11769
(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11770
xmlSchemaPIllegalAttrErr(ctxt,
11771
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11773
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11774
xmlSchemaPIllegalAttrErr(ctxt,
11775
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11780
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11783
* Attribute "base" - mandatory.
11785
if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
11786
"base", &(type->baseNs), &(type->base)) == 0) &&
11787
(type->base == NULL)) {
11788
xmlSchemaPMissingAttrErr(ctxt,
11789
XML_SCHEMAP_S4S_ATTR_MISSING,
11790
NULL, node, "base", NULL);
11793
* And now for the children...
11795
child = node->children;
11796
if (IS_SCHEMA(child, "annotation")) {
11798
* Add the annotation to the type ancestor.
11800
xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11801
xmlSchemaParseAnnotation(ctxt, child, 1));
11802
child = child->next;
11804
if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11806
* Corresponds to <complexType><complexContent><extension>... and:
11808
* Model groups <all>, <choice>, <sequence> and <group>.
11810
if (IS_SCHEMA(child, "all")) {
11811
type->subtypes = (xmlSchemaTypePtr)
11812
xmlSchemaParseModelGroup(ctxt, schema,
11813
child, XML_SCHEMA_TYPE_ALL, 1);
11814
child = child->next;
11815
} else if (IS_SCHEMA(child, "choice")) {
11816
type->subtypes = (xmlSchemaTypePtr)
11817
xmlSchemaParseModelGroup(ctxt, schema,
11818
child, XML_SCHEMA_TYPE_CHOICE, 1);
11819
child = child->next;
11820
} else if (IS_SCHEMA(child, "sequence")) {
11821
type->subtypes = (xmlSchemaTypePtr)
11822
xmlSchemaParseModelGroup(ctxt, schema,
11823
child, XML_SCHEMA_TYPE_SEQUENCE, 1);
11824
child = child->next;
11825
} else if (IS_SCHEMA(child, "group")) {
11826
type->subtypes = (xmlSchemaTypePtr)
11827
xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11829
* Note that the reference will be resolved in
11830
* xmlSchemaResolveTypeReferences();
11832
child = child->next;
11835
if (child != NULL) {
11837
* Attribute uses/declarations.
11839
if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11840
(xmlSchemaItemListPtr *) &(type->attrUses),
11841
XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
11844
* Attribute wildcard.
11846
if (IS_SCHEMA(child, "anyAttribute")) {
11847
ctxt->ctxtType->attributeWildcard =
11848
xmlSchemaParseAnyAttribute(ctxt, schema, child);
11849
child = child->next;
11852
if (child != NULL) {
11853
if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11854
/* Complex content extension. */
11855
xmlSchemaPContentErr(ctxt,
11856
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11857
NULL, node, child, NULL,
11858
"(annotation?, ((group | all | choice | sequence)?, "
11859
"((attribute | attributeGroup)*, anyAttribute?)))");
11861
/* Simple content extension. */
11862
xmlSchemaPContentErr(ctxt,
11863
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11864
NULL, node, child, NULL,
11865
"(annotation?, ((attribute | attributeGroup)*, "
11866
"anyAttribute?))");
11873
* xmlSchemaParseSimpleContent:
11874
* @ctxt: a schema validation context
11875
* @schema: the schema being built
11876
* @node: a subtree containing XML Schema informations
11878
* parse a XML schema SimpleContent definition
11879
* *WARNING* this interface is highly subject to change
11881
* Returns the type definition or NULL in case of error
11884
xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
11885
xmlSchemaPtr schema, xmlNodePtr node,
11886
int *hasRestrictionOrExtension)
11888
xmlSchemaTypePtr type;
11889
xmlNodePtr child = NULL;
11892
if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11893
(hasRestrictionOrExtension == NULL))
11895
*hasRestrictionOrExtension = 0;
11896
/* Not a component, don't create it. */
11897
type = ctxt->ctxtType;
11898
type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
11900
* Check for illegal attributes.
11902
attr = node->properties;
11903
while (attr != NULL) {
11904
if (attr->ns == NULL) {
11905
if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
11906
xmlSchemaPIllegalAttrErr(ctxt,
11907
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11909
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11910
xmlSchemaPIllegalAttrErr(ctxt,
11911
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11916
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11919
* And now for the children...
11921
child = node->children;
11922
if (IS_SCHEMA(child, "annotation")) {
11924
* Add the annotation to the complex type ancestor.
11926
xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11927
xmlSchemaParseAnnotation(ctxt, child, 1));
11928
child = child->next;
11930
if (child == NULL) {
11931
xmlSchemaPContentErr(ctxt,
11932
XML_SCHEMAP_S4S_ELEM_MISSING,
11933
NULL, node, NULL, NULL,
11934
"(annotation?, (restriction | extension))");
11936
if (child == NULL) {
11937
xmlSchemaPContentErr(ctxt,
11938
XML_SCHEMAP_S4S_ELEM_MISSING,
11939
NULL, node, NULL, NULL,
11940
"(annotation?, (restriction | extension))");
11942
if (IS_SCHEMA(child, "restriction")) {
11943
xmlSchemaParseRestriction(ctxt, schema, child,
11944
XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11945
(*hasRestrictionOrExtension) = 1;
11946
child = child->next;
11947
} else if (IS_SCHEMA(child, "extension")) {
11948
xmlSchemaParseExtension(ctxt, schema, child,
11949
XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11950
(*hasRestrictionOrExtension) = 1;
11951
child = child->next;
11953
if (child != NULL) {
11954
xmlSchemaPContentErr(ctxt,
11955
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11956
NULL, node, child, NULL,
11957
"(annotation?, (restriction | extension))");
11963
* xmlSchemaParseComplexContent:
11964
* @ctxt: a schema validation context
11965
* @schema: the schema being built
11966
* @node: a subtree containing XML Schema informations
11968
* parse a XML schema ComplexContent definition
11969
* *WARNING* this interface is highly subject to change
11971
* Returns the type definition or NULL in case of error
11974
xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
11975
xmlSchemaPtr schema, xmlNodePtr node,
11976
int *hasRestrictionOrExtension)
11978
xmlSchemaTypePtr type;
11979
xmlNodePtr child = NULL;
11982
if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11983
(hasRestrictionOrExtension == NULL))
11985
*hasRestrictionOrExtension = 0;
11986
/* Not a component, don't create it. */
11987
type = ctxt->ctxtType;
11989
* Check for illegal attributes.
11991
attr = node->properties;
11992
while (attr != NULL) {
11993
if (attr->ns == NULL) {
11994
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11995
(!xmlStrEqual(attr->name, BAD_CAST "mixed")))
11997
xmlSchemaPIllegalAttrErr(ctxt,
11998
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12000
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12001
xmlSchemaPIllegalAttrErr(ctxt,
12002
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12007
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12010
* Set the 'mixed' on the complex type ancestor.
12012
if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) {
12013
if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
12014
type->flags |= XML_SCHEMAS_TYPE_MIXED;
12016
child = node->children;
12017
if (IS_SCHEMA(child, "annotation")) {
12019
* Add the annotation to the complex type ancestor.
12021
xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12022
xmlSchemaParseAnnotation(ctxt, child, 1));
12023
child = child->next;
12025
if (child == NULL) {
12026
xmlSchemaPContentErr(ctxt,
12027
XML_SCHEMAP_S4S_ELEM_MISSING,
12029
NULL, "(annotation?, (restriction | extension))");
12031
if (child == NULL) {
12032
xmlSchemaPContentErr(ctxt,
12033
XML_SCHEMAP_S4S_ELEM_MISSING,
12035
NULL, "(annotation?, (restriction | extension))");
12037
if (IS_SCHEMA(child, "restriction")) {
12038
xmlSchemaParseRestriction(ctxt, schema, child,
12039
XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12040
(*hasRestrictionOrExtension) = 1;
12041
child = child->next;
12042
} else if (IS_SCHEMA(child, "extension")) {
12043
xmlSchemaParseExtension(ctxt, schema, child,
12044
XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12045
(*hasRestrictionOrExtension) = 1;
12046
child = child->next;
12048
if (child != NULL) {
12049
xmlSchemaPContentErr(ctxt,
12050
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12052
NULL, "(annotation?, (restriction | extension))");
12058
* xmlSchemaParseComplexType:
12059
* @ctxt: a schema validation context
12060
* @schema: the schema being built
12061
* @node: a subtree containing XML Schema informations
12063
* parse a XML schema Complex Type definition
12064
* *WARNING* this interface is highly subject to change
12066
* Returns the type definition or NULL in case of error
12068
static xmlSchemaTypePtr
12069
xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
12070
xmlNodePtr node, int topLevel)
12072
xmlSchemaTypePtr type, ctxtType;
12073
xmlNodePtr child = NULL;
12074
const xmlChar *name = NULL;
12076
const xmlChar *attrValue;
12077
#ifdef ENABLE_NAMED_LOCALS
12080
int final = 0, block = 0, hasRestrictionOrExtension = 0;
12083
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
12086
ctxtType = ctxt->ctxtType;
12089
attr = xmlSchemaGetPropNode(node, "name");
12090
if (attr == NULL) {
12091
xmlSchemaPMissingAttrErr(ctxt,
12092
XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
12094
} else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
12095
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
12100
if (topLevel == 0) {
12102
* Parse as local complex type definition.
12104
#ifdef ENABLE_NAMED_LOCALS
12105
snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
12106
type = xmlSchemaAddType(ctxt, schema,
12107
XML_SCHEMA_TYPE_COMPLEX,
12108
xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
12109
ctxt->targetNamespace, node, 0);
12111
type = xmlSchemaAddType(ctxt, schema,
12112
XML_SCHEMA_TYPE_COMPLEX,
12113
NULL, ctxt->targetNamespace, node, 0);
12119
type->type = XML_SCHEMA_TYPE_COMPLEX;
12121
* TODO: We need the target namespace.
12125
* Parse as global complex type definition.
12127
type = xmlSchemaAddType(ctxt, schema,
12128
XML_SCHEMA_TYPE_COMPLEX,
12129
name, ctxt->targetNamespace, node, 1);
12133
type->type = XML_SCHEMA_TYPE_COMPLEX;
12134
type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
12136
type->targetNamespace = ctxt->targetNamespace;
12138
* Handle attributes.
12140
attr = node->properties;
12141
while (attr != NULL) {
12142
if (attr->ns == NULL) {
12143
if (xmlStrEqual(attr->name, BAD_CAST "id")) {
12147
xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12148
} else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
12150
* Attribute "mixed".
12152
if (xmlSchemaPGetBoolNodeValue(ctxt,
12153
NULL, (xmlNodePtr) attr))
12154
type->flags |= XML_SCHEMAS_TYPE_MIXED;
12155
} else if (topLevel) {
12157
* Attributes of global complex type definitions.
12159
if (xmlStrEqual(attr->name, BAD_CAST "name")) {
12161
} else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
12163
* Attribute "abstract".
12165
if (xmlSchemaPGetBoolNodeValue(ctxt,
12166
NULL, (xmlNodePtr) attr))
12167
type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
12168
} else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
12170
* Attribute "final".
12172
attrValue = xmlSchemaGetNodeContent(ctxt,
12173
(xmlNodePtr) attr);
12174
if (xmlSchemaPValAttrBlockFinal(attrValue,
12177
XML_SCHEMAS_TYPE_FINAL_EXTENSION,
12178
XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
12181
xmlSchemaPSimpleTypeErr(ctxt,
12182
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12183
NULL, (xmlNodePtr) attr, NULL,
12184
"(#all | List of (extension | restriction))",
12185
attrValue, NULL, NULL, NULL);
12188
} else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
12190
* Attribute "block".
12192
attrValue = xmlSchemaGetNodeContent(ctxt,
12193
(xmlNodePtr) attr);
12194
if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
12196
XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
12197
XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
12198
-1, -1, -1) != 0) {
12199
xmlSchemaPSimpleTypeErr(ctxt,
12200
XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12201
NULL, (xmlNodePtr) attr, NULL,
12202
"(#all | List of (extension | restriction)) ",
12203
attrValue, NULL, NULL, NULL);
12207
xmlSchemaPIllegalAttrErr(ctxt,
12208
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12211
xmlSchemaPIllegalAttrErr(ctxt,
12212
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12214
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12215
xmlSchemaPIllegalAttrErr(ctxt,
12216
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12222
* Apply default "block" values.
12224
if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
12225
type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
12226
if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
12227
type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
12231
* Apply default "block" values.
12233
if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
12234
type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
12235
if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
12236
type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
12239
* And now for the children...
12241
child = node->children;
12242
if (IS_SCHEMA(child, "annotation")) {
12243
type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12244
child = child->next;
12246
ctxt->ctxtType = type;
12247
if (IS_SCHEMA(child, "simpleContent")) {
12249
* <complexType><simpleContent>...
12251
* Specifying mixed='true' when the <simpleContent>
12252
* alternative is chosen has no effect
12254
if (type->flags & XML_SCHEMAS_TYPE_MIXED)
12255
type->flags ^= XML_SCHEMAS_TYPE_MIXED;
12256
xmlSchemaParseSimpleContent(ctxt, schema, child,
12257
&hasRestrictionOrExtension);
12258
child = child->next;
12259
} else if (IS_SCHEMA(child, "complexContent")) {
12261
* <complexType><complexContent>...
12263
type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12264
xmlSchemaParseComplexContent(ctxt, schema, child,
12265
&hasRestrictionOrExtension);
12266
child = child->next;
12269
* E.g <complexType><sequence>... or <complexType><attribute>... etc.
12272
* "...the third alternative (neither <simpleContent> nor
12273
* <complexContent>) is chosen. This case is understood as shorthand
12274
* for complex content restricting the ļæ½ur-type definitionļæ½, and the
12275
* details of the mappings should be modified as necessary.
12277
type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12278
type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
12280
* Parse model groups.
12282
if (IS_SCHEMA(child, "all")) {
12283
type->subtypes = (xmlSchemaTypePtr)
12284
xmlSchemaParseModelGroup(ctxt, schema, child,
12285
XML_SCHEMA_TYPE_ALL, 1);
12286
child = child->next;
12287
} else if (IS_SCHEMA(child, "choice")) {
12288
type->subtypes = (xmlSchemaTypePtr)
12289
xmlSchemaParseModelGroup(ctxt, schema, child,
12290
XML_SCHEMA_TYPE_CHOICE, 1);
12291
child = child->next;
12292
} else if (IS_SCHEMA(child, "sequence")) {
12293
type->subtypes = (xmlSchemaTypePtr)
12294
xmlSchemaParseModelGroup(ctxt, schema, child,
12295
XML_SCHEMA_TYPE_SEQUENCE, 1);
12296
child = child->next;
12297
} else if (IS_SCHEMA(child, "group")) {
12298
type->subtypes = (xmlSchemaTypePtr)
12299
xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
12301
* Note that the reference will be resolved in
12302
* xmlSchemaResolveTypeReferences();
12304
child = child->next;
12307
* Parse attribute decls/refs.
12309
if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12310
(xmlSchemaItemListPtr *) &(type->attrUses),
12311
XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
12314
* Parse attribute wildcard.
12316
if (IS_SCHEMA(child, "anyAttribute")) {
12317
type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12318
child = child->next;
12321
if (child != NULL) {
12322
xmlSchemaPContentErr(ctxt,
12323
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12325
NULL, "(annotation?, (simpleContent | complexContent | "
12326
"((group | all | choice | sequence)?, ((attribute | "
12327
"attributeGroup)*, anyAttribute?))))");
12330
* REDEFINE: SPEC src-redefine (5)
12332
if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
12333
xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
12334
NULL, node, "This is a redefinition, thus the "
12335
"<complexType> must have a <restriction> or <extension> "
12336
"grand-child", NULL);
12338
ctxt->ctxtType = ctxtType;
12342
/************************************************************************
12344
* Validating using Schemas *
12346
************************************************************************/
12348
/************************************************************************
12350
* Reading/Writing Schemas *
12352
************************************************************************/
12354
#if 0 /* Will be enabled if it is clear what options are needed. */
12356
* xmlSchemaParserCtxtSetOptions:
12357
* @ctxt: a schema parser context
12358
* @options: a combination of xmlSchemaParserOption
12360
* Sets the options to be used during the parse.
12362
* Returns 0 in case of success, -1 in case of an
12366
xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12375
* WARNING: Change the start value if adding to the
12376
* xmlSchemaParseOption.
12378
for (i = 1; i < (int) sizeof(int) * 8; i++) {
12379
if (options & 1<<i) {
12383
ctxt->options = options;
12388
* xmlSchemaValidCtxtGetOptions:
12389
* @ctxt: a schema parser context
12391
* Returns the option combination of the parser context.
12394
xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12400
return (ctxt->options);
12405
* xmlSchemaNewParserCtxt:
12406
* @URL: the location of the schema
12408
* Create an XML Schemas parse context for that file/resource expected
12409
* to contain an XML Schemas file.
12411
* Returns the parser context or NULL in case of error
12413
xmlSchemaParserCtxtPtr
12414
xmlSchemaNewParserCtxt(const char *URL)
12416
xmlSchemaParserCtxtPtr ret;
12421
ret = xmlSchemaParserCtxtCreate();
12424
ret->dict = xmlDictCreate();
12425
ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12430
* xmlSchemaNewMemParserCtxt:
12431
* @buffer: a pointer to a char array containing the schemas
12432
* @size: the size of the array
12434
* Create an XML Schemas parse context for that memory buffer expected
12435
* to contain an XML Schemas file.
12437
* Returns the parser context or NULL in case of error
12439
xmlSchemaParserCtxtPtr
12440
xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12442
xmlSchemaParserCtxtPtr ret;
12444
if ((buffer == NULL) || (size <= 0))
12446
ret = xmlSchemaParserCtxtCreate();
12449
ret->buffer = buffer;
12451
ret->dict = xmlDictCreate();
12456
* xmlSchemaNewDocParserCtxt:
12457
* @doc: a preparsed document tree
12459
* Create an XML Schemas parse context for that document.
12460
* NB. The document may be modified during the parsing process.
12462
* Returns the parser context or NULL in case of error
12464
xmlSchemaParserCtxtPtr
12465
xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
12467
xmlSchemaParserCtxtPtr ret;
12471
ret = xmlSchemaParserCtxtCreate();
12475
ret->dict = xmlDictCreate();
12476
/* The application has responsibility for the document */
12483
* xmlSchemaFreeParserCtxt:
12484
* @ctxt: the schema parser context
12486
* Free the resources associated to the schema parser context
12489
xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
12493
if (ctxt->doc != NULL && !ctxt->preserve)
12494
xmlFreeDoc(ctxt->doc);
12495
if (ctxt->vctxt != NULL) {
12496
xmlSchemaFreeValidCtxt(ctxt->vctxt);
12498
if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
12499
xmlSchemaConstructionCtxtFree(ctxt->constructor);
12500
ctxt->constructor = NULL;
12501
ctxt->ownsConstructor = 0;
12503
if (ctxt->attrProhibs != NULL)
12504
xmlSchemaItemListFree(ctxt->attrProhibs);
12505
xmlDictFree(ctxt->dict);
12509
/************************************************************************
12511
* Building the content models *
12513
************************************************************************/
12516
xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12517
xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12519
xmlAutomataStatePtr start, tmp;
12520
xmlSchemaElementPtr elemDecl, member;
12521
xmlSchemaSubstGroupPtr substGroup;
12524
elemDecl = (xmlSchemaElementPtr) particle->children;
12526
* Wrap the substitution group with a CHOICE.
12528
start = pctxt->state;
12530
end = xmlAutomataNewState(pctxt->am);
12531
substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
12532
if (substGroup == NULL) {
12533
xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
12534
XML_SCHEMAP_INTERNAL,
12535
"Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12536
"declaration is marked having a subst. group but none "
12537
"available.\n", elemDecl->name, NULL);
12540
if (counter >= 0) {
12542
* NOTE that we put the declaration in, even if it's abstract.
12543
* However, an error will be raised during *validation* if an element
12544
* information item shall be validated against an abstract element
12547
tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
12548
xmlAutomataNewTransition2(pctxt->am, tmp, end,
12549
elemDecl->name, elemDecl->targetNamespace, elemDecl);
12551
* Add subst. group members.
12553
for (i = 0; i < substGroup->members->nbItems; i++) {
12554
member = (xmlSchemaElementPtr) substGroup->members->items[i];
12555
xmlAutomataNewTransition2(pctxt->am, tmp, end,
12556
member->name, member->targetNamespace, member);
12558
} else if (particle->maxOccurs == 1) {
12560
* NOTE that we put the declaration in, even if it's abstract,
12562
xmlAutomataNewEpsilon(pctxt->am,
12563
xmlAutomataNewTransition2(pctxt->am,
12565
elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12567
* Add subst. group members.
12569
for (i = 0; i < substGroup->members->nbItems; i++) {
12570
member = (xmlSchemaElementPtr) substGroup->members->items[i];
12572
* NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12573
* was incorrectly used instead of xmlAutomataNewTransition2()
12574
* (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12575
* section in xmlSchemaBuildAContentModel() ).
12576
* TODO: Check if xmlAutomataNewOnceTrans2() was instead
12577
* intended for the above "counter" section originally. I.e.,
12578
* check xs:all with subst-groups.
12580
* tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12581
* member->name, member->targetNamespace,
12584
tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
12585
member->name, member->targetNamespace, member);
12586
xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12589
xmlAutomataStatePtr hop;
12590
int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12591
UNBOUNDED : particle->maxOccurs - 1;
12592
int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12595
xmlAutomataNewCounter(pctxt->am, minOccurs,
12597
hop = xmlAutomataNewState(pctxt->am);
12599
xmlAutomataNewEpsilon(pctxt->am,
12600
xmlAutomataNewTransition2(pctxt->am,
12602
elemDecl->name, elemDecl->targetNamespace, elemDecl),
12605
* Add subst. group members.
12607
for (i = 0; i < substGroup->members->nbItems; i++) {
12608
member = (xmlSchemaElementPtr) substGroup->members->items[i];
12609
xmlAutomataNewEpsilon(pctxt->am,
12610
xmlAutomataNewTransition2(pctxt->am,
12612
member->name, member->targetNamespace, member),
12615
xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12616
xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12618
if (particle->minOccurs == 0)
12619
xmlAutomataNewEpsilon(pctxt->am, start, end);
12620
pctxt->state = end;
12624
xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12625
xmlSchemaParticlePtr particle)
12627
if (((xmlSchemaElementPtr) particle->children)->flags &
12628
XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12630
* Substitution groups.
12632
xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
12634
xmlSchemaElementPtr elemDecl;
12635
xmlAutomataStatePtr start;
12637
elemDecl = (xmlSchemaElementPtr) particle->children;
12639
if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
12641
if (particle->maxOccurs == 1) {
12642
start = ctxt->state;
12643
ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12644
elemDecl->name, elemDecl->targetNamespace, elemDecl);
12645
} else if ((particle->maxOccurs >= UNBOUNDED) &&
12646
(particle->minOccurs < 2)) {
12647
/* Special case. */
12648
start = ctxt->state;
12649
ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12650
elemDecl->name, elemDecl->targetNamespace, elemDecl);
12651
ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
12652
elemDecl->name, elemDecl->targetNamespace, elemDecl);
12655
int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12656
UNBOUNDED : particle->maxOccurs - 1;
12657
int minOccurs = particle->minOccurs < 1 ?
12658
0 : particle->minOccurs - 1;
12660
start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
12661
counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
12662
ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12663
elemDecl->name, elemDecl->targetNamespace, elemDecl);
12664
xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
12665
ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
12668
if (particle->minOccurs == 0)
12669
xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
12674
* xmlSchemaBuildAContentModel:
12675
* @ctxt: the schema parser context
12676
* @particle: the particle component
12677
* @name: the complex type's name whose content is being built
12679
* Create the automaton for the {content type} of a complex type.
12683
xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12684
xmlSchemaParticlePtr particle)
12686
if (particle == NULL) {
12687
PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12690
if (particle->children == NULL) {
12692
* Just return in this case. A missing "term" of the particle
12693
* might arise due to an invalid "term" component.
12698
switch (particle->children->type) {
12699
case XML_SCHEMA_TYPE_ANY: {
12700
xmlAutomataStatePtr start, end;
12701
xmlSchemaWildcardPtr wild;
12702
xmlSchemaWildcardNsPtr ns;
12704
wild = (xmlSchemaWildcardPtr) particle->children;
12706
start = pctxt->state;
12707
end = xmlAutomataNewState(pctxt->am);
12709
if (particle->maxOccurs == 1) {
12710
if (wild->any == 1) {
12712
* We need to add both transitions:
12714
* 1. the {"*", "*"} for elements in a namespace.
12717
xmlAutomataNewTransition2(pctxt->am,
12718
start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12719
xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12721
* 2. the {"*"} for elements in no namespace.
12724
xmlAutomataNewTransition2(pctxt->am,
12725
start, NULL, BAD_CAST "*", NULL, wild);
12726
xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12728
} else if (wild->nsSet != NULL) {
12731
pctxt->state = start;
12732
pctxt->state = xmlAutomataNewTransition2(pctxt->am,
12733
pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
12734
xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12736
} while (ns != NULL);
12738
} else if (wild->negNsSet != NULL) {
12739
pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12740
start, end, BAD_CAST "*", wild->negNsSet->value,
12745
xmlAutomataStatePtr hop;
12747
particle->maxOccurs == UNBOUNDED ? UNBOUNDED : particle->maxOccurs - 1;
12749
particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12751
counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12752
hop = xmlAutomataNewState(pctxt->am);
12753
if (wild->any == 1) {
12755
xmlAutomataNewTransition2(pctxt->am,
12756
start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12757
xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12759
xmlAutomataNewTransition2(pctxt->am,
12760
start, NULL, BAD_CAST "*", NULL, wild);
12761
xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12762
} else if (wild->nsSet != NULL) {
12766
xmlAutomataNewTransition2(pctxt->am,
12767
start, NULL, BAD_CAST "*", ns->value, wild);
12768
xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12770
} while (ns != NULL);
12772
} else if (wild->negNsSet != NULL) {
12773
pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12774
start, hop, BAD_CAST "*", wild->negNsSet->value,
12777
xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12778
xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12780
if (particle->minOccurs == 0) {
12781
xmlAutomataNewEpsilon(pctxt->am, start, end);
12783
pctxt->state = end;
12786
case XML_SCHEMA_TYPE_ELEMENT:
12787
xmlSchemaBuildContentModelForElement(pctxt, particle);
12789
case XML_SCHEMA_TYPE_SEQUENCE:{
12790
xmlSchemaTreeItemPtr sub;
12793
* If max and min occurances are default (1) then
12794
* simply iterate over the particles of the <sequence>.
12796
if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12797
sub = particle->children->children;
12798
while (sub != NULL) {
12799
xmlSchemaBuildAContentModel(pctxt,
12800
(xmlSchemaParticlePtr) sub);
12804
xmlAutomataStatePtr oldstate = pctxt->state;
12806
if (particle->maxOccurs >= UNBOUNDED) {
12807
if (particle->minOccurs > 1) {
12808
xmlAutomataStatePtr tmp;
12811
pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12813
oldstate = pctxt->state;
12815
counter = xmlAutomataNewCounter(pctxt->am,
12816
particle->minOccurs - 1, UNBOUNDED);
12818
sub = particle->children->children;
12819
while (sub != NULL) {
12820
xmlSchemaBuildAContentModel(pctxt,
12821
(xmlSchemaParticlePtr) sub);
12824
tmp = pctxt->state;
12825
xmlAutomataNewCountedTrans(pctxt->am, tmp,
12826
oldstate, counter);
12828
xmlAutomataNewCounterTrans(pctxt->am, tmp,
12832
pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12834
oldstate = pctxt->state;
12836
sub = particle->children->children;
12837
while (sub != NULL) {
12838
xmlSchemaBuildAContentModel(pctxt,
12839
(xmlSchemaParticlePtr) sub);
12842
xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
12845
* epsilon needed to block previous trans from
12846
* being allowed to enter back from another
12849
pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12850
pctxt->state, NULL);
12851
if (particle->minOccurs == 0) {
12852
xmlAutomataNewEpsilon(pctxt->am,
12853
oldstate, pctxt->state);
12856
} else if ((particle->maxOccurs > 1)
12857
|| (particle->minOccurs > 1)) {
12858
xmlAutomataStatePtr tmp;
12861
pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12863
oldstate = pctxt->state;
12865
counter = xmlAutomataNewCounter(pctxt->am,
12866
particle->minOccurs - 1,
12867
particle->maxOccurs - 1);
12869
sub = particle->children->children;
12870
while (sub != NULL) {
12871
xmlSchemaBuildAContentModel(pctxt,
12872
(xmlSchemaParticlePtr) sub);
12875
tmp = pctxt->state;
12876
xmlAutomataNewCountedTrans(pctxt->am,
12877
tmp, oldstate, counter);
12879
xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
12881
if (particle->minOccurs == 0) {
12882
xmlAutomataNewEpsilon(pctxt->am,
12883
oldstate, pctxt->state);
12886
sub = particle->children->children;
12887
while (sub != NULL) {
12888
xmlSchemaBuildAContentModel(pctxt,
12889
(xmlSchemaParticlePtr) sub);
12892
if (particle->minOccurs == 0) {
12893
xmlAutomataNewEpsilon(pctxt->am, oldstate,
12900
case XML_SCHEMA_TYPE_CHOICE:{
12901
xmlSchemaTreeItemPtr sub;
12902
xmlAutomataStatePtr start, end;
12904
start = pctxt->state;
12905
end = xmlAutomataNewState(pctxt->am);
12908
* iterate over the subtypes and remerge the end with an
12909
* epsilon transition
12911
if (particle->maxOccurs == 1) {
12912
sub = particle->children->children;
12913
while (sub != NULL) {
12914
pctxt->state = start;
12915
xmlSchemaBuildAContentModel(pctxt,
12916
(xmlSchemaParticlePtr) sub);
12917
xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12922
xmlAutomataStatePtr hop, base;
12923
int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12924
UNBOUNDED : particle->maxOccurs - 1;
12926
particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12929
* use a counter to keep track of the number of transtions
12930
* which went through the choice.
12933
xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12934
hop = xmlAutomataNewState(pctxt->am);
12935
base = xmlAutomataNewState(pctxt->am);
12937
sub = particle->children->children;
12938
while (sub != NULL) {
12939
pctxt->state = base;
12940
xmlSchemaBuildAContentModel(pctxt,
12941
(xmlSchemaParticlePtr) sub);
12942
xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12945
xmlAutomataNewEpsilon(pctxt->am, start, base);
12946
xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
12947
xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12949
if (particle->minOccurs == 0) {
12950
xmlAutomataNewEpsilon(pctxt->am, start, end);
12952
pctxt->state = end;
12955
case XML_SCHEMA_TYPE_ALL:{
12956
xmlAutomataStatePtr start;
12957
xmlSchemaParticlePtr sub;
12958
xmlSchemaElementPtr elemDecl;
12961
sub = (xmlSchemaParticlePtr) particle->children->children;
12964
start = pctxt->state;
12965
while (sub != NULL) {
12966
pctxt->state = start;
12968
elemDecl = (xmlSchemaElementPtr) sub->children;
12969
if (elemDecl == NULL) {
12970
PERROR_INT("xmlSchemaBuildAContentModel",
12971
"<element> particle has no term");
12975
* NOTE: The {max occurs} of all the particles in the
12976
* {particles} of the group must be 0 or 1; this is
12977
* already ensured during the parse of the content of
12980
if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12984
* This is an abstract group, we need to share
12985
* the same counter for all the element transitions
12986
* derived from the group
12988
counter = xmlAutomataNewCounter(pctxt->am,
12989
sub->minOccurs, sub->maxOccurs);
12990
xmlSchemaBuildContentModelForSubstGroup(pctxt,
12991
sub, counter, pctxt->state);
12993
if ((sub->minOccurs == 1) &&
12994
(sub->maxOccurs == 1)) {
12995
xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
12998
elemDecl->targetNamespace,
13000
} else if ((sub->minOccurs == 0) &&
13001
(sub->maxOccurs == 1)) {
13003
xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
13006
elemDecl->targetNamespace,
13012
sub = (xmlSchemaParticlePtr) sub->next;
13014
lax = particle->minOccurs == 0;
13016
xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, lax);
13019
case XML_SCHEMA_TYPE_GROUP:
13021
* If we hit a model group definition, then this means that
13022
* it was empty, thus was not substituted for the containing
13023
* model group. Just do nothing in this case.
13024
* TODO: But the group should be substituted and not occur at
13025
* all in the content model at this point. Fix this.
13029
xmlSchemaInternalErr2(ACTXT_CAST pctxt,
13030
"xmlSchemaBuildAContentModel",
13031
"found unexpected term of type '%s' in content model",
13032
WXS_ITEM_TYPE_NAME(particle->children), NULL);
13038
* xmlSchemaBuildContentModel:
13039
* @ctxt: the schema parser context
13040
* @type: the complex type definition
13041
* @name: the element name
13043
* Builds the content model of the complex type.
13046
xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
13047
xmlSchemaParserCtxtPtr ctxt)
13049
if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
13050
(type->contModel != NULL) ||
13051
((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
13052
(type->contentType != XML_SCHEMA_CONTENT_MIXED)))
13055
#ifdef DEBUG_CONTENT
13056
xmlGenericError(xmlGenericErrorContext,
13057
"Building content model for %s\n", name);
13060
ctxt->am = xmlNewAutomata();
13061
if (ctxt->am == NULL) {
13062
xmlGenericError(xmlGenericErrorContext,
13063
"Cannot create automata for complex type %s\n", type->name);
13066
ctxt->state = xmlAutomataGetInitState(ctxt->am);
13068
* Build the automaton.
13070
xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
13071
xmlAutomataSetFinalState(ctxt->am, ctxt->state);
13072
type->contModel = xmlAutomataCompile(ctxt->am);
13073
if (type->contModel == NULL) {
13074
xmlSchemaPCustomErr(ctxt,
13075
XML_SCHEMAP_INTERNAL,
13076
WXS_BASIC_CAST type, type->node,
13077
"Failed to compile the content model", NULL);
13078
} else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
13079
xmlSchemaPCustomErr(ctxt,
13080
XML_SCHEMAP_NOT_DETERMINISTIC,
13081
/* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13082
WXS_BASIC_CAST type, type->node,
13083
"The content model is not determinist", NULL);
13085
#ifdef DEBUG_CONTENT_REGEXP
13086
xmlGenericError(xmlGenericErrorContext,
13087
"Content model of %s:\n", type->name);
13088
xmlRegexpPrint(stderr, type->contModel);
13091
ctxt->state = NULL;
13092
xmlFreeAutomata(ctxt->am);
13097
* xmlSchemaResolveElementReferences:
13098
* @elem: the schema element context
13099
* @ctxt: the schema parser context
13101
* Resolves the references of an element declaration
13102
* or particle, which has an element declaration as it's
13106
xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
13107
xmlSchemaParserCtxtPtr ctxt)
13109
if ((ctxt == NULL) || (elemDecl == NULL) ||
13110
((elemDecl != NULL) &&
13111
(elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
13113
elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
13115
if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
13116
xmlSchemaTypePtr type;
13118
/* (type definition) ... otherwise the type definition ļæ½resolvedļæ½
13119
* to by the ļæ½actual valueļæ½ of the type [attribute] ...
13121
type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
13122
elemDecl->namedTypeNs);
13123
if (type == NULL) {
13124
xmlSchemaPResCompAttrErr(ctxt,
13125
XML_SCHEMAP_SRC_RESOLVE,
13126
WXS_BASIC_CAST elemDecl, elemDecl->node,
13127
"type", elemDecl->namedType, elemDecl->namedTypeNs,
13128
XML_SCHEMA_TYPE_BASIC, "type definition");
13130
elemDecl->subtypes = type;
13132
if (elemDecl->substGroup != NULL) {
13133
xmlSchemaElementPtr substHead;
13136
* FIXME TODO: Do we need a new field in _xmlSchemaElement for
13137
* substitutionGroup?
13139
substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
13140
elemDecl->substGroupNs);
13141
if (substHead == NULL) {
13142
xmlSchemaPResCompAttrErr(ctxt,
13143
XML_SCHEMAP_SRC_RESOLVE,
13144
WXS_BASIC_CAST elemDecl, NULL,
13145
"substitutionGroup", elemDecl->substGroup,
13146
elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
13148
xmlSchemaResolveElementReferences(substHead, ctxt);
13150
* Set the "substitution group affiliation".
13151
* NOTE that now we use the "refDecl" field for this.
13153
WXS_SUBST_HEAD(elemDecl) = substHead;
13155
* The type definitions is set to:
13156
* SPEC "...the {type definition} of the element
13157
* declaration ļæ½resolvedļæ½ to by the ļæ½actual valueļæ½
13158
* of the substitutionGroup [attribute], if present"
13160
if (elemDecl->subtypes == NULL)
13161
elemDecl->subtypes = substHead->subtypes;
13165
* SPEC "The definition of anyType serves as the default type definition
13166
* for element declarations whose XML representation does not specify one."
13168
if ((elemDecl->subtypes == NULL) &&
13169
(elemDecl->namedType == NULL) &&
13170
(elemDecl->substGroup == NULL))
13171
elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
13175
* xmlSchemaResolveUnionMemberTypes:
13176
* @ctxt: the schema parser context
13177
* @type: the schema simple type definition
13179
* Checks and builds the "member type definitions" property of the union
13180
* simple type. This handles part (1), part (2) is done in
13181
* xmlSchemaFinishMemberTypeDefinitionsProperty()
13183
* Returns -1 in case of an internal error, 0 otherwise.
13186
xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
13187
xmlSchemaTypePtr type)
13190
xmlSchemaTypeLinkPtr link, lastLink, newLink;
13191
xmlSchemaTypePtr memberType;
13194
* SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13195
* define the explicit members as the type definitions ļæ½resolvedļæ½
13196
* to by the items in the ļæ½actual valueļæ½ of the memberTypes [attribute],
13197
* if any, followed by the type definitions corresponding to the
13198
* <simpleType>s among the [children] of <union>, if any."
13201
* Resolve references.
13203
link = type->memberTypes;
13205
while (link != NULL) {
13206
const xmlChar *name, *nsName;
13208
name = ((xmlSchemaQNameRefPtr) link->type)->name;
13209
nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
13211
memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
13212
if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
13213
xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
13214
WXS_BASIC_CAST type, type->node, "memberTypes",
13215
name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
13217
* Remove the member type link.
13219
if (lastLink == NULL)
13220
type->memberTypes = link->next;
13222
lastLink->next = link->next;
13227
link->type = memberType;
13233
* Add local simple types,
13235
memberType = type->subtypes;
13236
while (memberType != NULL) {
13237
link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
13238
if (link == NULL) {
13239
xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
13242
link->type = memberType;
13244
if (lastLink == NULL)
13245
type->memberTypes = link;
13247
lastLink->next = link;
13249
memberType = memberType->next;
13255
* xmlSchemaIsDerivedFromBuiltInType:
13256
* @ctxt: the schema parser context
13257
* @type: the type definition
13258
* @valType: the value type
13261
* Returns 1 if the type has the given value type, or
13262
* is derived from such a type.
13265
xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13269
if (WXS_IS_COMPLEX(type))
13271
if (type->type == XML_SCHEMA_TYPE_BASIC) {
13272
if (type->builtInType == valType)
13274
if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13275
(type->builtInType == XML_SCHEMAS_ANYTYPE))
13277
return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13279
return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13284
* xmlSchemaIsDerivedFromBuiltInType:
13285
* @ctxt: the schema parser context
13286
* @type: the type definition
13287
* @valType: the value type
13290
* Returns 1 if the type has the given value type, or
13291
* is derived from such a type.
13294
xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13298
if (WXS_IS_COMPLEX(type))
13300
if (type->type == XML_SCHEMA_TYPE_BASIC) {
13301
if (type->builtInType == valType)
13305
return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13311
static xmlSchemaTypePtr
13312
xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13316
if (WXS_IS_COMPLEX(type))
13318
if (type->type == XML_SCHEMA_TYPE_BASIC)
13320
return(xmlSchemaQueryBuiltInType(type->subtypes));
13324
* xmlSchemaGetPrimitiveType:
13325
* @type: the simpleType definition
13327
* Returns the primitive type of the given type or
13328
* NULL in case of error.
13330
static xmlSchemaTypePtr
13331
xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13334
while (type != NULL) {
13336
* Note that anySimpleType is actually not a primitive type
13337
* but we need that here.
13339
if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13340
(type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
13342
type = type->baseType;
13350
* xmlSchemaGetBuiltInTypeAncestor:
13351
* @type: the simpleType definition
13353
* Returns the primitive type of the given type or
13354
* NULL in case of error.
13356
static xmlSchemaTypePtr
13357
xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13359
if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
13361
while (type != NULL) {
13362
if (type->type == XML_SCHEMA_TYPE_BASIC)
13364
type = type->baseType;
13372
* xmlSchemaCloneWildcardNsConstraints:
13373
* @ctxt: the schema parser context
13374
* @dest: the destination wildcard
13375
* @source: the source wildcard
13377
* Clones the namespace constraints of source
13378
* and assignes them to dest.
13379
* Returns -1 on internal error, 0 otherwise.
13382
xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13383
xmlSchemaWildcardPtr dest,
13384
xmlSchemaWildcardPtr source)
13386
xmlSchemaWildcardNsPtr cur, tmp, last;
13388
if ((source == NULL) || (dest == NULL))
13390
dest->any = source->any;
13391
cur = source->nsSet;
13393
while (cur != NULL) {
13394
tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13397
tmp->value = cur->value;
13405
if (dest->negNsSet != NULL)
13406
xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13407
if (source->negNsSet != NULL) {
13408
dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13409
if (dest->negNsSet == NULL)
13411
dest->negNsSet->value = source->negNsSet->value;
13413
dest->negNsSet = NULL;
13418
* xmlSchemaUnionWildcards:
13419
* @ctxt: the schema parser context
13420
* @completeWild: the first wildcard
13421
* @curWild: the second wildcard
13423
* Unions the namespace constraints of the given wildcards.
13424
* @completeWild will hold the resulting union.
13425
* Returns a positive error code on failure, -1 in case of an
13426
* internal error, 0 otherwise.
13429
xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13430
xmlSchemaWildcardPtr completeWild,
13431
xmlSchemaWildcardPtr curWild)
13433
xmlSchemaWildcardNsPtr cur, curB, tmp;
13436
* 1 If O1 and O2 are the same value, then that value must be the
13439
if ((completeWild->any == curWild->any) &&
13440
((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13441
((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13443
if ((completeWild->negNsSet == NULL) ||
13444
(completeWild->negNsSet->value == curWild->negNsSet->value)) {
13446
if (completeWild->nsSet != NULL) {
13450
* Check equality of sets.
13452
cur = completeWild->nsSet;
13453
while (cur != NULL) {
13455
curB = curWild->nsSet;
13456
while (curB != NULL) {
13457
if (cur->value == curB->value) {
13474
* 2 If either O1 or O2 is any, then any must be the value
13476
if (completeWild->any != curWild->any) {
13477
if (completeWild->any == 0) {
13478
completeWild->any = 1;
13479
if (completeWild->nsSet != NULL) {
13480
xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13481
completeWild->nsSet = NULL;
13483
if (completeWild->negNsSet != NULL) {
13484
xmlFree(completeWild->negNsSet);
13485
completeWild->negNsSet = NULL;
13491
* 3 If both O1 and O2 are sets of (namespace names or ļæ½absentļæ½),
13492
* then the union of those sets must be the value.
13494
if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13496
xmlSchemaWildcardNsPtr start;
13498
cur = curWild->nsSet;
13499
start = completeWild->nsSet;
13500
while (cur != NULL) {
13503
while (curB != NULL) {
13504
if (cur->value == curB->value) {
13511
tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13514
tmp->value = cur->value;
13515
tmp->next = completeWild->nsSet;
13516
completeWild->nsSet = tmp;
13524
* 4 If the two are negations of different values (namespace names
13525
* or ļæ½absentļæ½), then a pair of not and ļæ½absentļæ½ must be the value.
13527
if ((completeWild->negNsSet != NULL) &&
13528
(curWild->negNsSet != NULL) &&
13529
(completeWild->negNsSet->value != curWild->negNsSet->value)) {
13530
completeWild->negNsSet->value = NULL;
13537
if (((completeWild->negNsSet != NULL) &&
13538
(completeWild->negNsSet->value != NULL) &&
13539
(curWild->nsSet != NULL)) ||
13540
((curWild->negNsSet != NULL) &&
13541
(curWild->negNsSet->value != NULL) &&
13542
(completeWild->nsSet != NULL))) {
13544
int nsFound, absentFound = 0;
13546
if (completeWild->nsSet != NULL) {
13547
cur = completeWild->nsSet;
13548
curB = curWild->negNsSet;
13550
cur = curWild->nsSet;
13551
curB = completeWild->negNsSet;
13554
while (cur != NULL) {
13555
if (cur->value == NULL)
13557
else if (cur->value == curB->value)
13559
if (nsFound && absentFound)
13564
if (nsFound && absentFound) {
13566
* 5.1 If the set S includes both the negated namespace
13567
* name and ļæ½absentļæ½, then any must be the value.
13569
completeWild->any = 1;
13570
if (completeWild->nsSet != NULL) {
13571
xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13572
completeWild->nsSet = NULL;
13574
if (completeWild->negNsSet != NULL) {
13575
xmlFree(completeWild->negNsSet);
13576
completeWild->negNsSet = NULL;
13578
} else if (nsFound && (!absentFound)) {
13580
* 5.2 If the set S includes the negated namespace name
13581
* but not ļæ½absentļæ½, then a pair of not and ļæ½absentļæ½ must
13584
if (completeWild->nsSet != NULL) {
13585
xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13586
completeWild->nsSet = NULL;
13588
if (completeWild->negNsSet == NULL) {
13589
completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13590
if (completeWild->negNsSet == NULL)
13593
completeWild->negNsSet->value = NULL;
13594
} else if ((!nsFound) && absentFound) {
13596
* 5.3 If the set S includes ļæ½absentļæ½ but not the negated
13597
* namespace name, then the union is not expressible.
13599
xmlSchemaPErr(ctxt, completeWild->node,
13600
XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
13601
"The union of the wilcard is not expressible.\n",
13603
return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
13604
} else if ((!nsFound) && (!absentFound)) {
13606
* 5.4 If the set S does not include either the negated namespace
13607
* name or ļæ½absentļæ½, then whichever of O1 or O2 is a pair of not
13608
* and a namespace name must be the value.
13610
if (completeWild->negNsSet == NULL) {
13611
if (completeWild->nsSet != NULL) {
13612
xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13613
completeWild->nsSet = NULL;
13615
completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13616
if (completeWild->negNsSet == NULL)
13618
completeWild->negNsSet->value = curWild->negNsSet->value;
13626
if (((completeWild->negNsSet != NULL) &&
13627
(completeWild->negNsSet->value == NULL) &&
13628
(curWild->nsSet != NULL)) ||
13629
((curWild->negNsSet != NULL) &&
13630
(curWild->negNsSet->value == NULL) &&
13631
(completeWild->nsSet != NULL))) {
13633
if (completeWild->nsSet != NULL) {
13634
cur = completeWild->nsSet;
13636
cur = curWild->nsSet;
13638
while (cur != NULL) {
13639
if (cur->value == NULL) {
13641
* 6.1 If the set S includes ļæ½absentļæ½, then any must be the
13644
completeWild->any = 1;
13645
if (completeWild->nsSet != NULL) {
13646
xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13647
completeWild->nsSet = NULL;
13649
if (completeWild->negNsSet != NULL) {
13650
xmlFree(completeWild->negNsSet);
13651
completeWild->negNsSet = NULL;
13657
if (completeWild->negNsSet == NULL) {
13659
* 6.2 If the set S does not include ļæ½absentļæ½, then a pair of not
13660
* and ļæ½absentļæ½ must be the value.
13662
if (completeWild->nsSet != NULL) {
13663
xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13664
completeWild->nsSet = NULL;
13666
completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13667
if (completeWild->negNsSet == NULL)
13669
completeWild->negNsSet->value = NULL;
13678
* xmlSchemaIntersectWildcards:
13679
* @ctxt: the schema parser context
13680
* @completeWild: the first wildcard
13681
* @curWild: the second wildcard
13683
* Intersects the namespace constraints of the given wildcards.
13684
* @completeWild will hold the resulting intersection.
13685
* Returns a positive error code on failure, -1 in case of an
13686
* internal error, 0 otherwise.
13689
xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13690
xmlSchemaWildcardPtr completeWild,
13691
xmlSchemaWildcardPtr curWild)
13693
xmlSchemaWildcardNsPtr cur, curB, prev, tmp;
13696
* 1 If O1 and O2 are the same value, then that value must be the
13699
if ((completeWild->any == curWild->any) &&
13700
((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13701
((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13703
if ((completeWild->negNsSet == NULL) ||
13704
(completeWild->negNsSet->value == curWild->negNsSet->value)) {
13706
if (completeWild->nsSet != NULL) {
13710
* Check equality of sets.
13712
cur = completeWild->nsSet;
13713
while (cur != NULL) {
13715
curB = curWild->nsSet;
13716
while (curB != NULL) {
13717
if (cur->value == curB->value) {
13734
* 2 If either O1 or O2 is any, then the other must be the value.
13736
if ((completeWild->any != curWild->any) && (completeWild->any)) {
13737
if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13742
* 3 If either O1 or O2 is a pair of not and a value (a namespace
13743
* name or ļæ½absentļæ½) and the other is a set of (namespace names or
13744
* ļæ½absentļæ½), then that set, minus the negated value if it was in
13745
* the set, minus ļæ½absentļæ½ if it was in the set, must be the value.
13747
if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
13748
((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
13749
const xmlChar *neg;
13751
if (completeWild->nsSet == NULL) {
13752
neg = completeWild->negNsSet->value;
13753
if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13756
neg = curWild->negNsSet->value;
13758
* Remove absent and negated.
13761
cur = completeWild->nsSet;
13762
while (cur != NULL) {
13763
if (cur->value == NULL) {
13765
completeWild->nsSet = cur->next;
13767
prev->next = cur->next;
13776
cur = completeWild->nsSet;
13777
while (cur != NULL) {
13778
if (cur->value == neg) {
13780
completeWild->nsSet = cur->next;
13782
prev->next = cur->next;
13794
* 4 If both O1 and O2 are sets of (namespace names or ļæ½absentļæ½),
13795
* then the intersection of those sets must be the value.
13797
if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13800
cur = completeWild->nsSet;
13802
while (cur != NULL) {
13804
curB = curWild->nsSet;
13805
while (curB != NULL) {
13806
if (cur->value == curB->value) {
13814
completeWild->nsSet = cur->next;
13816
prev->next = cur->next;
13828
/* 5 If the two are negations of different namespace names,
13829
* then the intersection is not expressible
13831
if ((completeWild->negNsSet != NULL) &&
13832
(curWild->negNsSet != NULL) &&
13833
(completeWild->negNsSet->value != curWild->negNsSet->value) &&
13834
(completeWild->negNsSet->value != NULL) &&
13835
(curWild->negNsSet->value != NULL)) {
13837
xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
13838
"The intersection of the wilcard is not expressible.\n",
13840
return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
13843
* 6 If the one is a negation of a namespace name and the other
13844
* is a negation of ļæ½absentļæ½, then the one which is the negation
13845
* of a namespace name must be the value.
13847
if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
13848
(completeWild->negNsSet->value != curWild->negNsSet->value) &&
13849
(completeWild->negNsSet->value == NULL)) {
13850
completeWild->negNsSet->value = curWild->negNsSet->value;
13856
* xmlSchemaIsWildcardNsConstraintSubset:
13857
* @ctxt: the schema parser context
13858
* @sub: the first wildcard
13859
* @super: the second wildcard
13861
* Schema Component Constraint: Wildcard Subset (cos-ns-subset)
13863
* Returns 0 if the namespace constraint of @sub is an intensional
13864
* subset of @super, 1 otherwise.
13867
xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
13868
xmlSchemaWildcardPtr super)
13871
* 1 super must be any.
13876
* 2.1 sub must be a pair of not and a namespace name or ļæ½absentļæ½.
13877
* 2.2 super must be a pair of not and the same value.
13879
if ((sub->negNsSet != NULL) &&
13880
(super->negNsSet != NULL) &&
13881
(sub->negNsSet->value == sub->negNsSet->value))
13884
* 3.1 sub must be a set whose members are either namespace names or ļæ½absentļæ½.
13886
if (sub->nsSet != NULL) {
13888
* 3.2.1 super must be the same set or a superset thereof.
13890
if (super->nsSet != NULL) {
13891
xmlSchemaWildcardNsPtr cur, curB;
13895
while (cur != NULL) {
13897
curB = super->nsSet;
13898
while (curB != NULL) {
13899
if (cur->value == curB->value) {
13911
} else if (super->negNsSet != NULL) {
13912
xmlSchemaWildcardNsPtr cur;
13914
* 3.2.2 super must be a pair of not and a namespace name or
13915
* ļæ½absentļæ½ and that value must not be in sub's set.
13918
while (cur != NULL) {
13919
if (cur->value == super->negNsSet->value)
13930
xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
13932
const xmlChar **value,
13933
xmlSchemaValPtr *val)
13940
if (attruse->defValue != NULL) {
13941
*value = attruse->defValue;
13943
*val = attruse->defVal;
13944
if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
13947
} else if ((attruse->attrDecl != NULL) &&
13948
(attruse->attrDecl->defValue != NULL)) {
13949
*value = attruse->attrDecl->defValue;
13951
*val = attruse->attrDecl->defVal;
13952
if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
13959
* xmlSchemaCheckCVCWildcardNamespace:
13960
* @wild: the wildcard
13961
* @ns: the namespace
13963
* Validation Rule: Wildcard allows Namespace Name
13964
* (cvc-wildcard-namespace)
13966
* Returns 0 if the given namespace matches the wildcard,
13967
* 1 otherwise and -1 on API errors.
13970
xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
13978
else if (wild->nsSet != NULL) {
13979
xmlSchemaWildcardNsPtr cur;
13982
while (cur != NULL) {
13983
if (xmlStrEqual(cur->value, ns))
13987
} else if ((wild->negNsSet != NULL) && (ns != NULL) &&
13988
(!xmlStrEqual(wild->negNsSet->value, ns)))
13994
#define XML_SCHEMA_ACTION_DERIVE 0
13995
#define XML_SCHEMA_ACTION_REDEFINE 1
13997
#define WXS_ACTION_STR(a) \
13998
((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14001
* Schema Component Constraint:
14002
* Derivation Valid (Restriction, Complex)
14003
* derivation-ok-restriction (2) - (4)
14006
* In XML Schema 1.1 this will be:
14008
* Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14012
xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
14014
xmlSchemaBasicItemPtr item,
14015
xmlSchemaBasicItemPtr baseItem,
14016
xmlSchemaItemListPtr uses,
14017
xmlSchemaItemListPtr baseUses,
14018
xmlSchemaWildcardPtr wild,
14019
xmlSchemaWildcardPtr baseWild)
14021
xmlSchemaAttributeUsePtr cur = NULL, bcur;
14022
int i, j, found; /* err = 0; */
14023
const xmlChar *bEffValue;
14026
if (uses != NULL) {
14027
for (i = 0; i < uses->nbItems; i++) {
14028
cur = uses->items[i];
14030
if (baseUses == NULL)
14032
for (j = 0; j < baseUses->nbItems; j++) {
14033
bcur = baseUses->items[j];
14034
if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14035
WXS_ATTRUSE_DECL_NAME(bcur)) &&
14036
(WXS_ATTRUSE_DECL_TNS(cur) ==
14037
WXS_ATTRUSE_DECL_TNS(bcur)))
14040
* (2.1) "If there is an attribute use in the {attribute
14041
* uses} of the {base type definition} (call this B) whose
14042
* {attribute declaration} has the same {name} and {target
14043
* namespace}, then all of the following must be true:"
14047
if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
14048
(bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
14050
xmlChar *str = NULL;
14052
* (2.1.1) "one of the following must be true:"
14053
* (2.1.1.1) "B's {required} is false."
14054
* (2.1.1.2) "R's {required} is true."
14056
xmlSchemaPAttrUseErr4(pctxt,
14057
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
14058
WXS_ITEM_NODE(item), item, cur,
14059
"The 'optional' attribute use is inconsistent "
14060
"with the corresponding 'required' attribute use of "
14062
WXS_ACTION_STR(action),
14063
xmlSchemaGetComponentDesignation(&str, baseItem),
14065
FREE_AND_NULL(str);
14066
/* err = pctxt->err; */
14067
} else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
14068
WXS_ATTRUSE_TYPEDEF(cur),
14069
WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
14071
xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
14074
* SPEC (2.1.2) "R's {attribute declaration}'s
14075
* {type definition} must be validly derived from
14076
* B's {type definition} given the empty set as
14077
* defined in Type Derivation OK (Simple) (ļæ½3.14.6)."
14079
xmlSchemaPAttrUseErr4(pctxt,
14080
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
14081
WXS_ITEM_NODE(item), item, cur,
14082
"The attribute declaration's %s "
14083
"is not validly derived from "
14084
"the corresponding %s of the "
14085
"attribute declaration in the %s %s",
14086
xmlSchemaGetComponentDesignation(&strA,
14087
WXS_ATTRUSE_TYPEDEF(cur)),
14088
xmlSchemaGetComponentDesignation(&strB,
14089
WXS_ATTRUSE_TYPEDEF(bcur)),
14090
WXS_ACTION_STR(action),
14091
xmlSchemaGetComponentDesignation(&strC, baseItem));
14092
/* xmlSchemaGetComponentDesignation(&str, baseItem), */
14093
FREE_AND_NULL(strA);
14094
FREE_AND_NULL(strB);
14095
FREE_AND_NULL(strC);
14096
/* err = pctxt->err; */
14099
* 2.1.3 [Definition:] Let the effective value
14100
* constraint of an attribute use be its {value
14101
* constraint}, if present, otherwise its {attribute
14102
* declaration}'s {value constraint} .
14104
xmlSchemaGetEffectiveValueConstraint(bcur,
14105
&effFixed, &bEffValue, NULL);
14107
* 2.1.3 ... one of the following must be true
14109
* 2.1.3.1 B's ļæ½effective value constraintļæ½ is
14110
* ļæ½absentļæ½ or default.
14112
if ((bEffValue != NULL) &&
14114
const xmlChar *rEffValue = NULL;
14116
xmlSchemaGetEffectiveValueConstraint(bcur,
14117
&effFixed, &rEffValue, NULL);
14119
* 2.1.3.2 R's ļæ½effective value constraintļæ½ is
14120
* fixed with the same string as B's.
14121
* MAYBE TODO: Compare the computed values.
14122
* Hmm, it says "same string" so
14123
* string-equality might really be sufficient.
14125
if ((effFixed == 0) ||
14126
(! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
14128
xmlChar *str = NULL;
14130
xmlSchemaPAttrUseErr4(pctxt,
14131
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
14132
WXS_ITEM_NODE(item), item, cur,
14133
"The effective value constraint of the "
14134
"attribute use is inconsistent with "
14135
"its correspondent in the %s %s",
14136
WXS_ACTION_STR(action),
14137
xmlSchemaGetComponentDesignation(&str,
14140
FREE_AND_NULL(str);
14141
/* err = pctxt->err; */
14151
* (2.2) "otherwise the {base type definition} must have an
14152
* {attribute wildcard} and the {target namespace} of the
14153
* R's {attribute declaration} must be ļæ½validļæ½ with respect
14154
* to that wildcard, as defined in Wildcard allows Namespace
14155
* Name (ļæ½3.10.4)."
14157
if ((baseWild == NULL) ||
14158
(xmlSchemaCheckCVCWildcardNamespace(baseWild,
14159
(WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
14161
xmlChar *str = NULL;
14163
xmlSchemaPAttrUseErr4(pctxt,
14164
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
14165
WXS_ITEM_NODE(item), item, cur,
14166
"Neither a matching attribute use, "
14167
"nor a matching wildcard exists in the %s %s",
14168
WXS_ACTION_STR(action),
14169
xmlSchemaGetComponentDesignation(&str, baseItem),
14171
FREE_AND_NULL(str);
14172
/* err = pctxt->err; */
14178
* SPEC derivation-ok-restriction (3):
14179
* (3) "For each attribute use in the {attribute uses} of the {base type
14180
* definition} whose {required} is true, there must be an attribute
14181
* use with an {attribute declaration} with the same {name} and
14182
* {target namespace} as its {attribute declaration} in the {attribute
14183
* uses} of the complex type definition itself whose {required} is true.
14185
if (baseUses != NULL) {
14186
for (j = 0; j < baseUses->nbItems; j++) {
14187
bcur = baseUses->items[j];
14188
if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
14191
if (uses != NULL) {
14192
for (i = 0; i < uses->nbItems; i++) {
14193
cur = uses->items[i];
14194
if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14195
WXS_ATTRUSE_DECL_NAME(bcur)) &&
14196
(WXS_ATTRUSE_DECL_TNS(cur) ==
14197
WXS_ATTRUSE_DECL_TNS(bcur))) {
14204
xmlChar *strA = NULL, *strB = NULL;
14206
xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14207
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
14209
"A matching attribute use for the "
14210
"'required' %s of the %s %s is missing",
14211
xmlSchemaGetComponentDesignation(&strA, bcur),
14212
WXS_ACTION_STR(action),
14213
xmlSchemaGetComponentDesignation(&strB, baseItem),
14215
FREE_AND_NULL(strA);
14216
FREE_AND_NULL(strB);
14221
* derivation-ok-restriction (4)
14223
if (wild != NULL) {
14225
* (4) "If there is an {attribute wildcard}, all of the
14226
* following must be true:"
14228
if (baseWild == NULL) {
14229
xmlChar *str = NULL;
14232
* (4.1) "The {base type definition} must also have one."
14234
xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14235
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
14237
"The %s has an attribute wildcard, "
14238
"but the %s %s '%s' does not have one",
14239
WXS_ITEM_TYPE_NAME(item),
14240
WXS_ACTION_STR(action),
14241
WXS_ITEM_TYPE_NAME(baseItem),
14242
xmlSchemaGetComponentQName(&str, baseItem));
14243
FREE_AND_NULL(str);
14244
return(pctxt->err);
14245
} else if ((baseWild->any == 0) &&
14246
xmlSchemaCheckCOSNSSubset(wild, baseWild))
14248
xmlChar *str = NULL;
14250
* (4.2) "The complex type definition's {attribute wildcard}'s
14251
* {namespace constraint} must be a subset of the {base type
14252
* definition}'s {attribute wildcard}'s {namespace constraint},
14253
* as defined by Wildcard Subset (ļæ½3.10.6)."
14255
xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14256
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
14258
"The attribute wildcard is not a valid "
14259
"subset of the wildcard in the %s %s '%s'",
14260
WXS_ACTION_STR(action),
14261
WXS_ITEM_TYPE_NAME(baseItem),
14262
xmlSchemaGetComponentQName(&str, baseItem),
14264
FREE_AND_NULL(str);
14265
return(pctxt->err);
14267
/* 4.3 Unless the {base type definition} is the ļæ½ur-type
14268
* definitionļæ½, the complex type definition's {attribute
14269
* wildcard}'s {process contents} must be identical to or
14270
* stronger than the {base type definition}'s {attribute
14271
* wildcard}'s {process contents}, where strict is stronger
14272
* than lax is stronger than skip.
14274
if ((! WXS_IS_ANYTYPE(baseItem)) &&
14275
(wild->processContents < baseWild->processContents)) {
14276
xmlChar *str = NULL;
14277
xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14278
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
14280
"The {process contents} of the attribute wildcard is "
14281
"weaker than the one in the %s %s '%s'",
14282
WXS_ACTION_STR(action),
14283
WXS_ITEM_TYPE_NAME(baseItem),
14284
xmlSchemaGetComponentQName(&str, baseItem),
14287
return(pctxt->err);
14295
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14296
xmlSchemaBasicItemPtr item,
14297
xmlSchemaWildcardPtr *completeWild,
14298
xmlSchemaItemListPtr list,
14299
xmlSchemaItemListPtr prohibs);
14301
* xmlSchemaFixupTypeAttributeUses:
14302
* @ctxt: the schema parser context
14303
* @type: the complex type definition
14306
* Builds the wildcard and the attribute uses on the given complex type.
14307
* Returns -1 if an internal error occurs, 0 otherwise.
14309
* ATTENTION TODO: Experimantally this uses pointer comparisons for
14310
* strings, so recheck this if we start to hardcode some schemata, since
14311
* they might not be in the same dict.
14312
* NOTE: It is allowed to "extend" the xs:anyType type.
14315
xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14316
xmlSchemaTypePtr type)
14318
xmlSchemaTypePtr baseType = NULL;
14319
xmlSchemaAttributeUsePtr use;
14320
xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
14322
if (type->baseType == NULL) {
14323
PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14327
baseType = type->baseType;
14328
if (WXS_IS_TYPE_NOT_FIXED(baseType))
14329
if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
14332
uses = type->attrUses;
14333
baseUses = baseType->attrUses;
14335
* Expand attribute group references. And build the 'complete'
14336
* wildcard, i.e. intersect multiple wildcards.
14337
* Move attribute prohibitions into a separate list.
14339
if (uses != NULL) {
14340
if (WXS_IS_RESTRICTION(type)) {
14342
* This one will transfer all attr. prohibitions
14343
* into pctxt->attrProhibs.
14345
if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14346
WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14347
pctxt->attrProhibs) == -1)
14349
PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14350
"failed to expand attributes");
14352
if (pctxt->attrProhibs->nbItems != 0)
14353
prohibs = pctxt->attrProhibs;
14355
if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14356
WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14359
PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14360
"failed to expand attributes");
14365
* Inherit the attribute uses of the base type.
14367
if (baseUses != NULL) {
14369
xmlSchemaAttributeUseProhibPtr pro;
14371
if (WXS_IS_RESTRICTION(type)) {
14373
xmlSchemaAttributeUsePtr tmp;
14376
usesCount = uses->nbItems;
14381
for (i = 0; i < baseUses->nbItems; i++) {
14382
use = baseUses->items[i];
14385
* Filter out prohibited uses.
14387
for (j = 0; j < prohibs->nbItems; j++) {
14388
pro = prohibs->items[j];
14389
if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
14390
(WXS_ATTRUSE_DECL_TNS(use) ==
14391
pro->targetNamespace))
14399
* Filter out existing uses.
14401
for (j = 0; j < usesCount; j++) {
14402
tmp = uses->items[j];
14403
if ((WXS_ATTRUSE_DECL_NAME(use) ==
14404
WXS_ATTRUSE_DECL_NAME(tmp)) &&
14405
(WXS_ATTRUSE_DECL_TNS(use) ==
14406
WXS_ATTRUSE_DECL_TNS(tmp)))
14412
if (uses == NULL) {
14413
type->attrUses = xmlSchemaItemListCreate();
14414
if (type->attrUses == NULL)
14416
uses = type->attrUses;
14418
xmlSchemaItemListAddSize(uses, 2, use);
14423
for (i = 0; i < baseUses->nbItems; i++) {
14424
use = baseUses->items[i];
14425
if (uses == NULL) {
14426
type->attrUses = xmlSchemaItemListCreate();
14427
if (type->attrUses == NULL)
14429
uses = type->attrUses;
14431
xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14436
* Shrink attr. uses.
14439
if (uses->nbItems == 0) {
14440
xmlSchemaItemListFree(uses);
14441
type->attrUses = NULL;
14444
* TODO: We could shrink the size of the array
14445
* to fit the actual number of items.
14449
* Compute the complete wildcard.
14451
if (WXS_IS_EXTENSION(type)) {
14452
if (baseType->attributeWildcard != NULL) {
14454
* (3.2.2.1) "If the ļæ½base wildcardļæ½ is non-ļæ½absentļæ½, then
14455
* the appropriate case among the following:"
14457
if (type->attributeWildcard != NULL) {
14459
* Union the complete wildcard with the base wildcard.
14460
* SPEC {attribute wildcard}
14461
* (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14462
* and {annotation} are those of the ļæ½complete wildcardļæ½,
14463
* and whose {namespace constraint} is the intensional union
14464
* of the {namespace constraint} of the ļæ½complete wildcardļæ½
14465
* and of the ļæ½base wildcardļæ½, as defined in Attribute
14466
* Wildcard Union (ļæ½3.10.6)."
14468
if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14469
baseType->attributeWildcard) == -1)
14473
* (3.2.2.1.1) "If the ļæ½complete wildcardļæ½ is ļæ½absentļæ½,
14474
* then the ļæ½base wildcardļæ½."
14476
type->attributeWildcard = baseType->attributeWildcard;
14480
* (3.2.2.2) "otherwise (the ļæ½base wildcardļæ½ is ļæ½absentļæ½) the
14481
* ļæ½complete wildcard"
14487
* SPEC {attribute wildcard}
14488
* (3.1) "If the <restriction> alternative is chosen, then the
14489
* ļæ½complete wildcardļæ½;"
14501
* xmlSchemaTypeFinalContains:
14502
* @schema: the schema
14503
* @type: the type definition
14504
* @final: the final
14506
* Evaluates if a type definition contains the given "final".
14507
* This does take "finalDefault" into account as well.
14509
* Returns 1 if the type does containt the given "final",
14513
xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14517
if (type->flags & final)
14524
* xmlSchemaGetUnionSimpleTypeMemberTypes:
14525
* @type: the Union Simple Type
14527
* Returns a list of member types of @type if existing,
14528
* returns NULL otherwise.
14530
static xmlSchemaTypeLinkPtr
14531
xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14533
while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14534
if (type->memberTypes != NULL)
14535
return (type->memberTypes);
14537
type = type->baseType;
14543
* xmlSchemaGetParticleTotalRangeMin:
14544
* @particle: the particle
14546
* Schema Component Constraint: Effective Total Range
14547
* (all and sequence) + (choice)
14549
* Returns the minimun Effective Total Range.
14552
xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14554
if ((particle->children == NULL) ||
14555
(particle->minOccurs == 0))
14557
if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14559
xmlSchemaParticlePtr part =
14560
(xmlSchemaParticlePtr) particle->children->children;
14564
while (part != NULL) {
14565
if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14566
(part->children->type == XML_SCHEMA_TYPE_ANY))
14567
cur = part->minOccurs;
14569
cur = xmlSchemaGetParticleTotalRangeMin(part);
14572
if ((min > cur) || (min == -1))
14574
part = (xmlSchemaParticlePtr) part->next;
14576
return (particle->minOccurs * min);
14578
/* <all> and <sequence> */
14580
xmlSchemaParticlePtr part =
14581
(xmlSchemaParticlePtr) particle->children->children;
14586
if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14587
(part->children->type == XML_SCHEMA_TYPE_ANY))
14588
sum += part->minOccurs;
14590
sum += xmlSchemaGetParticleTotalRangeMin(part);
14591
part = (xmlSchemaParticlePtr) part->next;
14592
} while (part != NULL);
14593
return (particle->minOccurs * sum);
14598
* xmlSchemaGetParticleTotalRangeMax:
14599
* @particle: the particle
14601
* Schema Component Constraint: Effective Total Range
14602
* (all and sequence) + (choice)
14604
* Returns the maximum Effective Total Range.
14607
xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14609
if ((particle->children == NULL) ||
14610
(particle->children->children == NULL))
14612
if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14614
xmlSchemaParticlePtr part =
14615
(xmlSchemaParticlePtr) particle->children->children;
14617
for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14618
if (part->children == NULL)
14620
if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14621
(part->children->type == XML_SCHEMA_TYPE_ANY))
14622
cur = part->maxOccurs;
14624
cur = xmlSchemaGetParticleTotalRangeMax(part);
14625
if (cur == UNBOUNDED)
14626
return (UNBOUNDED);
14627
if ((max < cur) || (max == -1))
14630
/* TODO: Handle overflows? */
14631
return (particle->maxOccurs * max);
14633
/* <all> and <sequence> */
14635
xmlSchemaParticlePtr part =
14636
(xmlSchemaParticlePtr) particle->children->children;
14638
for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14639
if (part->children == NULL)
14641
if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14642
(part->children->type == XML_SCHEMA_TYPE_ANY))
14643
cur = part->maxOccurs;
14645
cur = xmlSchemaGetParticleTotalRangeMax(part);
14646
if (cur == UNBOUNDED)
14647
return (UNBOUNDED);
14648
if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
14649
return (UNBOUNDED);
14652
/* TODO: Handle overflows? */
14653
return (particle->maxOccurs * sum);
14658
* xmlSchemaIsParticleEmptiable:
14659
* @particle: the particle
14661
* Schema Component Constraint: Particle Emptiable
14662
* Checks whether the given particle is emptiable.
14664
* Returns 1 if emptiable, 0 otherwise.
14667
xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14670
* SPEC (1) "Its {min occurs} is 0."
14672
if ((particle == NULL) || (particle->minOccurs == 0) ||
14673
(particle->children == NULL))
14676
* SPEC (2) "Its {term} is a group and the minimum part of the
14677
* effective total range of that group, [...] is 0."
14679
if (WXS_IS_MODEL_GROUP(particle->children)) {
14680
if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
14687
* xmlSchemaCheckCOSSTDerivedOK:
14688
* @actxt: a context
14689
* @type: the derived simple type definition
14690
* @baseType: the base type definition
14691
* @subset: the subset of ('restriction', ect.)
14693
* Schema Component Constraint:
14694
* Type Derivation OK (Simple) (cos-st-derived-OK)
14696
* Checks wheter @type can be validly
14697
* derived from @baseType.
14699
* Returns 0 on success, an positive error code otherwise.
14702
xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14703
xmlSchemaTypePtr type,
14704
xmlSchemaTypePtr baseType,
14708
* 1 They are the same type definition.
14709
* TODO: The identy check might have to be more complex than this.
14711
if (type == baseType)
14714
* 2.1 restriction is not in the subset, or in the {final}
14715
* of its own {base type definition};
14717
* NOTE that this will be used also via "xsi:type".
14719
* TODO: Revise this, it looks strange. How can the "type"
14720
* not be fixed or *in* fixing?
14722
if (WXS_IS_TYPE_NOT_FIXED(type))
14723
if (xmlSchemaTypeFixup(type, actxt) == -1)
14725
if (WXS_IS_TYPE_NOT_FIXED(baseType))
14726
if (xmlSchemaTypeFixup(baseType, actxt) == -1)
14728
if ((subset & SUBSET_RESTRICTION) ||
14729
(xmlSchemaTypeFinalContains(type->baseType,
14730
XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
14731
return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
14734
if (type->baseType == baseType) {
14736
* 2.2.1 D's ļæ½base type definitionļæ½ is B.
14741
* 2.2.2 D's ļæ½base type definitionļæ½ is not the ļæ½ur-type definitionļæ½
14742
* and is validly derived from B given the subset, as defined by this
14745
if ((! WXS_IS_ANYTYPE(type->baseType)) &&
14746
(xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14747
baseType, subset) == 0)) {
14751
* 2.2.3 D's {variety} is list or union and B is the ļæ½simple ur-type
14754
if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
14755
(WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
14759
* 2.2.4 B's {variety} is union and D is validly derived from a type
14760
* definition in B's {member type definitions} given the subset, as
14761
* defined by this constraint.
14763
* NOTE: This seems not to involve built-in types, since there is no
14764
* built-in Union Simple Type.
14766
if (WXS_IS_UNION(baseType)) {
14767
xmlSchemaTypeLinkPtr cur;
14769
cur = baseType->memberTypes;
14770
while (cur != NULL) {
14771
if (WXS_IS_TYPE_NOT_FIXED(cur->type))
14772
if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
14774
if (xmlSchemaCheckCOSSTDerivedOK(actxt,
14775
type, cur->type, subset) == 0)
14778
* It just has to be validly derived from at least one
14786
return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
14790
* xmlSchemaCheckTypeDefCircularInternal:
14791
* @pctxt: the schema parser context
14792
* @ctxtType: the type definition
14793
* @ancestor: an ancestor of @ctxtType
14795
* Checks st-props-correct (2) + ct-props-correct (3).
14796
* Circular type definitions are not allowed.
14798
* Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
14799
* circular, 0 otherwise.
14802
xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
14803
xmlSchemaTypePtr ctxtType,
14804
xmlSchemaTypePtr ancestor)
14808
if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
14811
if (ctxtType == ancestor) {
14812
xmlSchemaPCustomErr(pctxt,
14813
XML_SCHEMAP_ST_PROPS_CORRECT_2,
14814
WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
14815
"The definition is circular", NULL);
14816
return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
14818
if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
14820
* Avoid inifinite recursion on circular types not yet checked.
14824
ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
14825
ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
14826
ancestor->baseType);
14827
ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
14832
* xmlSchemaCheckTypeDefCircular:
14833
* @item: the complex/simple type definition
14834
* @ctxt: the parser context
14837
* Checks for circular type definitions.
14840
xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
14841
xmlSchemaParserCtxtPtr ctxt)
14843
if ((item == NULL) ||
14844
(item->type == XML_SCHEMA_TYPE_BASIC) ||
14845
(item->baseType == NULL))
14847
xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
14852
* Simple Type Definition Representation OK (src-simple-type) 4
14854
* "4 Circular union type definition is disallowed. That is, if the
14855
* <union> alternative is chosen, there must not be any entries in the
14856
* memberTypes [attribute] at any depth which resolve to the component
14857
* corresponding to the <simpleType>."
14859
* Note that this should work on the *representation* of a component,
14860
* thus assumes any union types in the member types not being yet
14861
* substituted. At this stage we need the variety of the types
14862
* to be already computed.
14865
xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
14866
xmlSchemaTypePtr ctxType,
14867
xmlSchemaTypeLinkPtr members)
14869
xmlSchemaTypeLinkPtr member;
14870
xmlSchemaTypePtr memberType;
14873
while (member != NULL) {
14874
memberType = member->type;
14875
while ((memberType != NULL) &&
14876
(memberType->type != XML_SCHEMA_TYPE_BASIC)) {
14877
if (memberType == ctxType) {
14878
xmlSchemaPCustomErr(pctxt,
14879
XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
14880
WXS_BASIC_CAST ctxType, NULL,
14881
"The union type definition is circular", NULL);
14882
return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
14884
if ((WXS_IS_UNION(memberType)) &&
14885
((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
14888
memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
14889
res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
14891
xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
14892
memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
14896
memberType = memberType->baseType;
14898
member = member->next;
14904
xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
14905
xmlSchemaTypePtr type)
14907
if (! WXS_IS_UNION(type))
14909
return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
14910
type->memberTypes));
14914
* xmlSchemaResolveTypeReferences:
14915
* @item: the complex/simple type definition
14916
* @ctxt: the parser context
14919
* Resolvese type definition references
14922
xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
14923
xmlSchemaParserCtxtPtr ctxt)
14925
if (typeDef == NULL)
14929
* Resolve the base type.
14931
if (typeDef->baseType == NULL) {
14932
typeDef->baseType = xmlSchemaGetType(ctxt->schema,
14933
typeDef->base, typeDef->baseNs);
14934
if (typeDef->baseType == NULL) {
14935
xmlSchemaPResCompAttrErr(ctxt,
14936
XML_SCHEMAP_SRC_RESOLVE,
14937
WXS_BASIC_CAST typeDef, typeDef->node,
14938
"base", typeDef->base, typeDef->baseNs,
14939
XML_SCHEMA_TYPE_SIMPLE, NULL);
14943
if (WXS_IS_SIMPLE(typeDef)) {
14944
if (WXS_IS_UNION(typeDef)) {
14946
* Resolve the memberTypes.
14948
xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
14950
} else if (WXS_IS_LIST(typeDef)) {
14952
* Resolve the itemType.
14954
if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
14956
typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
14957
typeDef->base, typeDef->baseNs);
14959
if ((typeDef->subtypes == NULL) ||
14960
(! WXS_IS_SIMPLE(typeDef->subtypes)))
14962
typeDef->subtypes = NULL;
14963
xmlSchemaPResCompAttrErr(ctxt,
14964
XML_SCHEMAP_SRC_RESOLVE,
14965
WXS_BASIC_CAST typeDef, typeDef->node,
14966
"itemType", typeDef->base, typeDef->baseNs,
14967
XML_SCHEMA_TYPE_SIMPLE, NULL);
14974
* The ball of letters below means, that if we have a particle
14975
* which has a QName-helper component as its {term}, we want
14978
else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
14979
((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
14980
XML_SCHEMA_TYPE_PARTICLE) &&
14981
(WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
14982
((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
14983
XML_SCHEMA_EXTRA_QNAMEREF))
14985
xmlSchemaQNameRefPtr ref =
14986
WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
14987
xmlSchemaModelGroupDefPtr groupDef;
14990
* URGENT TODO: Test this.
14992
WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
14994
* Resolve the MG definition reference.
14997
WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
14998
ref->itemType, ref->name, ref->targetNamespace);
14999
if (groupDef == NULL) {
15000
xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
15001
NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
15002
"ref", ref->name, ref->targetNamespace, ref->itemType,
15004
/* Remove the particle. */
15005
WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15006
} else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
15007
/* Remove the particle. */
15008
WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15011
* Assign the MG definition's {model group} to the
15012
* particle's {term}.
15014
WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
15016
if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
15018
* SPEC cos-all-limited (1.2)
15019
* "1.2 the {term} property of a particle with
15020
* {max occurs}=1 which is part of a pair which constitutes
15021
* the {content type} of a complex type definition."
15023
if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
15024
xmlSchemaCustomErr(ACTXT_CAST ctxt,
15025
/* TODO: error code */
15026
XML_SCHEMAP_COS_ALL_LIMITED,
15027
WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
15028
"The particle's {max occurs} must be 1, since the "
15029
"reference resolves to an 'all' model group",
15040
* xmlSchemaCheckSTPropsCorrect:
15041
* @ctxt: the schema parser context
15042
* @type: the simple type definition
15044
* Checks st-props-correct.
15046
* Returns 0 if the properties are correct,
15047
* if not, a positive error code and -1 on internal
15051
xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
15052
xmlSchemaTypePtr type)
15054
xmlSchemaTypePtr baseType = type->baseType;
15055
xmlChar *str = NULL;
15057
/* STATE: error funcs converted. */
15059
* Schema Component Constraint: Simple Type Definition Properties Correct
15061
* NOTE: This is somehow redundant, since we actually built a simple type
15062
* to have all the needed information; this acts as an self test.
15064
/* Base type: If the datatype has been ļæ½derivedļæ½ by ļæ½restrictionļæ½
15065
* then the Simple Type Definition component from which it is ļæ½derivedļæ½,
15066
* otherwise the Simple Type Definition for anySimpleType (ļæ½4.1.6).
15068
if (baseType == NULL) {
15070
* TODO: Think about: "modulo the impact of Missing
15071
* Sub-components (ļæ½5.3)."
15073
xmlSchemaPCustomErr(ctxt,
15074
XML_SCHEMAP_ST_PROPS_CORRECT_1,
15075
WXS_BASIC_CAST type, NULL,
15076
"No base type existent", NULL);
15077
return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15080
if (! WXS_IS_SIMPLE(baseType)) {
15081
xmlSchemaPCustomErr(ctxt,
15082
XML_SCHEMAP_ST_PROPS_CORRECT_1,
15083
WXS_BASIC_CAST type, NULL,
15084
"The base type '%s' is not a simple type",
15085
xmlSchemaGetComponentQName(&str, baseType));
15087
return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15089
if ( (WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
15090
(WXS_IS_RESTRICTION(type) == 0) &&
15091
(! WXS_IS_ANY_SIMPLE_TYPE(baseType))) {
15092
xmlSchemaPCustomErr(ctxt,
15093
XML_SCHEMAP_ST_PROPS_CORRECT_1,
15094
WXS_BASIC_CAST type, NULL,
15095
"A type, derived by list or union, must have"
15096
"the simple ur-type definition as base type, not '%s'",
15097
xmlSchemaGetComponentQName(&str, baseType));
15099
return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15102
* Variety: One of {atomic, list, union}.
15104
if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
15105
(! WXS_IS_LIST(type))) {
15106
xmlSchemaPCustomErr(ctxt,
15107
XML_SCHEMAP_ST_PROPS_CORRECT_1,
15108
WXS_BASIC_CAST type, NULL,
15109
"The variety is absent", NULL);
15110
return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15112
/* TODO: Finish this. Hmm, is this finished? */
15115
* 3 The {final} of the {base type definition} must not contain restriction.
15117
if (xmlSchemaTypeFinalContains(baseType,
15118
XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15119
xmlSchemaPCustomErr(ctxt,
15120
XML_SCHEMAP_ST_PROPS_CORRECT_3,
15121
WXS_BASIC_CAST type, NULL,
15122
"The 'final' of its base type '%s' must not contain "
15124
xmlSchemaGetComponentQName(&str, baseType));
15126
return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
15130
* 2 All simple type definitions must be derived ultimately from the ļæ½simple
15131
* ur-type definition (soļæ½ circular definitions are disallowed). That is, it
15132
* must be possible to reach a built-in primitive datatype or the ļæ½simple
15133
* ur-type definitionļæ½ by repeatedly following the {base type definition}.
15135
* NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15141
* xmlSchemaCheckCOSSTRestricts:
15142
* @ctxt: the schema parser context
15143
* @type: the simple type definition
15145
* Schema Component Constraint:
15146
* Derivation Valid (Restriction, Simple) (cos-st-restricts)
15148
* Checks if the given @type (simpleType) is derived validly by restriction.
15151
* Returns -1 on internal errors, 0 if the type is validly derived,
15152
* a positive error code otherwise.
15155
xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
15156
xmlSchemaTypePtr type)
15158
xmlChar *str = NULL;
15160
if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
15161
PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15162
"given type is not a user-derived simpleType");
15166
if (WXS_IS_ATOMIC(type)) {
15167
xmlSchemaTypePtr primitive;
15169
* 1.1 The {base type definition} must be an atomic simple
15170
* type definition or a built-in primitive datatype.
15172
if (! WXS_IS_ATOMIC(type->baseType)) {
15173
xmlSchemaPCustomErr(pctxt,
15174
XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
15175
WXS_BASIC_CAST type, NULL,
15176
"The base type '%s' is not an atomic simple type",
15177
xmlSchemaGetComponentQName(&str, type->baseType));
15179
return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
15181
/* 1.2 The {final} of the {base type definition} must not contain
15184
/* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15185
if (xmlSchemaTypeFinalContains(type->baseType,
15186
XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15187
xmlSchemaPCustomErr(pctxt,
15188
XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
15189
WXS_BASIC_CAST type, NULL,
15190
"The final of its base type '%s' must not contain 'restriction'",
15191
xmlSchemaGetComponentQName(&str, type->baseType));
15193
return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
15197
* 1.3.1 DF must be an allowed constraining facet for the {primitive
15198
* type definition}, as specified in the appropriate subsection of 3.2
15199
* Primitive datatypes.
15201
if (type->facets != NULL) {
15202
xmlSchemaFacetPtr facet;
15205
primitive = xmlSchemaGetPrimitiveType(type);
15206
if (primitive == NULL) {
15207
PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15208
"failed to get primitive type");
15211
facet = type->facets;
15213
if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15215
xmlSchemaPIllegalFacetAtomicErr(pctxt,
15216
XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
15217
type, primitive, facet);
15219
facet = facet->next;
15220
} while (facet != NULL);
15222
return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
15225
* SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15226
* of the {base type definition} (call this BF),then the DF's {value}
15227
* must be a valid restriction of BF's {value} as defined in
15228
* [XML Schemas: Datatypes]."
15230
* NOTE (1.3.2) Facet derivation constraints are currently handled in
15231
* xmlSchemaDeriveAndValidateFacets()
15233
} else if (WXS_IS_LIST(type)) {
15234
xmlSchemaTypePtr itemType = NULL;
15236
itemType = type->subtypes;
15237
if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
15238
PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15239
"failed to evaluate the item type");
15242
if (WXS_IS_TYPE_NOT_FIXED(itemType))
15243
xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
15245
* 2.1 The {item type definition} must have a {variety} of atomic or
15246
* union (in which case all the {member type definitions}
15249
if ((! WXS_IS_ATOMIC(itemType)) &&
15250
(! WXS_IS_UNION(itemType))) {
15251
xmlSchemaPCustomErr(pctxt,
15252
XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15253
WXS_BASIC_CAST type, NULL,
15254
"The item type '%s' does not have a variety of atomic or union",
15255
xmlSchemaGetComponentQName(&str, itemType));
15257
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15258
} else if (WXS_IS_UNION(itemType)) {
15259
xmlSchemaTypeLinkPtr member;
15261
member = itemType->memberTypes;
15262
while (member != NULL) {
15263
if (! WXS_IS_ATOMIC(member->type)) {
15264
xmlSchemaPCustomErr(pctxt,
15265
XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15266
WXS_BASIC_CAST type, NULL,
15267
"The item type is a union type, but the "
15268
"member type '%s' of this item type is not atomic",
15269
xmlSchemaGetComponentQName(&str, member->type));
15271
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15273
member = member->next;
15277
if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
15278
xmlSchemaFacetPtr facet;
15280
* This is the case if we have: <simpleType><list ..
15284
* 2.3.1.1 The {final} of the {item type definition} must not
15287
if (xmlSchemaTypeFinalContains(itemType,
15288
XML_SCHEMAS_TYPE_FINAL_LIST)) {
15289
xmlSchemaPCustomErr(pctxt,
15290
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
15291
WXS_BASIC_CAST type, NULL,
15292
"The final of its item type '%s' must not contain 'list'",
15293
xmlSchemaGetComponentQName(&str, itemType));
15295
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
15298
* 2.3.1.2 The {facets} must only contain the whiteSpace
15300
* OPTIMIZE TODO: the S4S already disallows any facet
15303
if (type->facets != NULL) {
15304
facet = type->facets;
15306
if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15307
xmlSchemaPIllegalFacetListUnionErr(pctxt,
15308
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
15310
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
15312
facet = facet->next;
15313
} while (facet != NULL);
15316
* MAYBE TODO: (Hmm, not really) Datatypes states:
15317
* A ļæ½listļæ½ datatype can be ļæ½derivedļæ½ from an ļæ½atomicļæ½ datatype
15318
* whose ļæ½lexical spaceļæ½ allows space (such as string or anyURI)or
15319
* a ļæ½unionļæ½ datatype any of whose {member type definitions}'s
15320
* ļæ½lexical spaceļæ½ allows space.
15324
* This is the case if we have: <simpleType><restriction ...
15325
* I.e. the variety of "list" is inherited.
15329
* 2.3.2.1 The {base type definition} must have a {variety} of list.
15331
if (! WXS_IS_LIST(type->baseType)) {
15332
xmlSchemaPCustomErr(pctxt,
15333
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
15334
WXS_BASIC_CAST type, NULL,
15335
"The base type '%s' must be a list type",
15336
xmlSchemaGetComponentQName(&str, type->baseType));
15338
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
15341
* 2.3.2.2 The {final} of the {base type definition} must not
15342
* contain restriction.
15344
if (xmlSchemaTypeFinalContains(type->baseType,
15345
XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15346
xmlSchemaPCustomErr(pctxt,
15347
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
15348
WXS_BASIC_CAST type, NULL,
15349
"The 'final' of the base type '%s' must not contain 'restriction'",
15350
xmlSchemaGetComponentQName(&str, type->baseType));
15352
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
15355
* 2.3.2.3 The {item type definition} must be validly derived
15356
* from the {base type definition}'s {item type definition} given
15357
* the empty set, as defined in Type Derivation OK (Simple) (ļæ½3.14.6).
15360
xmlSchemaTypePtr baseItemType;
15362
baseItemType = type->baseType->subtypes;
15363
if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
15364
PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15365
"failed to eval the item type of a base type");
15368
if ((itemType != baseItemType) &&
15369
(xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
15370
baseItemType, 0) != 0)) {
15371
xmlChar *strBIT = NULL, *strBT = NULL;
15372
xmlSchemaPCustomErrExt(pctxt,
15373
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
15374
WXS_BASIC_CAST type, NULL,
15375
"The item type '%s' is not validly derived from "
15376
"the item type '%s' of the base type '%s'",
15377
xmlSchemaGetComponentQName(&str, itemType),
15378
xmlSchemaGetComponentQName(&strBIT, baseItemType),
15379
xmlSchemaGetComponentQName(&strBT, type->baseType));
15382
FREE_AND_NULL(strBIT)
15383
FREE_AND_NULL(strBT)
15384
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
15388
if (type->facets != NULL) {
15389
xmlSchemaFacetPtr facet;
15392
* 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15393
* and enumeration facet components are allowed among the {facets}.
15395
facet = type->facets;
15397
switch (facet->type) {
15398
case XML_SCHEMA_FACET_LENGTH:
15399
case XML_SCHEMA_FACET_MINLENGTH:
15400
case XML_SCHEMA_FACET_MAXLENGTH:
15401
case XML_SCHEMA_FACET_WHITESPACE:
15403
* TODO: 2.5.1.2 List datatypes
15404
* The value of ļæ½whiteSpaceļæ½ is fixed to the value collapse.
15406
case XML_SCHEMA_FACET_PATTERN:
15407
case XML_SCHEMA_FACET_ENUMERATION:
15410
xmlSchemaPIllegalFacetListUnionErr(pctxt,
15411
XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
15414
* We could return, but it's nicer to report all
15420
facet = facet->next;
15421
} while (facet != NULL);
15423
return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
15425
* SPEC (2.3.2.5) (same as 1.3.2)
15427
* NOTE (2.3.2.5) This is currently done in
15428
* xmlSchemaDeriveAndValidateFacets()
15432
} else if (WXS_IS_UNION(type)) {
15434
* 3.1 The {member type definitions} must all have {variety} of
15437
xmlSchemaTypeLinkPtr member;
15439
member = type->memberTypes;
15440
while (member != NULL) {
15441
if (WXS_IS_TYPE_NOT_FIXED(member->type))
15442
xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
15444
if ((! WXS_IS_ATOMIC(member->type)) &&
15445
(! WXS_IS_LIST(member->type))) {
15446
xmlSchemaPCustomErr(pctxt,
15447
XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
15448
WXS_BASIC_CAST type, NULL,
15449
"The member type '%s' is neither an atomic, nor a list type",
15450
xmlSchemaGetComponentQName(&str, member->type));
15452
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
15454
member = member->next;
15457
* 3.3.1 If the {base type definition} is the ļæ½simple ur-type
15460
if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15462
* 3.3.1.1 All of the {member type definitions} must have a
15463
* {final} which does not contain union.
15465
member = type->memberTypes;
15466
while (member != NULL) {
15467
if (xmlSchemaTypeFinalContains(member->type,
15468
XML_SCHEMAS_TYPE_FINAL_UNION)) {
15469
xmlSchemaPCustomErr(pctxt,
15470
XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
15471
WXS_BASIC_CAST type, NULL,
15472
"The 'final' of member type '%s' contains 'union'",
15473
xmlSchemaGetComponentQName(&str, member->type));
15475
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
15477
member = member->next;
15480
* 3.3.1.2 The {facets} must be empty.
15482
if (type->facetSet != NULL) {
15483
xmlSchemaPCustomErr(pctxt,
15484
XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
15485
WXS_BASIC_CAST type, NULL,
15486
"No facets allowed", NULL);
15487
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
15491
* 3.3.2.1 The {base type definition} must have a {variety} of union.
15492
* I.e. the variety of "list" is inherited.
15494
if (! WXS_IS_UNION(type->baseType)) {
15495
xmlSchemaPCustomErr(pctxt,
15496
XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
15497
WXS_BASIC_CAST type, NULL,
15498
"The base type '%s' is not a union type",
15499
xmlSchemaGetComponentQName(&str, type->baseType));
15501
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
15504
* 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15506
if (xmlSchemaTypeFinalContains(type->baseType,
15507
XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15508
xmlSchemaPCustomErr(pctxt,
15509
XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
15510
WXS_BASIC_CAST type, NULL,
15511
"The 'final' of its base type '%s' must not contain 'restriction'",
15512
xmlSchemaGetComponentQName(&str, type->baseType));
15514
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
15517
* 3.3.2.3 The {member type definitions}, in order, must be validly
15518
* derived from the corresponding type definitions in the {base
15519
* type definition}'s {member type definitions} given the empty set,
15520
* as defined in Type Derivation OK (Simple) (ļæ½3.14.6).
15523
xmlSchemaTypeLinkPtr baseMember;
15526
* OPTIMIZE: if the type is restricting, it has no local defined
15527
* member types and inherits the member types of the base type;
15528
* thus a check for equality can be skipped.
15531
* Even worse: I cannot see a scenario where a restricting
15532
* union simple type can have other member types as the member
15533
* types of it's base type. This check seems not necessary with
15534
* respect to the derivation process in libxml2.
15535
* But necessary if constructing types with an API.
15537
if (type->memberTypes != NULL) {
15538
member = type->memberTypes;
15539
baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15540
if ((member == NULL) && (baseMember != NULL)) {
15541
PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15542
"different number of member types in base");
15544
while (member != NULL) {
15545
if (baseMember == NULL) {
15546
PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15547
"different number of member types in base");
15548
} else if ((member->type != baseMember->type) &&
15549
(xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
15550
member->type, baseMember->type, 0) != 0)) {
15551
xmlChar *strBMT = NULL, *strBT = NULL;
15553
xmlSchemaPCustomErrExt(pctxt,
15554
XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
15555
WXS_BASIC_CAST type, NULL,
15556
"The member type %s is not validly "
15557
"derived from its corresponding member "
15558
"type %s of the base type %s",
15559
xmlSchemaGetComponentQName(&str, member->type),
15560
xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15561
xmlSchemaGetComponentQName(&strBT, type->baseType));
15563
FREE_AND_NULL(strBMT)
15564
FREE_AND_NULL(strBT)
15565
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
15567
member = member->next;
15568
baseMember = baseMember->next;
15573
* 3.3.2.4 Only pattern and enumeration facet components are
15574
* allowed among the {facets}.
15576
if (type->facets != NULL) {
15577
xmlSchemaFacetPtr facet;
15580
facet = type->facets;
15582
if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15583
(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15584
xmlSchemaPIllegalFacetListUnionErr(pctxt,
15585
XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
15589
facet = facet->next;
15590
} while (facet != NULL);
15592
return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
15596
* SPEC (3.3.2.5) (same as 1.3.2)
15598
* NOTE (3.3.2.5) This is currently done in
15599
* xmlSchemaDeriveAndValidateFacets()
15608
* xmlSchemaCheckSRCSimpleType:
15609
* @ctxt: the schema parser context
15610
* @type: the simple type definition
15612
* Checks crc-simple-type constraints.
15614
* Returns 0 if the constraints are satisfied,
15615
* if not a positive error code and -1 on internal
15620
xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15621
xmlSchemaTypePtr type)
15624
* src-simple-type.1 The corresponding simple type definition, if any,
15625
* must satisfy the conditions set out in Constraints on Simple Type
15626
* Definition Schema Components (ļæ½3.14.6).
15628
if (WXS_IS_RESTRICTION(type)) {
15630
* src-simple-type.2 "If the <restriction> alternative is chosen,
15631
* either it must have a base [attribute] or a <simpleType> among its
15632
* [children], but not both."
15633
* NOTE: This is checked in the parse function of <restriction>.
15638
} else if (WXS_IS_LIST(type)) {
15639
/* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15640
* an itemType [attribute] or a <simpleType> among its [children],
15643
* NOTE: This is checked in the parse function of <list>.
15645
} else if (WXS_IS_UNION(type)) {
15647
* src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15655
xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15657
if (ctxt->vctxt == NULL) {
15658
ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
15659
if (ctxt->vctxt == NULL) {
15660
xmlSchemaPErr(ctxt, NULL,
15661
XML_SCHEMAP_INTERNAL,
15662
"Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15663
"failed to create a temp. validation context.\n",
15667
/* TODO: Pass user data. */
15668
xmlSchemaSetValidErrors(ctxt->vctxt,
15669
ctxt->error, ctxt->warning, ctxt->errCtxt);
15670
xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15671
ctxt->serror, ctxt->errCtxt);
15677
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15679
xmlSchemaTypePtr type,
15680
const xmlChar *value,
15681
xmlSchemaValPtr *retVal,
15687
* xmlSchemaParseCheckCOSValidDefault:
15688
* @pctxt: the schema parser context
15689
* @type: the simple type definition
15690
* @value: the default value
15691
* @node: an optional node (the holder of the value)
15693
* Schema Component Constraint: Element Default Valid (Immediate)
15694
* (cos-valid-default)
15695
* This will be used by the parser only. For the validator there's
15696
* an other version.
15698
* Returns 0 if the constraints are satisfied,
15699
* if not, a positive error code and -1 on internal
15703
xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15705
xmlSchemaTypePtr type,
15706
const xmlChar *value,
15707
xmlSchemaValPtr *val)
15712
* cos-valid-default:
15713
* Schema Component Constraint: Element Default Valid (Immediate)
15714
* For a string to be a valid default with respect to a type
15715
* definition the appropriate case among the following must be true:
15717
if WXS_IS_COMPLEX(type) {
15721
* SPEC (2.1) "its {content type} must be a simple type definition
15723
* SPEC (2.2.2) "If the {content type} is mixed, then the {content
15724
* type}'s particle must be ļæ½emptiableļæ½ as defined by
15725
* Particle Emptiable (ļæ½3.9.6)."
15727
if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
15728
((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
15729
/* NOTE that this covers (2.2.2) as well. */
15730
xmlSchemaPCustomErr(pctxt,
15731
XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
15732
WXS_BASIC_CAST type, type->node,
15733
"For a string to be a valid default, the type definition "
15734
"must be a simple type or a complex type with mixed content "
15735
"and a particle emptiable", NULL);
15736
return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
15740
* 1 If the type definition is a simple type definition, then the string
15741
* must be ļæ½validļæ½ with respect to that definition as defined by String
15742
* Valid (ļæ½3.14.4).
15746
* 2.2.1 If the {content type} is a simple type definition, then the
15747
* string must be ļæ½validļæ½ with respect to that simple type definition
15748
* as defined by String Valid (ļæ½3.14.4).
15750
if (WXS_IS_SIMPLE(type))
15751
ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15752
type, value, val, 1, 1, 0);
15753
else if (WXS_HAS_SIMPLE_CONTENT(type))
15754
ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15755
type->contentTypeDef, value, val, 1, 1, 0);
15760
PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
15761
"calling xmlSchemaVCheckCVCSimpleType()");
15768
* xmlSchemaCheckCTPropsCorrect:
15769
* @ctxt: the schema parser context
15770
* @type: the complex type definition
15772
*.(4.6) Constraints on Complex Type Definition Schema Components
15773
* Schema Component Constraint:
15774
* Complex Type Definition Properties Correct (ct-props-correct)
15775
* STATUS: (seems) complete
15777
* Returns 0 if the constraints are satisfied, a positive
15778
* error code if not and -1 if an internal error occured.
15781
xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
15782
xmlSchemaTypePtr type)
15785
* TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
15787
* SPEC (1) "The values of the properties of a complex type definition must
15788
* be as described in the property tableau in The Complex Type Definition
15789
* Schema Component (ļæ½3.4.1), modulo the impact of Missing
15790
* Sub-components (ļæ½5.3)."
15792
if ((type->baseType != NULL) &&
15793
(WXS_IS_SIMPLE(type->baseType)) &&
15794
(WXS_IS_EXTENSION(type) == 0)) {
15796
* SPEC (2) "If the {base type definition} is a simple type definition,
15797
* the {derivation method} must be extension."
15799
xmlSchemaCustomErr(ACTXT_CAST pctxt,
15800
XML_SCHEMAP_SRC_CT_1,
15801
NULL, WXS_BASIC_CAST type,
15802
"If the base type is a simple type, the derivation method must be "
15803
"'extension'", NULL, NULL);
15804
return (XML_SCHEMAP_SRC_CT_1);
15807
* SPEC (3) "Circular definitions are disallowed, except for the ļæ½ur-type
15808
* definitionļæ½. That is, it must be possible to reach the ļæ½ur-type
15809
* definition by repeatedly following the {base type definition}."
15811
* NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
15814
* NOTE that (4) and (5) need the following:
15815
* - attribute uses need to be already inherited (apply attr. prohibitions)
15816
* - attribute group references need to be expanded already
15817
* - simple types need to be typefixed already
15819
if (type->attrUses &&
15820
(((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
15822
xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
15823
xmlSchemaAttributeUsePtr use, tmp;
15824
int i, j, hasId = 0;
15826
for (i = uses->nbItems -1; i >= 0; i--) {
15827
use = uses->items[i];
15830
* SPEC ct-props-correct
15831
* (4) "Two distinct attribute declarations in the
15832
* {attribute uses} must not have identical {name}s and
15833
* {target namespace}s."
15836
for (j = i -1; j >= 0; j--) {
15837
tmp = uses->items[j];
15838
if ((WXS_ATTRUSE_DECL_NAME(use) ==
15839
WXS_ATTRUSE_DECL_NAME(tmp)) &&
15840
(WXS_ATTRUSE_DECL_TNS(use) ==
15841
WXS_ATTRUSE_DECL_TNS(tmp)))
15843
xmlChar *str = NULL;
15845
xmlSchemaCustomErr(ACTXT_CAST pctxt,
15846
XML_SCHEMAP_AG_PROPS_CORRECT,
15847
NULL, WXS_BASIC_CAST type,
15849
xmlSchemaGetComponentDesignation(&str, use),
15851
FREE_AND_NULL(str);
15853
* Remove the duplicate.
15855
if (xmlSchemaItemListRemove(uses, i) == -1)
15862
* SPEC ct-props-correct
15863
* (5) "Two distinct attribute declarations in the
15864
* {attribute uses} must not have {type definition}s which
15865
* are or are derived from ID."
15867
if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
15868
if (xmlSchemaIsDerivedFromBuiltInType(
15869
WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
15872
xmlChar *str = NULL;
15874
xmlSchemaCustomErr(ACTXT_CAST pctxt,
15875
XML_SCHEMAP_AG_PROPS_CORRECT,
15876
NULL, WXS_BASIC_CAST type,
15877
"There must not exist more than one attribute "
15878
"declaration of type 'xs:ID' "
15879
"(or derived from 'xs:ID'). The %s violates this "
15881
xmlSchemaGetComponentDesignation(&str, use),
15883
FREE_AND_NULL(str);
15884
if (xmlSchemaItemListRemove(uses, i) == -1)
15900
xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
15901
xmlSchemaTypePtr typeB)
15904
* TODO: This should implement component-identity
15907
if ((typeA == NULL) || (typeB == NULL))
15909
return (typeA == typeB);
15913
* xmlSchemaCheckCOSCTDerivedOK:
15914
* @ctxt: the schema parser context
15915
* @type: the to-be derived complex type definition
15916
* @baseType: the base complex type definition
15917
* @set: the given set
15919
* Schema Component Constraint:
15920
* Type Derivation OK (Complex) (cos-ct-derived-ok)
15922
* STATUS: completed
15924
* Returns 0 if the constraints are satisfied, or 1
15928
xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
15929
xmlSchemaTypePtr type,
15930
xmlSchemaTypePtr baseType,
15933
int equal = xmlSchemaAreEqualTypes(type, baseType);
15934
/* TODO: Error codes. */
15936
* SPEC "For a complex type definition (call it D, for derived)
15937
* to be validly derived from a type definition (call this
15938
* B, for base) given a subset of {extension, restriction}
15939
* all of the following must be true:"
15943
* SPEC (1) "If B and D are not the same type definition, then the
15944
* {derivation method} of D must not be in the subset."
15946
if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
15947
((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
15951
* SPEC (2.1) "B and D must be the same type definition."
15956
* SPEC (2.2) "B must be D's {base type definition}."
15958
if (type->baseType == baseType)
15961
* SPEC (2.3.1) "D's {base type definition} must not be the ļæ½ur-type
15964
if (WXS_IS_ANYTYPE(type->baseType))
15967
if (WXS_IS_COMPLEX(type->baseType)) {
15969
* SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
15970
* must be validly derived from B given the subset as defined by this
15973
return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
15977
* SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
15978
* must be validly derived from B given the subset as defined in Type
15979
* Derivation OK (Simple) (ļæ½3.14.6).
15981
return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
15987
* xmlSchemaCheckCOSDerivedOK:
15988
* @type: the derived simple type definition
15989
* @baseType: the base type definition
15992
* Type Derivation OK (Simple) AND Type Derivation OK (Complex)
15994
* Checks wheter @type can be validly derived from @baseType.
15996
* Returns 0 on success, an positive error code otherwise.
15999
xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16000
xmlSchemaTypePtr type,
16001
xmlSchemaTypePtr baseType,
16004
if (WXS_IS_SIMPLE(type))
16005
return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
16007
return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
16011
* xmlSchemaCheckCOSCTExtends:
16012
* @ctxt: the schema parser context
16013
* @type: the complex type definition
16015
* (3.4.6) Constraints on Complex Type Definition Schema Components
16016
* Schema Component Constraint:
16017
* Derivation Valid (Extension) (cos-ct-extends)
16022
* (1.4.3.2.2.2) "Particle Valid (Extension)"
16024
* Returns 0 if the constraints are satisfied, a positive
16025
* error code if not and -1 if an internal error occured.
16028
xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
16029
xmlSchemaTypePtr type)
16031
xmlSchemaTypePtr base = type->baseType;
16033
* TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16034
* temporarily only.
16037
* SPEC (1) "If the {base type definition} is a complex type definition,
16038
* then all of the following must be true:"
16040
if (WXS_IS_COMPLEX(base)) {
16042
* SPEC (1.1) "The {final} of the {base type definition} must not
16043
* contain extension."
16045
if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16046
xmlSchemaPCustomErr(ctxt,
16047
XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16048
WXS_BASIC_CAST type, NULL,
16049
"The 'final' of the base type definition "
16050
"contains 'extension'", NULL);
16051
return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16055
* ATTENTION: The constrains (1.2) and (1.3) are not applied,
16056
* since they are automatically satisfied through the
16057
* inheriting mechanism.
16058
* Note that even if redefining components, the inheriting mechanism
16063
* SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16065
* of the complex type definition itself, that is, for every attribute
16066
* use in the {attribute uses} of the {base type definition}, there
16067
* must be an attribute use in the {attribute uses} of the complex
16068
* type definition itself whose {attribute declaration} has the same
16069
* {name}, {target namespace} and {type definition} as its attribute
16072
if (base->attrUses != NULL) {
16074
xmlSchemaAttributeUsePtr use, buse;
16076
for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
16077
buse = (WXS_LIST_CAST base->attrUses)->items[i];
16079
if (type->attrUses != NULL) {
16080
use = (WXS_LIST_CAST type->attrUses)->items[j];
16081
for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
16083
if ((WXS_ATTRUSE_DECL_NAME(use) ==
16084
WXS_ATTRUSE_DECL_NAME(buse)) &&
16085
(WXS_ATTRUSE_DECL_TNS(use) ==
16086
WXS_ATTRUSE_DECL_TNS(buse)) &&
16087
(WXS_ATTRUSE_TYPEDEF(use) ==
16088
WXS_ATTRUSE_TYPEDEF(buse))
16096
xmlChar *str = NULL;
16098
xmlSchemaCustomErr(ACTXT_CAST ctxt,
16099
XML_SCHEMAP_COS_CT_EXTENDS_1_2,
16100
NULL, WXS_BASIC_CAST type,
16102
* TODO: The report does not indicate that also the
16103
* type needs to be the same.
16105
"This type is missing a matching correspondent "
16106
"for its {base type}'s %s in its {attribute uses}",
16107
xmlSchemaGetComponentDesignation(&str,
16115
* SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16116
* definition must also have one, and the base type definition's
16117
* {attribute wildcard}'s {namespace constraint} must be a subset
16118
* of the complex type definition's {attribute wildcard}'s {namespace
16119
* constraint}, as defined by Wildcard Subset (ļæ½3.10.6)."
16123
* MAYBE TODO: Enable if ever needed. But this will be needed only
16124
* if created the type via a schema construction API.
16126
if (base->attributeWildcard != NULL) {
16127
if (type->attributeWilcard == NULL) {
16128
xmlChar *str = NULL;
16130
xmlSchemaCustomErr(ACTXT_CAST pctxt,
16131
XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16133
"The base %s has an attribute wildcard, "
16134
"but this type is missing an attribute wildcard",
16135
xmlSchemaGetComponentDesignation(&str, base));
16138
} else if (xmlSchemaCheckCOSNSSubset(
16139
base->attributeWildcard, type->attributeWildcard))
16141
xmlChar *str = NULL;
16143
xmlSchemaCustomErr(ACTXT_CAST pctxt,
16144
XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16146
"The attribute wildcard is not a valid "
16147
"superset of the one in the base %s",
16148
xmlSchemaGetComponentDesignation(&str, base));
16154
* SPEC (1.4) "One of the following must be true:"
16156
if ((type->contentTypeDef != NULL) &&
16157
(type->contentTypeDef == base->contentTypeDef)) {
16159
* SPEC (1.4.1) "The {content type} of the {base type definition}
16160
* and the {content type} of the complex type definition itself
16161
* must be the same simple type definition"
16164
} else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
16165
(base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
16167
* SPEC (1.4.2) "The {content type} of both the {base type
16168
* definition} and the complex type definition itself must
16174
* SPEC (1.4.3) "All of the following must be true:"
16176
if (type->subtypes == NULL) {
16178
* SPEC 1.4.3.1 The {content type} of the complex type
16179
* definition itself must specify a particle.
16181
xmlSchemaPCustomErr(ctxt,
16182
XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16183
WXS_BASIC_CAST type, NULL,
16184
"The content type must specify a particle", NULL);
16185
return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16188
* SPEC (1.4.3.2) "One of the following must be true:"
16190
if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16192
* SPEC (1.4.3.2.1) "The {content type} of the {base type
16193
* definition} must be empty.
16198
* SPEC (1.4.3.2.2) "All of the following must be true:"
16200
if ((type->contentType != base->contentType) ||
16201
((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16202
(type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16204
* SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16205
* or both must be element-only."
16207
xmlSchemaPCustomErr(ctxt,
16208
XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16209
WXS_BASIC_CAST type, NULL,
16210
"The content type of both, the type and its base "
16211
"type, must either 'mixed' or 'element-only'", NULL);
16212
return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16215
* URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16216
* complex type definition must be a ļæ½valid extensionļæ½
16217
* of the {base type definition}'s particle, as defined
16218
* in Particle Valid (Extension) (ļæ½3.9.6)."
16220
* NOTE that we won't check "Particle Valid (Extension)",
16221
* since it is ensured by the derivation process in
16222
* xmlSchemaTypeFixup(). We need to implement this when heading
16223
* for a construction API
16224
* TODO: !! This is needed to be checked if redefining a type !!
16228
* URGENT TODO (1.5)
16233
* SPEC (2) "If the {base type definition} is a simple type definition,
16234
* then all of the following must be true:"
16236
if (type->contentTypeDef != base) {
16238
* SPEC (2.1) "The {content type} must be the same simple type
16241
xmlSchemaPCustomErr(ctxt,
16242
XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16243
WXS_BASIC_CAST type, NULL,
16244
"The content type must be the simple base type", NULL);
16245
return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16247
if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16249
* SPEC (2.2) "The {final} of the {base type definition} must not
16250
* contain extension"
16251
* NOTE that this is the same as (1.1).
16253
xmlSchemaPCustomErr(ctxt,
16254
XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16255
WXS_BASIC_CAST type, NULL,
16256
"The 'final' of the base type definition "
16257
"contains 'extension'", NULL);
16258
return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16265
* xmlSchemaCheckDerivationOKRestriction:
16266
* @ctxt: the schema parser context
16267
* @type: the complex type definition
16269
* (3.4.6) Constraints on Complex Type Definition Schema Components
16270
* Schema Component Constraint:
16271
* Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16278
* In XML Schema 1.1 this will be:
16279
* Validation Rule: Checking complex type subsumption
16281
* Returns 0 if the constraints are satisfied, a positive
16282
* error code if not and -1 if an internal error occured.
16285
xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16286
xmlSchemaTypePtr type)
16288
xmlSchemaTypePtr base;
16291
* TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16292
* temporarily only.
16294
base = type->baseType;
16295
if (! WXS_IS_COMPLEX(base)) {
16296
xmlSchemaCustomErr(ACTXT_CAST ctxt,
16297
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16298
type->node, WXS_BASIC_CAST type,
16299
"The base type must be a complex type", NULL, NULL);
16302
if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
16304
* SPEC (1) "The {base type definition} must be a complex type
16305
* definition whose {final} does not contain restriction."
16307
xmlSchemaCustomErr(ACTXT_CAST ctxt,
16308
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16309
type->node, WXS_BASIC_CAST type,
16310
"The 'final' of the base type definition "
16311
"contains 'restriction'", NULL, NULL);
16312
return (ctxt->err);
16315
* SPEC (2), (3) and (4)
16316
* Those are handled in a separate function, since the
16317
* same constraints are needed for redefinition of
16318
* attribute groups as well.
16320
if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16321
XML_SCHEMA_ACTION_DERIVE,
16322
WXS_BASIC_CAST type, WXS_BASIC_CAST base,
16323
type->attrUses, base->attrUses,
16324
type->attributeWildcard,
16325
base->attributeWildcard) == -1)
16330
* SPEC (5) "One of the following must be true:"
16332
if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16334
* SPEC (5.1) "The {base type definition} must be the
16335
* ļæ½ur-type definitionļæ½."
16338
} else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16339
(type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16341
* SPEC (5.2.1) "The {content type} of the complex type definition
16342
* must be a simple type definition"
16344
* SPEC (5.2.2) "One of the following must be true:"
16346
if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16347
(base->contentType == XML_SCHEMA_CONTENT_BASIC))
16351
* SPEC (5.2.2.1) "The {content type} of the {base type
16352
* definition} must be a simple type definition from which
16353
* the {content type} is validly derived given the empty
16354
* set as defined in Type Derivation OK (Simple) (ļæ½3.14.6)."
16356
* ATTENTION TODO: This seems not needed if the type implicitely
16357
* derived from the base type.
16360
err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
16361
type->contentTypeDef, base->contentTypeDef, 0);
16363
xmlChar *strA = NULL, *strB = NULL;
16367
xmlSchemaCustomErr(ACTXT_CAST ctxt,
16368
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16369
NULL, WXS_BASIC_CAST type,
16370
"The {content type} %s is not validly derived from the "
16371
"base type's {content type} %s",
16372
xmlSchemaGetComponentDesignation(&strA,
16373
type->contentTypeDef),
16374
xmlSchemaGetComponentDesignation(&strB,
16375
base->contentTypeDef));
16376
FREE_AND_NULL(strA);
16377
FREE_AND_NULL(strB);
16380
} else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16381
(xmlSchemaIsParticleEmptiable(
16382
(xmlSchemaParticlePtr) base->subtypes))) {
16384
* SPEC (5.2.2.2) "The {base type definition} must be mixed
16385
* and have a particle which is ļæ½emptiableļæ½ as defined in
16386
* Particle Emptiable (ļæ½3.9.6)."
16390
xmlSchemaPCustomErr(ctxt,
16391
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16392
WXS_BASIC_CAST type, NULL,
16393
"The content type of the base type must be either "
16394
"a simple type or 'mixed' and an emptiable particle", NULL);
16395
return (ctxt->err);
16397
} else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16399
* SPEC (5.3.1) "The {content type} of the complex type itself must
16402
if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16404
* SPEC (5.3.2.1) "The {content type} of the {base type
16405
* definition} must also be empty."
16408
} else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16409
(base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16410
xmlSchemaIsParticleEmptiable(
16411
(xmlSchemaParticlePtr) base->subtypes)) {
16413
* SPEC (5.3.2.2) "The {content type} of the {base type
16414
* definition} must be elementOnly or mixed and have a particle
16415
* which is ļæ½emptiableļæ½ as defined in Particle Emptiable (ļæ½3.9.6)."
16419
xmlSchemaPCustomErr(ctxt,
16420
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16421
WXS_BASIC_CAST type, NULL,
16422
"The content type of the base type must be either "
16423
"empty or 'mixed' (or 'elements-only') and an emptiable "
16425
return (ctxt->err);
16427
} else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16428
WXS_HAS_MIXED_CONTENT(type)) {
16430
* SPEC (5.4.1.1) "The {content type} of the complex type definition
16431
* itself must be element-only"
16433
if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
16435
* SPEC (5.4.1.2) "The {content type} of the complex type
16436
* definition itself and of the {base type definition} must be
16439
xmlSchemaPCustomErr(ctxt,
16440
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16441
WXS_BASIC_CAST type, NULL,
16442
"If the content type is 'mixed', then the content type of the "
16443
"base type must also be 'mixed'", NULL);
16444
return (ctxt->err);
16447
* SPEC (5.4.2) "The particle of the complex type definition itself
16448
* must be a ļæ½valid restrictionļæ½ of the particle of the {content
16449
* type} of the {base type definition} as defined in Particle Valid
16450
* (Restriction) (ļæ½3.9.6).
16452
* URGENT TODO: (5.4.2)
16455
xmlSchemaPCustomErr(ctxt,
16456
XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16457
WXS_BASIC_CAST type, NULL,
16458
"The type is not a valid restriction of its base type", NULL);
16459
return (ctxt->err);
16465
* xmlSchemaCheckCTComponent:
16466
* @ctxt: the schema parser context
16467
* @type: the complex type definition
16469
* (3.4.6) Constraints on Complex Type Definition Schema Components
16471
* Returns 0 if the constraints are satisfied, a positive
16472
* error code if not and -1 if an internal error occured.
16475
xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16476
xmlSchemaTypePtr type)
16480
* Complex Type Definition Properties Correct
16482
ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16485
if (WXS_IS_EXTENSION(type))
16486
ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16488
ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16493
* xmlSchemaCheckSRCCT:
16494
* @ctxt: the schema parser context
16495
* @type: the complex type definition
16497
* (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16498
* Schema Representation Constraint:
16499
* Complex Type Definition Representation OK (src-ct)
16501
* Returns 0 if the constraints are satisfied, a positive
16502
* error code if not and -1 if an internal error occured.
16505
xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16506
xmlSchemaTypePtr type)
16508
xmlSchemaTypePtr base;
16512
* TODO: Adjust the error codes here, as I used
16513
* XML_SCHEMAP_SRC_CT_1 only yet.
16515
base = type->baseType;
16516
if (! WXS_HAS_SIMPLE_CONTENT(type)) {
16518
* 1 If the <complexContent> alternative is chosen, the type definition
16519
* ļæ½resolvedļæ½ to by the ļæ½actual valueļæ½ of the base [attribute]
16520
* must be a complex type definition;
16522
if (! WXS_IS_COMPLEX(base)) {
16523
xmlChar *str = NULL;
16524
xmlSchemaPCustomErr(ctxt,
16525
XML_SCHEMAP_SRC_CT_1,
16526
WXS_BASIC_CAST type, type->node,
16527
"If using <complexContent>, the base type is expected to be "
16528
"a complex type. The base type '%s' is a simple type",
16529
xmlSchemaFormatQName(&str, base->targetNamespace,
16532
return (XML_SCHEMAP_SRC_CT_1);
16537
* 2 If the <simpleContent> alternative is chosen, all of the
16538
* following must be true:
16539
* 2.1 The type definition ļæ½resolvedļæ½ to by the ļæ½actual valueļæ½ of the
16540
* base [attribute] must be one of the following:
16542
if (WXS_IS_SIMPLE(base)) {
16543
if (WXS_IS_EXTENSION(type) == 0) {
16544
xmlChar *str = NULL;
16546
* 2.1.3 only if the <extension> alternative is also
16547
* chosen, a simple type definition.
16549
/* TODO: Change error code to ..._SRC_CT_2_1_3. */
16550
xmlSchemaPCustomErr(ctxt,
16551
XML_SCHEMAP_SRC_CT_1,
16552
WXS_BASIC_CAST type, NULL,
16553
"If using <simpleContent> and <restriction>, the base "
16554
"type must be a complex type. The base type '%s' is "
16556
xmlSchemaFormatQName(&str, base->targetNamespace,
16559
return (XML_SCHEMAP_SRC_CT_1);
16562
/* Base type is a complex type. */
16563
if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16564
(base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16566
* 2.1.1 a complex type definition whose {content type} is a
16567
* simple type definition;
16570
if (base->contentTypeDef == NULL) {
16571
xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16572
WXS_BASIC_CAST type, NULL,
16573
"Internal error: xmlSchemaCheckSRCCT, "
16574
"'%s', base type has no content type",
16578
} else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16579
(WXS_IS_RESTRICTION(type))) {
16582
* 2.1.2 only if the <restriction> alternative is also
16583
* chosen, a complex type definition whose {content type}
16584
* is mixed and a particle emptiable.
16586
if (! xmlSchemaIsParticleEmptiable(
16587
(xmlSchemaParticlePtr) base->subtypes)) {
16588
ret = XML_SCHEMAP_SRC_CT_1;
16591
* Attention: at this point the <simpleType> child is in
16592
* ->contentTypeDef (put there during parsing).
16594
if (type->contentTypeDef == NULL) {
16595
xmlChar *str = NULL;
16597
* 2.2 If clause 2.1.2 above is satisfied, then there
16598
* must be a <simpleType> among the [children] of
16601
/* TODO: Change error code to ..._SRC_CT_2_2. */
16602
xmlSchemaPCustomErr(ctxt,
16603
XML_SCHEMAP_SRC_CT_1,
16604
WXS_BASIC_CAST type, NULL,
16605
"A <simpleType> is expected among the children "
16606
"of <restriction>, if <simpleContent> is used and "
16607
"the base type '%s' is a complex type",
16608
xmlSchemaFormatQName(&str, base->targetNamespace,
16611
return (XML_SCHEMAP_SRC_CT_1);
16614
ret = XML_SCHEMAP_SRC_CT_1;
16618
xmlChar *str = NULL;
16619
if (WXS_IS_RESTRICTION(type)) {
16620
xmlSchemaPCustomErr(ctxt,
16621
XML_SCHEMAP_SRC_CT_1,
16622
WXS_BASIC_CAST type, NULL,
16623
"If <simpleContent> and <restriction> is used, the "
16624
"base type must be a simple type or a complex type with "
16625
"mixed content and particle emptiable. The base type "
16626
"'%s' is none of those",
16627
xmlSchemaFormatQName(&str, base->targetNamespace,
16630
xmlSchemaPCustomErr(ctxt,
16631
XML_SCHEMAP_SRC_CT_1,
16632
WXS_BASIC_CAST type, NULL,
16633
"If <simpleContent> and <extension> is used, the "
16634
"base type must be a simple type. The base type '%s' "
16635
"is a complex type",
16636
xmlSchemaFormatQName(&str, base->targetNamespace,
16643
* SPEC (3) "The corresponding complex type definition component must
16644
* satisfy the conditions set out in Constraints on Complex Type
16645
* Definition Schema Components (ļæ½3.4.6);"
16646
* NOTE (3) will be done in xmlSchemaTypeFixup().
16649
* SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16650
* above for {attribute wildcard} is satisfied, the intensional
16651
* intersection must be expressible, as defined in Attribute Wildcard
16652
* Intersection (ļæ½3.10.6).
16653
* NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16658
#ifdef ENABLE_PARTICLE_RESTRICTION
16660
* xmlSchemaCheckParticleRangeOK:
16661
* @ctxt: the schema parser context
16662
* @type: the complex type definition
16664
* (3.9.6) Constraints on Particle Schema Components
16665
* Schema Component Constraint:
16666
* Occurrence Range OK (range-ok)
16670
* Returns 0 if the constraints are satisfied, a positive
16671
* error code if not and -1 if an internal error occured.
16674
xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16675
int bmin, int bmax)
16679
if ((bmax != UNBOUNDED) &&
16686
* xmlSchemaCheckRCaseNameAndTypeOK:
16687
* @ctxt: the schema parser context
16688
* @r: the restricting element declaration particle
16689
* @b: the base element declaration particle
16691
* (3.9.6) Constraints on Particle Schema Components
16692
* Schema Component Constraint:
16693
* Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16694
* (rcase-NameAndTypeOK)
16700
* Returns 0 if the constraints are satisfied, a positive
16701
* error code if not and -1 if an internal error occured.
16704
xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16705
xmlSchemaParticlePtr r,
16706
xmlSchemaParticlePtr b)
16708
xmlSchemaElementPtr elemR, elemB;
16710
/* TODO: Error codes (rcase-NameAndTypeOK). */
16711
elemR = (xmlSchemaElementPtr) r->children;
16712
elemB = (xmlSchemaElementPtr) b->children;
16714
* SPEC (1) "The declarations' {name}s and {target namespace}s are
16717
if ((elemR != elemB) &&
16718
((! xmlStrEqual(elemR->name, elemB->name)) ||
16719
(! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16722
* SPEC (2) "R's occurrence range is a valid restriction of B's
16723
* occurrence range as defined by Occurrence Range OK (ļæ½3.9.6)."
16725
if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16726
b->minOccurs, b->maxOccurs) != 0)
16729
* SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16730
* {scope} are global."
16732
if (elemR == elemB)
16735
* SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16737
if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
16738
(elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
16741
* SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16742
* or is not fixed, or R's declaration's {value constraint} is fixed
16743
* with the same value."
16745
if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
16746
((elemR->value == NULL) ||
16747
((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
16748
/* TODO: Equality of the initial value or normalized or canonical? */
16749
(! xmlStrEqual(elemR->value, elemB->value))))
16752
* TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16753
* definitions} is a subset of B's declaration's {identity-constraint
16754
* definitions}, if any."
16756
if (elemB->idcs != NULL) {
16760
* SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16761
* superset of B's declaration's {disallowed substitutions}."
16763
if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
16764
((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
16765
((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
16766
((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
16767
((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
16768
((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
16771
* SPEC (3.2.5) "R's {type definition} is validly derived given
16772
* {extension, list, union} from B's {type definition}"
16774
* BADSPEC TODO: What's the point of adding "list" and "union" to the
16775
* set, if the corresponding constraints handle "restriction" and
16776
* "extension" only?
16782
set |= SUBSET_EXTENSION;
16783
set |= SUBSET_LIST;
16784
set |= SUBSET_UNION;
16785
if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
16786
elemB->subtypes, set) != 0)
16793
* xmlSchemaCheckRCaseNSCompat:
16794
* @ctxt: the schema parser context
16795
* @r: the restricting element declaration particle
16796
* @b: the base wildcard particle
16798
* (3.9.6) Constraints on Particle Schema Components
16799
* Schema Component Constraint:
16800
* Particle Derivation OK (Elt:Any -- NSCompat)
16805
* Returns 0 if the constraints are satisfied, a positive
16806
* error code if not and -1 if an internal error occured.
16809
xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
16810
xmlSchemaParticlePtr r,
16811
xmlSchemaParticlePtr b)
16813
/* TODO:Error codes (rcase-NSCompat). */
16815
* SPEC "For an element declaration particle to be a ļæ½valid restrictionļæ½
16816
* of a wildcard particle all of the following must be true:"
16818
* SPEC (1) "The element declaration's {target namespace} is ļæ½validļæ½
16819
* with respect to the wildcard's {namespace constraint} as defined by
16820
* Wildcard allows Namespace Name (ļæ½3.10.4)."
16822
if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
16823
((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
16826
* SPEC (2) "R's occurrence range is a valid restriction of B's
16827
* occurrence range as defined by Occurrence Range OK (ļæ½3.9.6)."
16829
if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16830
b->minOccurs, b->maxOccurs) != 0)
16837
* xmlSchemaCheckRCaseRecurseAsIfGroup:
16838
* @ctxt: the schema parser context
16839
* @r: the restricting element declaration particle
16840
* @b: the base model group particle
16842
* (3.9.6) Constraints on Particle Schema Components
16843
* Schema Component Constraint:
16844
* Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
16845
* (rcase-RecurseAsIfGroup)
16849
* Returns 0 if the constraints are satisfied, a positive
16850
* error code if not and -1 if an internal error occured.
16853
xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
16854
xmlSchemaParticlePtr r,
16855
xmlSchemaParticlePtr b)
16857
/* TODO: Error codes (rcase-RecurseAsIfGroup). */
16863
* xmlSchemaCheckRCaseNSSubset:
16864
* @ctxt: the schema parser context
16865
* @r: the restricting wildcard particle
16866
* @b: the base wildcard particle
16868
* (3.9.6) Constraints on Particle Schema Components
16869
* Schema Component Constraint:
16870
* Particle Derivation OK (Any:Any -- NSSubset)
16875
* Returns 0 if the constraints are satisfied, a positive
16876
* error code if not and -1 if an internal error occured.
16879
xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
16880
xmlSchemaParticlePtr r,
16881
xmlSchemaParticlePtr b,
16884
/* TODO: Error codes (rcase-NSSubset). */
16886
* SPEC (1) "R's occurrence range is a valid restriction of B's
16887
* occurrence range as defined by Occurrence Range OK (ļæ½3.9.6)."
16889
if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16890
b->minOccurs, b->maxOccurs))
16893
* SPEC (2) "R's {namespace constraint} must be an intensional subset
16894
* of B's {namespace constraint} as defined by Wildcard Subset (ļæ½3.10.6)."
16896
if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
16897
(xmlSchemaWildcardPtr) b->children))
16900
* SPEC (3) "Unless B is the content model wildcard of the ļæ½ur-type
16901
* definitionļæ½, R's {process contents} must be identical to or stronger
16902
* than B's {process contents}, where strict is stronger than lax is
16903
* stronger than skip."
16905
if (! isAnyTypeBase) {
16906
if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
16907
((xmlSchemaWildcardPtr) b->children)->processContents)
16915
* xmlSchemaCheckCOSParticleRestrict:
16916
* @ctxt: the schema parser context
16917
* @type: the complex type definition
16919
* (3.9.6) Constraints on Particle Schema Components
16920
* Schema Component Constraint:
16921
* Particle Valid (Restriction) (cos-particle-restrict)
16925
* Returns 0 if the constraints are satisfied, a positive
16926
* error code if not and -1 if an internal error occured.
16929
xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
16930
xmlSchemaParticlePtr r,
16931
xmlSchemaParticlePtr b)
16935
/*part = WXS_TYPE_PARTICLE(type);
16936
basePart = WXS_TYPE_PARTICLE(base);
16942
* SPEC (1) "They are the same particle."
16952
* xmlSchemaCheckRCaseNSRecurseCheckCardinality:
16953
* @ctxt: the schema parser context
16954
* @r: the model group particle
16955
* @b: the base wildcard particle
16957
* (3.9.6) Constraints on Particle Schema Components
16958
* Schema Component Constraint:
16959
* Particle Derivation OK (All/Choice/Sequence:Any --
16960
* NSRecurseCheckCardinality)
16961
* (rcase-NSRecurseCheckCardinality)
16963
* STATUS: TODO: subst-groups
16965
* Returns 0 if the constraints are satisfied, a positive
16966
* error code if not and -1 if an internal error occured.
16969
xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
16970
xmlSchemaParticlePtr r,
16971
xmlSchemaParticlePtr b)
16973
xmlSchemaParticlePtr part;
16974
/* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
16975
if ((r->children == NULL) || (r->children->children == NULL))
16978
* SPEC "For a group particle to be a ļæ½valid restrictionļæ½ of a
16979
* wildcard particle..."
16981
* SPEC (1) "Every member of the {particles} of the group is a ļæ½valid
16982
* restrictionļæ½ of the wildcard as defined by
16983
* Particle Valid (Restriction) (ļæ½3.9.6)."
16985
part = (xmlSchemaParticlePtr) r->children->children;
16987
if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
16989
part = (xmlSchemaParticlePtr) part->next;
16990
} while (part != NULL);
16992
* SPEC (2) "The effective total range of the group [...] is a
16993
* valid restriction of B's occurrence range as defined by
16994
* Occurrence Range OK (ļæ½3.9.6)."
16996
if (xmlSchemaCheckParticleRangeOK(
16997
xmlSchemaGetParticleTotalRangeMin(r),
16998
xmlSchemaGetParticleTotalRangeMax(r),
16999
b->minOccurs, b->maxOccurs) != 0)
17005
* xmlSchemaCheckRCaseRecurse:
17006
* @ctxt: the schema parser context
17007
* @r: the <all> or <sequence> model group particle
17008
* @b: the base <all> or <sequence> model group particle
17010
* (3.9.6) Constraints on Particle Schema Components
17011
* Schema Component Constraint:
17012
* Particle Derivation OK (All:All,Sequence:Sequence --
17017
* TODO: subst-groups
17019
* Returns 0 if the constraints are satisfied, a positive
17020
* error code if not and -1 if an internal error occured.
17023
xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
17024
xmlSchemaParticlePtr r,
17025
xmlSchemaParticlePtr b)
17027
/* xmlSchemaParticlePtr part; */
17028
/* TODO: Error codes (rcase-Recurse). */
17029
if ((r->children == NULL) || (b->children == NULL) ||
17030
(r->children->type != b->children->type))
17033
* SPEC "For an all or sequence group particle to be a ļæ½valid
17034
* restrictionļæ½ of another group particle with the same {compositor}..."
17036
* SPEC (1) "R's occurrence range is a valid restriction of B's
17037
* occurrence range as defined by Occurrence Range OK (ļæ½3.9.6)."
17039
if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17040
b->minOccurs, b->maxOccurs))
17049
#define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17050
xmlSchemaPCustomErrExt(pctxt, \
17051
XML_SCHEMAP_INVALID_FACET_VALUE, \
17052
WXS_BASIC_CAST fac1, fac1->node, \
17053
"It is an error for both '%s' and '%s' to be specified on the "\
17054
"same type definition", \
17055
BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17056
BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17058
#define FACET_RESTR_ERR(fac1, msg) \
17059
xmlSchemaPCustomErr(pctxt, \
17060
XML_SCHEMAP_INVALID_FACET_VALUE, \
17061
WXS_BASIC_CAST fac1, fac1->node, \
17064
#define FACET_RESTR_FIXED_ERR(fac) \
17065
xmlSchemaPCustomErr(pctxt, \
17066
XML_SCHEMAP_INVALID_FACET_VALUE, \
17067
WXS_BASIC_CAST fac, fac->node, \
17068
"The base type's facet is 'fixed', thus the value must not " \
17072
xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
17073
xmlSchemaFacetPtr facet1,
17074
xmlSchemaFacetPtr facet2,
17079
xmlChar *msg = NULL;
17081
msg = xmlStrdup(BAD_CAST "'");
17082
msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
17083
msg = xmlStrcat(msg, BAD_CAST "' has to be");
17084
if (lessGreater == 0)
17085
msg = xmlStrcat(msg, BAD_CAST " equal to");
17086
if (lessGreater == 1)
17087
msg = xmlStrcat(msg, BAD_CAST " greater than");
17089
msg = xmlStrcat(msg, BAD_CAST " less than");
17092
msg = xmlStrcat(msg, BAD_CAST " or equal to");
17093
msg = xmlStrcat(msg, BAD_CAST " '");
17094
msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
17096
msg = xmlStrcat(msg, BAD_CAST "' of the base type");
17098
msg = xmlStrcat(msg, BAD_CAST "'");
17100
xmlSchemaPCustomErr(pctxt,
17101
XML_SCHEMAP_INVALID_FACET_VALUE,
17102
WXS_BASIC_CAST facet1, NULL,
17103
(const char *) msg, NULL);
17110
* xmlSchemaDeriveAndValidateFacets:
17112
* Schema Component Constraint: Simple Type Restriction (Facets)
17113
* (st-restrict-facets)
17116
xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
17117
xmlSchemaTypePtr type)
17119
xmlSchemaTypePtr base = type->baseType;
17120
xmlSchemaFacetLinkPtr link, cur, last = NULL;
17121
xmlSchemaFacetPtr facet, bfacet,
17122
flength = NULL, ftotdig = NULL, ffracdig = NULL,
17123
fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
17124
fmininc = NULL, fmaxinc = NULL,
17125
fminexc = NULL, fmaxexc = NULL,
17126
bflength = NULL, bftotdig = NULL, bffracdig = NULL,
17127
bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
17128
bfmininc = NULL, bfmaxinc = NULL,
17129
bfminexc = NULL, bfmaxexc = NULL;
17130
int res; /* err = 0, fixedErr; */
17133
* SPEC st-restrict-facets 1:
17134
* "The {variety} of R is the same as that of B."
17137
* SPEC st-restrict-facets 2:
17138
* "If {variety} is atomic, the {primitive type definition}
17139
* of R is the same as that of B."
17141
* NOTE: we leave 1 & 2 out for now, since this will be
17142
* satisfied by the derivation process.
17143
* CONSTRUCTION TODO: Maybe needed if using a construction API.
17146
* SPEC st-restrict-facets 3:
17147
* "The {facets} of R are the union of S and the {facets}
17148
* of B, eliminating duplicates. To eliminate duplicates,
17149
* when a facet of the same kind occurs in both S and the
17150
* {facets} of B, the one in the {facets} of B is not
17151
* included, with the exception of enumeration and pattern
17152
* facets, for which multiple occurrences with distinct values
17156
if ((type->facetSet == NULL) && (base->facetSet == NULL))
17159
last = type->facetSet;
17161
while (last->next != NULL)
17164
for (cur = type->facetSet; cur != NULL; cur = cur->next) {
17165
facet = cur->facet;
17166
switch (facet->type) {
17167
case XML_SCHEMA_FACET_LENGTH:
17168
flength = facet; break;
17169
case XML_SCHEMA_FACET_MINLENGTH:
17170
fminlen = facet; break;
17171
case XML_SCHEMA_FACET_MININCLUSIVE:
17172
fmininc = facet; break;
17173
case XML_SCHEMA_FACET_MINEXCLUSIVE:
17174
fminexc = facet; break;
17175
case XML_SCHEMA_FACET_MAXLENGTH:
17176
fmaxlen = facet; break;
17177
case XML_SCHEMA_FACET_MAXINCLUSIVE:
17178
fmaxinc = facet; break;
17179
case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17180
fmaxexc = facet; break;
17181
case XML_SCHEMA_FACET_TOTALDIGITS:
17182
ftotdig = facet; break;
17183
case XML_SCHEMA_FACET_FRACTIONDIGITS:
17184
ffracdig = facet; break;
17189
for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17190
facet = cur->facet;
17191
switch (facet->type) {
17192
case XML_SCHEMA_FACET_LENGTH:
17193
bflength = facet; break;
17194
case XML_SCHEMA_FACET_MINLENGTH:
17195
bfminlen = facet; break;
17196
case XML_SCHEMA_FACET_MININCLUSIVE:
17197
bfmininc = facet; break;
17198
case XML_SCHEMA_FACET_MINEXCLUSIVE:
17199
bfminexc = facet; break;
17200
case XML_SCHEMA_FACET_MAXLENGTH:
17201
bfmaxlen = facet; break;
17202
case XML_SCHEMA_FACET_MAXINCLUSIVE:
17203
bfmaxinc = facet; break;
17204
case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17205
bfmaxexc = facet; break;
17206
case XML_SCHEMA_FACET_TOTALDIGITS:
17207
bftotdig = facet; break;
17208
case XML_SCHEMA_FACET_FRACTIONDIGITS:
17209
bffracdig = facet; break;
17215
* length and minLength or maxLength (2.2) + (3.2)
17217
if (flength && (fminlen || fmaxlen)) {
17218
FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
17219
"either of 'minLength' or 'maxLength' to be specified on "
17220
"the same type definition")
17223
* Mutual exclusions in the same derivation step.
17225
if ((fmaxinc) && (fmaxexc)) {
17227
* SCC "maxInclusive and maxExclusive"
17229
FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
17231
if ((fmininc) && (fminexc)) {
17233
* SCC "minInclusive and minExclusive"
17235
FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
17238
if (flength && bflength) {
17240
* SCC "length valid restriction"
17241
* The values have to be equal.
17243
res = xmlSchemaCompareValues(flength->val, bflength->val);
17245
goto internal_error;
17247
xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17248
if ((res != 0) && (bflength->fixed)) {
17249
FACET_RESTR_FIXED_ERR(flength)
17253
if (fminlen && bfminlen) {
17255
* SCC "minLength valid restriction"
17256
* minLength >= BASE minLength
17258
res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17260
goto internal_error;
17262
xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17263
if ((res != 0) && (bfminlen->fixed)) {
17264
FACET_RESTR_FIXED_ERR(fminlen)
17267
if (fmaxlen && bfmaxlen) {
17269
* SCC "maxLength valid restriction"
17270
* maxLength <= BASE minLength
17272
res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17274
goto internal_error;
17276
xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17277
if ((res != 0) && (bfmaxlen->fixed)) {
17278
FACET_RESTR_FIXED_ERR(fmaxlen)
17282
* SCC "length and minLength or maxLength"
17285
flength = bflength;
17288
flength = bflength;
17290
/* (1.1) length >= minLength */
17291
res = xmlSchemaCompareValues(flength->val, fminlen->val);
17293
goto internal_error;
17295
xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17298
fmaxlen = bfmaxlen;
17300
/* (2.1) length <= maxLength */
17301
res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17303
goto internal_error;
17305
xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17313
/* SCC "maxInclusive >= minInclusive" */
17314
res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17316
goto internal_error;
17318
xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17322
* SCC "maxInclusive valid restriction"
17325
/* maxInclusive <= BASE maxInclusive */
17326
res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17328
goto internal_error;
17330
xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17331
if ((res != 0) && (bfmaxinc->fixed)) {
17332
FACET_RESTR_FIXED_ERR(fmaxinc)
17336
/* maxInclusive < BASE maxExclusive */
17337
res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17339
goto internal_error;
17341
xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17345
/* maxInclusive >= BASE minInclusive */
17346
res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17348
goto internal_error;
17350
xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17354
/* maxInclusive > BASE minExclusive */
17355
res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17357
goto internal_error;
17359
xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17365
* "maxExclusive >= minExclusive"
17368
res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17370
goto internal_error;
17372
xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17376
* "maxExclusive valid restriction"
17379
/* maxExclusive <= BASE maxExclusive */
17380
res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17382
goto internal_error;
17384
xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17386
if ((res != 0) && (bfmaxexc->fixed)) {
17387
FACET_RESTR_FIXED_ERR(fmaxexc)
17391
/* maxExclusive <= BASE maxInclusive */
17392
res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17394
goto internal_error;
17396
xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17400
/* maxExclusive > BASE minInclusive */
17401
res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17403
goto internal_error;
17405
xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17409
/* maxExclusive > BASE minExclusive */
17410
res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17412
goto internal_error;
17414
xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17420
* "minExclusive < maxInclusive"
17423
res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17425
goto internal_error;
17427
xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17431
* "minExclusive valid restriction"
17434
/* minExclusive >= BASE minExclusive */
17435
res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17437
goto internal_error;
17439
xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17441
if ((res != 0) && (bfminexc->fixed)) {
17442
FACET_RESTR_FIXED_ERR(fminexc)
17446
/* minExclusive <= BASE maxInclusive */
17447
res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17449
goto internal_error;
17451
xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17455
/* minExclusive >= BASE minInclusive */
17456
res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17458
goto internal_error;
17460
xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17464
/* minExclusive < BASE maxExclusive */
17465
res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17467
goto internal_error;
17469
xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17475
* "minInclusive < maxExclusive"
17478
res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17480
goto internal_error;
17482
xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17486
* "minExclusive valid restriction"
17489
/* minInclusive >= BASE minInclusive */
17490
res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17492
goto internal_error;
17494
xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17496
if ((res != 0) && (bfmininc->fixed)) {
17497
FACET_RESTR_FIXED_ERR(fmininc)
17501
/* minInclusive <= BASE maxInclusive */
17502
res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17504
goto internal_error;
17506
xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17510
/* minInclusive > BASE minExclusive */
17511
res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17513
goto internal_error;
17515
xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17518
/* minInclusive < BASE maxExclusive */
17519
res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17521
goto internal_error;
17523
xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17526
if (ftotdig && bftotdig) {
17528
* SCC " totalDigits valid restriction"
17529
* totalDigits <= BASE totalDigits
17531
res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17533
goto internal_error;
17535
xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17537
if ((res != 0) && (bftotdig->fixed)) {
17538
FACET_RESTR_FIXED_ERR(ftotdig)
17541
if (ffracdig && bffracdig) {
17543
* SCC "fractionDigits valid restriction"
17544
* fractionDigits <= BASE fractionDigits
17546
res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17548
goto internal_error;
17550
xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17552
if ((res != 0) && (bffracdig->fixed)) {
17553
FACET_RESTR_FIXED_ERR(ffracdig)
17557
* SCC "fractionDigits less than or equal to totalDigits"
17560
ftotdig = bftotdig;
17562
ffracdig = bffracdig;
17563
if (ftotdig && ffracdig) {
17564
res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17566
goto internal_error;
17568
xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17572
* *Enumerations* won' be added here, since only the first set
17573
* of enumerations in the ancestor-or-self axis is used
17574
* for validation, plus we need to use the base type of those
17575
* enumerations for whitespace.
17577
* *Patterns*: won't be add here, since they are ORed at
17578
* type level and ANDed at ancestor level. This will
17579
* happed during validation by walking the base axis
17582
for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17583
bfacet = cur->facet;
17585
* Special handling of enumerations and patterns.
17586
* TODO: hmm, they should not appear in the set, so remove this.
17588
if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17589
(bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17592
* Search for a duplicate facet in the current type.
17594
link = type->facetSet;
17596
/* fixedErr = 0; */
17597
while (link != NULL) {
17598
facet = link->facet;
17599
if (facet->type == bfacet->type) {
17600
switch (facet->type) {
17601
case XML_SCHEMA_FACET_WHITESPACE:
17603
* The whitespace must be stronger.
17605
if (facet->whitespace < bfacet->whitespace) {
17606
FACET_RESTR_ERR(flength,
17607
"The 'whitespace' value has to be equal to "
17608
"or stronger than the 'whitespace' value of "
17611
if ((bfacet->fixed) &&
17612
(facet->whitespace != bfacet->whitespace)) {
17613
FACET_RESTR_FIXED_ERR(facet)
17619
/* Duplicate found. */
17625
* If no duplicate was found: add the base types's facet
17628
if (link == NULL) {
17629
link = (xmlSchemaFacetLinkPtr)
17630
xmlMalloc(sizeof(xmlSchemaFacetLink));
17631
if (link == NULL) {
17632
xmlSchemaPErrMemory(pctxt,
17633
"deriving facets, creating a facet link", NULL);
17636
link->facet = cur->facet;
17639
type->facetSet = link;
17649
PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17650
"an error occured");
17655
xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17656
xmlSchemaTypePtr type)
17658
xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17660
* The actual value is then formed by replacing any union type
17661
* definition in the ļæ½explicit membersļæ½ with the members of their
17662
* {member type definitions}, in order.
17664
* TODO: There's a bug entry at
17665
* "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17666
* which indicates that we'll keep the union types the future.
17668
link = type->memberTypes;
17669
while (link != NULL) {
17671
if (WXS_IS_TYPE_NOT_FIXED(link->type))
17672
xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
17674
if (WXS_IS_UNION(link->type)) {
17675
subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17676
if (subLink != NULL) {
17677
link->type = subLink->type;
17678
if (subLink->next != NULL) {
17679
lastLink = link->next;
17680
subLink = subLink->next;
17682
while (subLink != NULL) {
17683
newLink = (xmlSchemaTypeLinkPtr)
17684
xmlMalloc(sizeof(xmlSchemaTypeLink));
17685
if (newLink == NULL) {
17686
xmlSchemaPErrMemory(pctxt, "allocating a type link",
17690
newLink->type = subLink->type;
17691
prevLink->next = newLink;
17692
prevLink = newLink;
17693
newLink->next = lastLink;
17695
subLink = subLink->next;
17706
xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17708
int has = 0, needVal = 0, normVal = 0;
17710
has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
17712
needVal = (type->baseType->flags &
17713
XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
17714
normVal = (type->baseType->flags &
17715
XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
17717
if (type->facets != NULL) {
17718
xmlSchemaFacetPtr fac;
17720
for (fac = type->facets; fac != NULL; fac = fac->next) {
17721
switch (fac->type) {
17722
case XML_SCHEMA_FACET_WHITESPACE:
17724
case XML_SCHEMA_FACET_PATTERN:
17728
case XML_SCHEMA_FACET_ENUMERATION:
17740
type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
17742
type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17744
type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
17746
if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
17747
xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17749
* OPTIMIZE VAL TODO: Some facets need a computed value.
17751
if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
17752
(prim->builtInType != XML_SCHEMAS_STRING)) {
17753
type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17759
xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
17764
* Evaluate the whitespace-facet value.
17766
if (WXS_IS_LIST(type)) {
17767
type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17769
} else if (WXS_IS_UNION(type))
17772
if (type->facetSet != NULL) {
17773
xmlSchemaFacetLinkPtr lin;
17775
for (lin = type->facetSet; lin != NULL; lin = lin->next) {
17776
if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
17777
switch (lin->facet->whitespace) {
17778
case XML_SCHEMAS_FACET_PRESERVE:
17779
type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17781
case XML_SCHEMAS_FACET_REPLACE:
17782
type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17784
case XML_SCHEMAS_FACET_COLLAPSE:
17785
type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17795
* For all ļæ½atomicļæ½ datatypes other than string (and types ļæ½derivedļæ½
17796
* by ļæ½restrictionļæ½ from it) the value of whiteSpace is fixed to
17800
xmlSchemaTypePtr anc;
17802
for (anc = type->baseType; anc != NULL &&
17803
anc->builtInType != XML_SCHEMAS_ANYTYPE;
17804
anc = anc->baseType) {
17806
if (anc->type == XML_SCHEMA_TYPE_BASIC) {
17807
if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
17808
type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17810
} else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
17811
(anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
17812
type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17815
type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17824
xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
17825
xmlSchemaTypePtr type)
17827
if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17829
if (! WXS_IS_TYPE_NOT_FIXED_1(type))
17831
type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
17833
if (WXS_IS_LIST(type)) {
17835
* Corresponds to <simpleType><list>...
17837
if (type->subtypes == NULL) {
17839
* This one is really needed, so get out.
17841
PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17842
"list type has no item-type assigned");
17845
} else if (WXS_IS_UNION(type)) {
17847
* Corresponds to <simpleType><union>...
17849
if (type->memberTypes == NULL) {
17851
* This one is really needed, so get out.
17853
PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17854
"union type has no member-types assigned");
17859
* Corresponds to <simpleType><restriction>...
17861
if (type->baseType == NULL) {
17862
PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17863
"type has no base-type assigned");
17866
if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
17867
if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
17871
* If the <restriction> alternative is chosen, then the
17872
* {variety} of the {base type definition}.
17874
if (WXS_IS_ATOMIC(type->baseType))
17875
type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
17876
else if (WXS_IS_LIST(type->baseType)) {
17877
type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
17879
* Inherit the itemType.
17881
type->subtypes = type->baseType->subtypes;
17882
} else if (WXS_IS_UNION(type->baseType)) {
17883
type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
17885
* NOTE that we won't assign the memberTypes of the base,
17886
* since this will make trouble when freeing them; we will
17887
* use a lookup function to access them instead.
17896
xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
17897
xmlSchemaTypePtr type)
17899
if (type->node != NULL) {
17900
xmlGenericError(xmlGenericErrorContext,
17901
"Type of %s : %s:%d :", name,
17902
type->node->doc->URL,
17903
xmlGetLineNo(type->node));
17905
xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
17907
if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
17908
switch (type->contentType) {
17909
case XML_SCHEMA_CONTENT_SIMPLE:
17910
xmlGenericError(xmlGenericErrorContext, "simple\n");
17912
case XML_SCHEMA_CONTENT_ELEMENTS:
17913
xmlGenericError(xmlGenericErrorContext, "elements\n");
17915
case XML_SCHEMA_CONTENT_UNKNOWN:
17916
xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
17918
case XML_SCHEMA_CONTENT_EMPTY:
17919
xmlGenericError(xmlGenericErrorContext, "empty\n");
17921
case XML_SCHEMA_CONTENT_MIXED:
17922
if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
17924
xmlGenericError(xmlGenericErrorContext,
17925
"mixed as emptiable particle\n");
17927
xmlGenericError(xmlGenericErrorContext, "mixed\n");
17929
/* Removed, since not used. */
17931
case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
17932
xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
17935
case XML_SCHEMA_CONTENT_BASIC:
17936
xmlGenericError(xmlGenericErrorContext, "basic\n");
17939
xmlGenericError(xmlGenericErrorContext,
17940
"not registered !!!\n");
17948
* 3.14.6 Constraints on Simple Type Definition Schema Components
17951
xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
17952
xmlSchemaTypePtr type)
17954
int res, olderrs = pctxt->nberrors;
17956
if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17959
if (! WXS_IS_TYPE_NOT_FIXED(type))
17962
type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
17963
type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
17965
if (type->baseType == NULL) {
17966
PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
17967
"missing baseType");
17970
if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
17971
xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
17973
* If a member type of a union is a union itself, we need to substitute
17974
* that member type for its member types.
17975
* NOTE that this might change in WXS 1.1; i.e. we will keep the union
17976
* types in WXS 1.1.
17978
if ((type->memberTypes != NULL) &&
17979
(xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
17982
* SPEC src-simple-type 1
17983
* "The corresponding simple type definition, if any, must satisfy
17984
* the conditions set out in Constraints on Simple Type Definition
17985
* Schema Components (ļæ½3.14.6)."
17988
* Schema Component Constraint: Simple Type Definition Properties Correct
17989
* (st-props-correct)
17991
res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
17994
* Schema Component Constraint: Derivation Valid (Restriction, Simple)
17995
* (cos-st-restricts)
17997
res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
18000
* TODO: Removed the error report, since it got annoying to get an
18001
* extra error report, if anything failed until now.
18002
* Enable this if needed.
18004
* xmlSchemaPErr(ctxt, type->node,
18005
* XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18006
* "Simple type '%s' does not satisfy the constraints "
18007
* "on simple type definitions.\n",
18008
* type->name, NULL);
18011
* Schema Component Constraint: Simple Type Restriction (Facets)
18012
* (st-restrict-facets)
18014
res = xmlSchemaCheckFacetValues(type, pctxt);
18016
if ((type->facetSet != NULL) ||
18017
(type->baseType->facetSet != NULL)) {
18018
res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
18022
* Whitespace value.
18024
res = xmlSchemaTypeFixupWhitespace(type);
18026
xmlSchemaTypeFixupOptimFacets(type);
18030
xmlSchemaDebugFixedType(pctxt, type);
18032
if (olderrs != pctxt->nberrors)
18033
return(pctxt->err);
18038
xmlSchemaDebugFixedType(pctxt, type);
18044
xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
18045
xmlSchemaTypePtr type)
18047
int res = 0, olderrs = pctxt->nberrors;
18048
xmlSchemaTypePtr baseType = type->baseType;
18050
if (! WXS_IS_TYPE_NOT_FIXED(type))
18052
type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18053
if (baseType == NULL) {
18054
PERROR_INT("xmlSchemaFixupComplexType",
18055
"missing baseType");
18059
* Fixup the base type.
18061
if (WXS_IS_TYPE_NOT_FIXED(baseType))
18062
xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
18063
if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
18065
* Skip fixup if the base type is invalid.
18066
* TODO: Generate a warning!
18071
* This basically checks if the base type can be derived.
18073
res = xmlSchemaCheckSRCCT(pctxt, type);
18076
* Fixup the content type.
18078
if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
18080
* Corresponds to <complexType><simpleContent>...
18082
if ((WXS_IS_COMPLEX(baseType)) &&
18083
(baseType->contentTypeDef != NULL) &&
18084
(WXS_IS_RESTRICTION(type))) {
18085
xmlSchemaTypePtr contentBase, content;
18086
#ifdef ENABLE_NAMED_LOCALS
18088
const xmlChar *tmpname;
18091
* SPEC (1) If <restriction> + base type is <complexType>,
18092
* "whose own {content type} is a simple type..."
18094
if (type->contentTypeDef != NULL) {
18096
* SPEC (1.1) "the simple type definition corresponding to the
18097
* <simpleType> among the [children] of <restriction> if there
18099
* Note that this "<simpleType> among the [children]" was put
18100
* into ->contentTypeDef during parsing.
18102
contentBase = type->contentTypeDef;
18103
type->contentTypeDef = NULL;
18106
* (1.2) "...otherwise (<restriction> has no <simpleType>
18107
* among its [children]), the simple type definition which
18108
* is the {content type} of the ... base type."
18110
contentBase = baseType->contentTypeDef;
18114
* "... a simple type definition which restricts the simple
18115
* type definition identified in clause 1.1 or clause 1.2
18116
* with a set of facet components"
18118
* Create the anonymous simple type, which will be the content
18119
* type of the complex type.
18121
#ifdef ENABLE_NAMED_LOCALS
18122
snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
18123
tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
18124
content = xmlSchemaAddType(pctxt, pctxt->schema,
18125
XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
18128
content = xmlSchemaAddType(pctxt, pctxt->schema,
18129
XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
18132
if (content == NULL)
18135
* We will use the same node as for the <complexType>
18136
* to have it somehow anchored in the schema doc.
18138
content->type = XML_SCHEMA_TYPE_SIMPLE;
18139
content->baseType = contentBase;
18141
* Move the facets, previously anchored on the
18142
* complexType during parsing.
18144
content->facets = type->facets;
18145
type->facets = NULL;
18146
content->facetSet = type->facetSet;
18147
type->facetSet = NULL;
18149
type->contentTypeDef = content;
18150
if (WXS_IS_TYPE_NOT_FIXED(contentBase))
18151
xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
18153
* Fixup the newly created type. We don't need to check
18154
* for circularity here.
18156
res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
18158
res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
18161
} else if ((WXS_IS_COMPLEX(baseType)) &&
18162
(baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
18163
(WXS_IS_RESTRICTION(type))) {
18165
* SPEC (2) If <restriction> + base is a mixed <complexType> with
18166
* an emptiable particle, then a simple type definition which
18167
* restricts the <restriction>'s <simpleType> child.
18169
if ((type->contentTypeDef == NULL) ||
18170
(type->contentTypeDef->baseType == NULL)) {
18172
* TODO: Check if this ever happens.
18174
xmlSchemaPCustomErr(pctxt,
18175
XML_SCHEMAP_INTERNAL,
18176
WXS_BASIC_CAST type, NULL,
18177
"Internal error: xmlSchemaTypeFixup, "
18178
"complex type '%s': the <simpleContent><restriction> "
18179
"is missing a <simpleType> child, but was not catched "
18180
"by xmlSchemaCheckSRCCT()", type->name);
18183
} else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
18185
* SPEC (3) If <extension> + base is <complexType> with
18186
* <simpleType> content, "...then the {content type} of that
18187
* complex type definition"
18189
if (baseType->contentTypeDef == NULL) {
18191
* TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18192
* should have catched this already.
18194
xmlSchemaPCustomErr(pctxt,
18195
XML_SCHEMAP_INTERNAL,
18196
WXS_BASIC_CAST type, NULL,
18197
"Internal error: xmlSchemaTypeFixup, "
18198
"complex type '%s': the <extension>ed base type is "
18199
"a complex type with no simple content type",
18203
type->contentTypeDef = baseType->contentTypeDef;
18204
} else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
18206
* SPEC (4) <extension> + base is <simpleType>
18207
* "... then that simple type definition"
18209
type->contentTypeDef = baseType;
18212
* TODO: Check if this ever happens.
18214
xmlSchemaPCustomErr(pctxt,
18215
XML_SCHEMAP_INTERNAL,
18216
WXS_BASIC_CAST type, NULL,
18217
"Internal error: xmlSchemaTypeFixup, "
18218
"complex type '%s' with <simpleContent>: unhandled "
18219
"derivation case", type->name);
18223
int dummySequence = 0;
18224
xmlSchemaParticlePtr particle =
18225
(xmlSchemaParticlePtr) type->subtypes;
18227
* Corresponds to <complexType><complexContent>...
18229
* NOTE that the effective mixed was already set during parsing of
18230
* <complexType> and <complexContent>; its flag value is
18231
* XML_SCHEMAS_TYPE_MIXED.
18233
* Compute the "effective content":
18234
* (2.1.1) + (2.1.2) + (2.1.3)
18236
if ((particle == NULL) ||
18237
((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
18238
((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
18239
(particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
18240
((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
18241
(particle->minOccurs == 0))) &&
18242
( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
18243
if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
18245
* SPEC (2.1.4) "If the ļæ½effective mixedļæ½ is true, then
18246
* a particle whose properties are as follows:..."
18248
* Empty sequence model group with
18249
* minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18250
* NOTE that we sill assign it the <complexType> node to
18251
* somehow anchor it in the doc.
18253
if ((particle == NULL) ||
18254
(particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
18256
* Create the particle.
18258
particle = xmlSchemaAddParticle(pctxt,
18260
if (particle == NULL)
18263
* Create the model group.
18264
*/ /* URGENT TODO: avoid adding to pending items. */
18265
particle->children = (xmlSchemaTreeItemPtr)
18266
xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18267
XML_SCHEMA_TYPE_SEQUENCE, type->node);
18268
if (particle->children == NULL)
18271
type->subtypes = (xmlSchemaTypePtr) particle;
18274
type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18277
* SPEC (2.1.5) "otherwise empty"
18279
type->contentType = XML_SCHEMA_CONTENT_EMPTY;
18283
* SPEC (2.2) "otherwise the particle corresponding to the
18284
* <all>, <choice>, <group> or <sequence> among the
18287
type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18290
* Compute the "content type".
18292
if (WXS_IS_RESTRICTION(type)) {
18294
* SPEC (3.1) "If <restriction>..."
18295
* (3.1.1) + (3.1.2) */
18296
if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18297
if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18298
type->contentType = XML_SCHEMA_CONTENT_MIXED;
18302
* SPEC (3.2) "If <extension>..."
18304
if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18307
* "If the ļæ½effective contentļæ½ is empty, then the
18308
* {content type} of the [...] base ..."
18310
type->contentType = baseType->contentType;
18311
type->subtypes = baseType->subtypes;
18313
* Fixes bug #347316:
18314
* This is the case when the base type has a simple
18315
* type definition as content.
18317
type->contentTypeDef = baseType->contentTypeDef;
18319
* NOTE that the effective mixed is ignored here.
18321
} else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18325
if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18326
type->contentType = XML_SCHEMA_CONTENT_MIXED;
18331
if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18332
type->contentType = XML_SCHEMA_CONTENT_MIXED;
18334
* "A model group whose {compositor} is sequence and whose
18335
* {particles} are..."
18337
if ((WXS_TYPE_PARTICLE(type) != NULL) &&
18338
(WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
18339
((WXS_TYPE_PARTICLE_TERM(type))->type ==
18340
XML_SCHEMA_TYPE_ALL))
18343
* SPEC cos-all-limited (1)
18345
xmlSchemaCustomErr(ACTXT_CAST pctxt,
18346
/* TODO: error code */
18347
XML_SCHEMAP_COS_ALL_LIMITED,
18348
WXS_ITEM_NODE(type), NULL,
18349
"The type has an 'all' model group in its "
18350
"{content type} and thus cannot be derived from "
18351
"a non-empty type, since this would produce a "
18352
"'sequence' model group containing the 'all' "
18353
"model group; 'all' model groups are not "
18354
"allowed to appear inside other model groups",
18357
} else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
18358
(WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
18359
((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
18360
XML_SCHEMA_TYPE_ALL))
18363
* SPEC cos-all-limited (1)
18365
xmlSchemaCustomErr(ACTXT_CAST pctxt,
18366
/* TODO: error code */
18367
XML_SCHEMAP_COS_ALL_LIMITED,
18368
WXS_ITEM_NODE(type), NULL,
18369
"A type cannot be derived by extension from a type "
18370
"which has an 'all' model group in its "
18371
"{content type}, since this would produce a "
18372
"'sequence' model group containing the 'all' "
18373
"model group; 'all' model groups are not "
18374
"allowed to appear inside other model groups",
18377
} else if (! dummySequence) {
18378
xmlSchemaTreeItemPtr effectiveContent =
18379
(xmlSchemaTreeItemPtr) type->subtypes;
18381
* Create the particle.
18383
particle = xmlSchemaAddParticle(pctxt,
18385
if (particle == NULL)
18388
* Create the "sequence" model group.
18390
particle->children = (xmlSchemaTreeItemPtr)
18391
xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18392
XML_SCHEMA_TYPE_SEQUENCE, type->node);
18393
if (particle->children == NULL)
18395
WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
18397
* SPEC "the particle of the {content type} of
18398
* the ... base ..."
18399
* Create a duplicate of the base type's particle
18400
* and assign its "term" to it.
18402
particle->children->children =
18403
(xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18405
((xmlSchemaParticlePtr) type->subtypes)->minOccurs,
18406
((xmlSchemaParticlePtr) type->subtypes)->maxOccurs);
18407
if (particle->children->children == NULL)
18409
particle = (xmlSchemaParticlePtr)
18410
particle->children->children;
18411
particle->children =
18412
((xmlSchemaParticlePtr) baseType->subtypes)->children;
18414
* SPEC "followed by the ļæ½effective contentļæ½."
18416
particle->next = effectiveContent;
18418
* This all will result in:
18420
* --> new-sequence(
18429
* This is the case when there is already an empty
18430
* <sequence> with minOccurs==maxOccurs==1.
18431
* Just add the base types's content type.
18432
* NOTE that, although we miss to add an intermediate
18433
* <sequence>, this should produce no difference to
18434
* neither the regex compilation of the content model,
18435
* nor to the complex type contraints.
18437
particle->children->children =
18438
(xmlSchemaTreeItemPtr) baseType->subtypes;
18444
* Now fixup attribute uses:
18445
* - expand attr. group references
18446
* - intersect attribute wildcards
18447
* - inherit attribute uses of the base type
18448
* - inherit or union attr. wildcards if extending
18449
* - apply attr. use prohibitions if restricting
18451
res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18454
* Apply the complex type component constraints; this will not
18455
* check attributes, since this is done in
18456
* xmlSchemaFixupTypeAttributeUses().
18458
res = xmlSchemaCheckCTComponent(pctxt, type);
18462
xmlSchemaDebugFixedType(pctxt, type);
18464
if (olderrs != pctxt->nberrors)
18465
return(pctxt->err);
18470
type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18472
xmlSchemaDebugFixedType(pctxt, type);
18474
return(pctxt->err);
18477
type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18479
xmlSchemaDebugFixedType(pctxt, type);
18486
* xmlSchemaTypeFixup:
18487
* @typeDecl: the schema type definition
18488
* @ctxt: the schema parser context
18490
* Fixes the content model of the type.
18491
* URGENT TODO: We need an int result!
18494
xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18495
xmlSchemaAbstractCtxtPtr actxt)
18499
if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
18500
AERROR_INT("xmlSchemaTypeFixup",
18501
"this function needs a parser context");
18504
if (! WXS_IS_TYPE_NOT_FIXED(type))
18506
if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18507
return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
18508
else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18509
return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
18514
* xmlSchemaCheckFacet:
18515
* @facet: the facet
18516
* @typeDecl: the schema type definition
18517
* @pctxt: the schema parser context or NULL
18518
* @name: the optional name of the type
18520
* Checks and computes the values of facets.
18522
* Returns 0 if valid, a positive error code if not valid and
18523
* -1 in case of an internal or API error.
18526
xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
18527
xmlSchemaTypePtr typeDecl,
18528
xmlSchemaParserCtxtPtr pctxt,
18529
const xmlChar * name ATTRIBUTE_UNUSED)
18531
int ret = 0, ctxtGiven;
18533
if ((facet == NULL) || (typeDecl == NULL))
18536
* TODO: will the parser context be given if used from
18537
* the relaxNG module?
18544
switch (facet->type) {
18545
case XML_SCHEMA_FACET_MININCLUSIVE:
18546
case XML_SCHEMA_FACET_MINEXCLUSIVE:
18547
case XML_SCHEMA_FACET_MAXINCLUSIVE:
18548
case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18549
case XML_SCHEMA_FACET_ENUMERATION: {
18551
* Okay we need to validate the value
18554
xmlSchemaTypePtr base;
18556
/* 4.3.5.5 Constraints on enumeration Schema Components
18557
* Schema Component Constraint: enumeration valid restriction
18558
* It is an ļæ½errorļæ½ if any member of {value} is not in the
18559
* ļæ½value spaceļæ½ of {base type definition}.
18561
* minInclusive, maxInclusive, minExclusive, maxExclusive:
18562
* The value ļæ½mustļæ½ be in the
18563
* ļæ½value spaceļæ½ of the ļæ½base typeļæ½.
18566
* This function is intended to deliver a compiled value
18567
* on the facet. In this implementation of XML Schemata the
18568
* type holding a facet, won't be a built-in type.
18569
* Thus to ensure that other API
18570
* calls (relaxng) do work, if the given type is a built-in
18571
* type, we will assume that the given built-in type *is
18572
* already* the base type.
18574
if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18575
base = typeDecl->baseType;
18576
if (base == NULL) {
18577
PERROR_INT("xmlSchemaCheckFacet",
18578
"a type user derived type has no base type");
18586
* A context is needed if called from RelaxNG.
18588
pctxt = xmlSchemaNewParserCtxt("*");
18593
* NOTE: This call does not check the content nodes,
18594
* since they are not available:
18595
* facet->node is just the node holding the facet
18596
* definition, *not* the attribute holding the *value*
18599
ret = xmlSchemaVCheckCVCSimpleType(
18600
ACTXT_CAST pctxt, facet->node, base,
18601
facet->value, &(facet->val), 1, 1, 0);
18604
/* No error message for RelaxNG. */
18606
xmlSchemaCustomErr(ACTXT_CAST pctxt,
18607
XML_SCHEMAP_INTERNAL, facet->node, NULL,
18608
"Internal error: xmlSchemaCheckFacet, "
18609
"failed to validate the value '%s' of the "
18610
"facet '%s' against the base type",
18611
facet->value, xmlSchemaFacetTypeToString(facet->type));
18613
goto internal_error;
18615
ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18616
/* No error message for RelaxNG. */
18618
xmlChar *str = NULL;
18620
xmlSchemaCustomErr(ACTXT_CAST pctxt,
18621
ret, facet->node, WXS_BASIC_CAST facet,
18622
"The value '%s' of the facet does not validate "
18623
"against the base type '%s'",
18625
xmlSchemaFormatQName(&str,
18626
base->targetNamespace, base->name));
18627
FREE_AND_NULL(str);
18630
} else if (facet->val == NULL) {
18632
PERROR_INT("xmlSchemaCheckFacet",
18633
"value was not computed");
18639
case XML_SCHEMA_FACET_PATTERN:
18640
facet->regexp = xmlRegexpCompile(facet->value);
18641
if (facet->regexp == NULL) {
18642
ret = XML_SCHEMAP_REGEXP_INVALID;
18643
/* No error message for RelaxNG. */
18645
xmlSchemaCustomErr(ACTXT_CAST pctxt,
18646
ret, facet->node, WXS_BASIC_CAST typeDecl,
18647
"The value '%s' of the facet 'pattern' is not a "
18648
"valid regular expression",
18649
facet->value, NULL);
18653
case XML_SCHEMA_FACET_TOTALDIGITS:
18654
case XML_SCHEMA_FACET_FRACTIONDIGITS:
18655
case XML_SCHEMA_FACET_LENGTH:
18656
case XML_SCHEMA_FACET_MAXLENGTH:
18657
case XML_SCHEMA_FACET_MINLENGTH:
18659
if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18660
ret = xmlSchemaValidatePredefinedType(
18661
xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18662
facet->value, &(facet->val));
18664
ret = xmlSchemaValidatePredefinedType(
18665
xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18666
facet->value, &(facet->val));
18670
/* No error message for RelaxNG. */
18672
PERROR_INT("xmlSchemaCheckFacet",
18673
"validating facet value");
18675
goto internal_error;
18677
ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18678
/* No error message for RelaxNG. */
18681
xmlSchemaCustomErr4(ACTXT_CAST pctxt,
18682
ret, facet->node, WXS_BASIC_CAST typeDecl,
18683
"The value '%s' of the facet '%s' is not a valid '%s'",
18685
xmlSchemaFacetTypeToString(facet->type),
18686
(facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18687
BAD_CAST "nonNegativeInteger" :
18688
BAD_CAST "positiveInteger",
18694
case XML_SCHEMA_FACET_WHITESPACE:{
18695
if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
18696
facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
18697
} else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
18698
facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
18699
} else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
18700
facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
18702
ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18703
/* No error message for RelaxNG. */
18705
/* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18706
xmlSchemaCustomErr(ACTXT_CAST pctxt,
18707
ret, facet->node, WXS_BASIC_CAST typeDecl,
18708
"The value '%s' of the facet 'whitespace' is not "
18709
"valid", facet->value, NULL);
18717
if ((! ctxtGiven) && (pctxt != NULL))
18718
xmlSchemaFreeParserCtxt(pctxt);
18721
if ((! ctxtGiven) && (pctxt != NULL))
18722
xmlSchemaFreeParserCtxt(pctxt);
18727
* xmlSchemaCheckFacetValues:
18728
* @typeDecl: the schema type definition
18729
* @ctxt: the schema parser context
18731
* Checks the default values types, especially for facets
18734
xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18735
xmlSchemaParserCtxtPtr pctxt)
18737
int res, olderrs = pctxt->nberrors;
18738
const xmlChar *name = typeDecl->name;
18740
* NOTE: It is intended to use the facets list, instead
18743
if (typeDecl->facets != NULL) {
18744
xmlSchemaFacetPtr facet = typeDecl->facets;
18747
* Temporarily assign the "schema" to the validation context
18748
* of the parser context. This is needed for NOTATION validation.
18750
if (pctxt->vctxt == NULL) {
18751
if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
18754
pctxt->vctxt->schema = pctxt->schema;
18755
while (facet != NULL) {
18756
res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
18758
facet = facet->next;
18760
pctxt->vctxt->schema = NULL;
18762
if (olderrs != pctxt->nberrors)
18763
return(pctxt->err);
18770
* xmlSchemaGetCircModelGrDefRef:
18771
* @ctxtMGroup: the searched model group
18772
* @selfMGroup: the second searched model group
18773
* @particle: the first particle
18775
* This one is intended to be used by
18776
* xmlSchemaCheckGroupDefCircular only.
18778
* Returns the particle with the circular model group definition reference,
18781
static xmlSchemaTreeItemPtr
18782
xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
18783
xmlSchemaTreeItemPtr particle)
18785
xmlSchemaTreeItemPtr circ = NULL;
18786
xmlSchemaTreeItemPtr term;
18787
xmlSchemaModelGroupDefPtr gdef;
18789
for (; particle != NULL; particle = particle->next) {
18790
term = particle->children;
18793
switch (term->type) {
18794
case XML_SCHEMA_TYPE_GROUP:
18795
gdef = (xmlSchemaModelGroupDefPtr) term;
18796
if (gdef == groupDef)
18799
* Mark this model group definition to avoid infinite
18800
* recursion on circular references not yet examined.
18802
if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
18804
if (gdef->children != NULL) {
18805
gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18806
circ = xmlSchemaGetCircModelGrDefRef(groupDef,
18807
gdef->children->children);
18808
gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18813
case XML_SCHEMA_TYPE_SEQUENCE:
18814
case XML_SCHEMA_TYPE_CHOICE:
18815
case XML_SCHEMA_TYPE_ALL:
18816
circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
18828
* xmlSchemaCheckGroupDefCircular:
18829
* @item: the model group definition
18830
* @ctxt: the parser context
18833
* Checks for circular references to model group definitions.
18836
xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
18837
xmlSchemaParserCtxtPtr ctxt)
18840
* Schema Component Constraint: Model Group Correct
18841
* 2 Circular groups are disallowed. That is, within the {particles}
18842
* of a group there must not be at any depth a particle whose {term}
18843
* is the group itself.
18845
if ((item == NULL) ||
18846
(item->type != XML_SCHEMA_TYPE_GROUP) ||
18847
(item->children == NULL))
18850
xmlSchemaTreeItemPtr circ;
18852
circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
18853
if (circ != NULL) {
18854
xmlChar *str = NULL;
18856
* TODO: The error report is not adequate: this constraint
18857
* is defined for model groups but not definitions, but since
18858
* there cannot be any circular model groups without a model group
18859
* definition (if not using a construction API), we check those
18862
xmlSchemaPCustomErr(ctxt,
18863
XML_SCHEMAP_MG_PROPS_CORRECT_2,
18864
NULL, WXS_ITEM_NODE(circ),
18865
"Circular reference to the model group definition '%s' "
18866
"defined", xmlSchemaFormatQName(&str,
18867
item->targetNamespace, item->name));
18870
* NOTE: We will cut the reference to avoid further
18871
* confusion of the processor. This is a fatal error.
18873
circ->children = NULL;
18879
* xmlSchemaModelGroupToModelGroupDefFixup:
18880
* @ctxt: the parser context
18881
* @mg: the model group
18883
* Assigns the model group of model group definitions to the "term"
18884
* of the referencing particle.
18885
* In xmlSchemaResolveModelGroupParticleReferences the model group
18886
* definitions were assigned to the "term", since needed for the
18887
* circularity check.
18889
* Schema Component Constraint:
18890
* All Group Limited (cos-all-limited) (1.2)
18893
xmlSchemaModelGroupToModelGroupDefFixup(
18894
xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
18895
xmlSchemaModelGroupPtr mg)
18897
xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
18899
while (particle != NULL) {
18900
if ((WXS_PARTICLE_TERM(particle) == NULL) ||
18901
((WXS_PARTICLE_TERM(particle))->type !=
18902
XML_SCHEMA_TYPE_GROUP))
18904
particle = WXS_PTC_CAST particle->next;
18907
if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
18909
* TODO: Remove the particle.
18911
WXS_PARTICLE_TERM(particle) = NULL;
18912
particle = WXS_PTC_CAST particle->next;
18916
* Assign the model group to the {term} of the particle.
18918
WXS_PARTICLE_TERM(particle) =
18919
WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
18921
particle = WXS_PTC_CAST particle->next;
18926
* xmlSchemaCheckAttrGroupCircularRecur:
18927
* @ctxtGr: the searched attribute group
18928
* @attr: the current attribute list to be processed
18930
* This one is intended to be used by
18931
* xmlSchemaCheckAttrGroupCircular only.
18933
* Returns the circular attribute grou reference, otherwise NULL.
18935
static xmlSchemaQNameRefPtr
18936
xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
18937
xmlSchemaItemListPtr list)
18939
xmlSchemaAttributeGroupPtr gr;
18940
xmlSchemaQNameRefPtr ref, circ;
18943
* We will search for an attribute group reference which
18944
* references the context attribute group.
18946
for (i = 0; i < list->nbItems; i++) {
18947
ref = list->items[i];
18948
if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
18949
(ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
18950
(ref->item != NULL))
18952
gr = WXS_ATTR_GROUP_CAST ref->item;
18955
if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
18958
* Mark as visited to avoid infinite recursion on
18959
* circular references not yet examined.
18961
if ((gr->attrUses) &&
18962
(gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
18964
gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
18965
circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
18966
(xmlSchemaItemListPtr) gr->attrUses);
18967
gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
18978
* xmlSchemaCheckAttrGroupCircular:
18979
* attrGr: the attribute group definition
18980
* @ctxt: the parser context
18983
* Checks for circular references of attribute groups.
18986
xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
18987
xmlSchemaParserCtxtPtr ctxt)
18990
* Schema Representation Constraint:
18991
* Attribute Group Definition Representation OK
18992
* 3 Circular group reference is disallowed outside <redefine>.
18993
* That is, unless this element information item's parent is
18994
* <redefine>, then among the [children], if any, there must
18995
* not be an <attributeGroup> with ref [attribute] which resolves
18996
* to the component corresponding to this <attributeGroup>. Indirect
18997
* circularity is also ruled out. That is, when QName resolution
18998
* (Schema Document) (ļæ½3.15.3) is applied to a ļæ½QNameļæ½ arising from
18999
* any <attributeGroup>s with a ref [attribute] among the [children],
19000
* it must not be the case that a ļæ½QNameļæ½ is encountered at any depth
19001
* which resolves to the component corresponding to this <attributeGroup>.
19003
if (attrGr->attrUses == NULL)
19005
else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
19008
xmlSchemaQNameRefPtr circ;
19010
circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
19011
(xmlSchemaItemListPtr) attrGr->attrUses);
19012
if (circ != NULL) {
19013
xmlChar *str = NULL;
19015
* TODO: Report the referenced attr group as QName.
19017
xmlSchemaPCustomErr(ctxt,
19018
XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
19019
NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
19020
"Circular reference to the attribute group '%s' "
19021
"defined", xmlSchemaGetComponentQName(&str, attrGr));
19022
FREE_AND_NULL(str);
19024
* NOTE: We will cut the reference to avoid further
19025
* confusion of the processor.
19026
* BADSPEC TODO: The spec should define how to process in this case.
19036
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19037
xmlSchemaAttributeGroupPtr attrGr);
19040
* xmlSchemaExpandAttributeGroupRefs:
19041
* @pctxt: the parser context
19042
* @node: the node of the component holding the attribute uses
19043
* @completeWild: the intersected wildcard to be returned
19044
* @list: the attribute uses
19046
* Substitutes contained attribute group references
19047
* for their attribute uses. Wilcards are intersected.
19048
* Attribute use prohibitions are removed from the list
19049
* and returned via the @prohibs list.
19050
* Pointlessness of attr. prohibs, if a matching attr. decl
19051
* is existent a well, are checked.
19054
xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
19055
xmlSchemaBasicItemPtr item,
19056
xmlSchemaWildcardPtr *completeWild,
19057
xmlSchemaItemListPtr list,
19058
xmlSchemaItemListPtr prohibs)
19060
xmlSchemaAttributeGroupPtr gr;
19061
xmlSchemaAttributeUsePtr use;
19062
xmlSchemaItemListPtr sublist;
19064
int created = (*completeWild == NULL) ? 0 : 1;
19067
prohibs->nbItems = 0;
19069
for (i = 0; i < list->nbItems; i++) {
19070
use = list->items[i];
19072
if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
19073
if (prohibs == NULL) {
19074
PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19075
"unexpected attr prohibition found");
19079
* Remove from attribute uses.
19081
if (xmlSchemaItemListRemove(list, i) == -1)
19085
* Note that duplicate prohibitions were already
19086
* handled at parsing time.
19089
* Add to list of prohibitions.
19091
xmlSchemaItemListAddSize(prohibs, 2, use);
19094
if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19095
((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
19097
if ((WXS_QNAME_CAST use)->item == NULL)
19099
gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
19101
* Expand the referenced attr. group.
19102
* TODO: remove this, this is done in a previous step, so
19103
* already done here.
19105
if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
19106
if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
19110
* Build the 'complete' wildcard; i.e. intersect multiple
19113
if (gr->attributeWildcard != NULL) {
19114
if (*completeWild == NULL) {
19115
*completeWild = gr->attributeWildcard;
19118
xmlSchemaWildcardPtr tmpWild;
19121
* Copy the first encountered wildcard as context,
19122
* except for the annotation.
19124
* Although the complete wildcard might not correspond
19125
* to any node in the schema, we will anchor it on
19126
* the node of the owner component.
19128
tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema,
19129
XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
19130
WXS_ITEM_NODE(item));
19131
if (tmpWild == NULL)
19133
if (xmlSchemaCloneWildcardNsConstraints(pctxt,
19134
tmpWild, *completeWild) == -1)
19136
tmpWild->processContents = (*completeWild)->processContents;
19137
*completeWild = tmpWild;
19141
if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
19142
gr->attributeWildcard) == -1)
19147
* Just remove the reference if the referenced group does not
19148
* contain any attribute uses.
19150
sublist = ((xmlSchemaItemListPtr) gr->attrUses);
19151
if ((sublist == NULL) || sublist->nbItems == 0) {
19152
if (xmlSchemaItemListRemove(list, i) == -1)
19158
* Add the attribute uses.
19160
list->items[i] = sublist->items[0];
19161
if (sublist->nbItems != 1) {
19162
for (j = 1; j < sublist->nbItems; j++) {
19164
if (xmlSchemaItemListInsert(list,
19165
sublist->items[j], i) == -1)
19173
* Handle pointless prohibitions of declared attributes.
19175
if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
19176
xmlSchemaAttributeUseProhibPtr prohib;
19178
for (i = prohibs->nbItems -1; i >= 0; i--) {
19179
prohib = prohibs->items[i];
19180
for (j = 0; j < list->nbItems; j++) {
19181
use = list->items[j];
19183
if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
19184
(prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
19186
xmlChar *str = NULL;
19188
xmlSchemaCustomWarning(ACTXT_CAST pctxt,
19189
XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
19190
prohib->node, NULL,
19191
"Skipping pointless attribute use prohibition "
19192
"'%s', since a corresponding attribute use "
19193
"exists already in the type definition",
19194
xmlSchemaFormatQName(&str,
19195
prohib->targetNamespace, prohib->name),
19197
FREE_AND_NULL(str);
19199
* Remove the prohibition.
19201
if (xmlSchemaItemListRemove(prohibs, i) == -1)
19212
* xmlSchemaAttributeGroupExpandRefs:
19213
* @pctxt: the parser context
19214
* @attrGr: the attribute group definition
19217
* {attribute uses} property
19218
* {attribute wildcard} property
19220
* Substitutes contained attribute group references
19221
* for their attribute uses. Wilcards are intersected.
19224
xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19225
xmlSchemaAttributeGroupPtr attrGr)
19227
if ((attrGr->attrUses == NULL) ||
19228
(attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
19231
attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
19232
if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
19233
&(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
19239
* xmlSchemaAttributeGroupExpandRefs:
19240
* @pctxt: the parser context
19241
* @attrGr: the attribute group definition
19243
* Substitutes contained attribute group references
19244
* for their attribute uses. Wilcards are intersected.
19246
* Schema Component Constraint:
19247
* Attribute Group Definition Properties Correct (ag-props-correct)
19250
xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19251
xmlSchemaAttributeGroupPtr attrGr)
19254
* SPEC ag-props-correct
19255
* (1) "The values of the properties of an attribute group definition
19256
* must be as described in the property tableau in The Attribute
19257
* Group Definition Schema Component (ļæ½3.6.1), modulo the impact of
19258
* Missing Sub-components (ļæ½5.3);"
19261
if ((attrGr->attrUses != NULL) &&
19262
(WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
19264
xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
19265
xmlSchemaAttributeUsePtr use, tmp;
19266
int i, j, hasId = 0;
19268
for (i = uses->nbItems -1; i >= 0; i--) {
19269
use = uses->items[i];
19271
* SPEC ag-props-correct
19272
* (2) "Two distinct members of the {attribute uses} must not have
19273
* {attribute declaration}s both of whose {name}s match and whose
19274
* {target namespace}s are identical."
19277
for (j = i -1; j >= 0; j--) {
19278
tmp = uses->items[j];
19279
if ((WXS_ATTRUSE_DECL_NAME(use) ==
19280
WXS_ATTRUSE_DECL_NAME(tmp)) &&
19281
(WXS_ATTRUSE_DECL_TNS(use) ==
19282
WXS_ATTRUSE_DECL_TNS(tmp)))
19284
xmlChar *str = NULL;
19286
xmlSchemaCustomErr(ACTXT_CAST pctxt,
19287
XML_SCHEMAP_AG_PROPS_CORRECT,
19288
attrGr->node, WXS_BASIC_CAST attrGr,
19290
xmlSchemaGetComponentDesignation(&str, use),
19292
FREE_AND_NULL(str);
19294
* Remove the duplicate.
19296
if (xmlSchemaItemListRemove(uses, i) == -1)
19303
* SPEC ag-props-correct
19304
* (3) "Two distinct members of the {attribute uses} must not have
19305
* {attribute declaration}s both of whose {type definition}s are or
19306
* are derived from ID."
19307
* TODO: Does 'derived' include member-types of unions?
19309
if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
19310
if (xmlSchemaIsDerivedFromBuiltInType(
19311
WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19314
xmlChar *str = NULL;
19316
xmlSchemaCustomErr(ACTXT_CAST pctxt,
19317
XML_SCHEMAP_AG_PROPS_CORRECT,
19318
attrGr->node, WXS_BASIC_CAST attrGr,
19319
"There must not exist more than one attribute "
19320
"declaration of type 'xs:ID' "
19321
"(or derived from 'xs:ID'). The %s violates this "
19323
xmlSchemaGetComponentDesignation(&str, use),
19325
FREE_AND_NULL(str);
19326
if (xmlSchemaItemListRemove(uses, i) == -1)
19339
* xmlSchemaResolveAttrGroupReferences:
19340
* @attrgrpDecl: the schema attribute definition
19341
* @ctxt: the schema parser context
19342
* @name: the attribute name
19344
* Resolves references to attribute group definitions.
19347
xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19348
xmlSchemaParserCtxtPtr ctxt)
19350
xmlSchemaAttributeGroupPtr group;
19352
if (ref->item != NULL)
19354
group = xmlSchemaGetAttributeGroup(ctxt->schema,
19356
ref->targetNamespace);
19357
if (group == NULL) {
19358
xmlSchemaPResCompAttrErr(ctxt,
19359
XML_SCHEMAP_SRC_RESOLVE,
19361
"ref", ref->name, ref->targetNamespace,
19362
ref->itemType, NULL);
19365
ref->item = WXS_BASIC_CAST group;
19370
* xmlSchemaCheckAttrPropsCorrect:
19371
* @item: an schema attribute declaration/use
19372
* @ctxt: a schema parser context
19373
* @name: the name of the attribute
19376
* Schema Component Constraint:
19377
* Attribute Declaration Properties Correct (a-props-correct)
19379
* Validates the value constraints of an attribute declaration/use.
19380
* NOTE that this needs the simle type definitions to be already
19381
* builded and checked.
19384
xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19385
xmlSchemaAttributePtr attr)
19389
* SPEC a-props-correct (1)
19390
* "The values of the properties of an attribute declaration must
19391
* be as described in the property tableau in The Attribute
19392
* Declaration Schema Component (ļæ½3.2.1), modulo the impact of
19393
* Missing Sub-components (ļæ½5.3)."
19396
if (WXS_ATTR_TYPEDEF(attr) == NULL)
19399
if (attr->defValue != NULL) {
19403
* SPEC a-props-correct (3)
19404
* "If the {type definition} is or is derived from ID then there
19405
* must not be a {value constraint}."
19407
if (xmlSchemaIsDerivedFromBuiltInType(
19408
WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
19410
xmlSchemaCustomErr(ACTXT_CAST pctxt,
19411
XML_SCHEMAP_A_PROPS_CORRECT_3,
19412
NULL, WXS_BASIC_CAST attr,
19413
"Value constraints are not allowed if the type definition "
19414
"is or is derived from xs:ID",
19416
return(pctxt->err);
19419
* SPEC a-props-correct (2)
19420
* "if there is a {value constraint}, the canonical lexical
19421
* representation of its value must be ļæ½validļæ½ with respect
19422
* to the {type definition} as defined in String Valid (ļæ½3.14.4)."
19423
* TODO: Don't care about the *cononical* stuff here, this requirement
19424
* will be removed in WXS 1.1 anyway.
19426
ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
19427
attr->node, WXS_ATTR_TYPEDEF(attr),
19428
attr->defValue, &(attr->defVal),
19432
PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19433
"calling xmlSchemaVCheckCVCSimpleType()");
19436
xmlSchemaCustomErr(ACTXT_CAST pctxt,
19437
XML_SCHEMAP_A_PROPS_CORRECT_2,
19438
NULL, WXS_BASIC_CAST attr,
19439
"The value of the value constraint is not valid",
19441
return(pctxt->err);
19448
static xmlSchemaElementPtr
19449
xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19450
xmlSchemaElementPtr ancestor)
19452
xmlSchemaElementPtr ret;
19454
if (WXS_SUBST_HEAD(ancestor) == NULL)
19456
if (WXS_SUBST_HEAD(ancestor) == elemDecl)
19459
if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
19461
WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
19462
ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19463
WXS_SUBST_HEAD(ancestor));
19464
WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
19470
* xmlSchemaCheckElemPropsCorrect:
19471
* @ctxt: a schema parser context
19472
* @decl: the element declaration
19473
* @name: the name of the attribute
19475
* Schema Component Constraint:
19476
* Element Declaration Properties Correct (e-props-correct)
19482
xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19483
xmlSchemaElementPtr elemDecl)
19486
xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
19488
* SPEC (1) "The values of the properties of an element declaration
19489
* must be as described in the property tableau in The Element
19490
* Declaration Schema Component (ļæ½3.3.1), modulo the impact of Missing
19491
* Sub-components (ļæ½5.3)."
19493
if (WXS_SUBST_HEAD(elemDecl) != NULL) {
19494
xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
19496
xmlSchemaCheckElementDeclComponent(head, pctxt);
19498
* SPEC (3) "If there is a non-ļæ½absentļæ½ {substitution group
19499
* affiliation}, then {scope} must be global."
19501
if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
19502
xmlSchemaPCustomErr(pctxt,
19503
XML_SCHEMAP_E_PROPS_CORRECT_3,
19504
WXS_BASIC_CAST elemDecl, NULL,
19505
"Only global element declarations can have a "
19506
"substitution group affiliation", NULL);
19507
ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
19510
* TODO: SPEC (6) "Circular substitution groups are disallowed.
19511
* That is, it must not be possible to return to an element declaration
19512
* by repeatedly following the {substitution group affiliation}
19515
if (head == elemDecl)
19517
else if (WXS_SUBST_HEAD(head) != NULL)
19518
circ = xmlSchemaCheckSubstGroupCircular(head, head);
19521
if (circ != NULL) {
19522
xmlChar *strA = NULL, *strB = NULL;
19524
xmlSchemaPCustomErrExt(pctxt,
19525
XML_SCHEMAP_E_PROPS_CORRECT_6,
19526
WXS_BASIC_CAST circ, NULL,
19527
"The element declaration '%s' defines a circular "
19528
"substitution group to element declaration '%s'",
19529
xmlSchemaGetComponentQName(&strA, circ),
19530
xmlSchemaGetComponentQName(&strB, head),
19532
FREE_AND_NULL(strA)
19533
FREE_AND_NULL(strB)
19534
ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
19537
* SPEC (4) "If there is a {substitution group affiliation},
19538
* the {type definition}
19539
* of the element declaration must be validly derived from the {type
19540
* definition} of the {substitution group affiliation}, given the value
19541
* of the {substitution group exclusions} of the {substitution group
19542
* affiliation}, as defined in Type Derivation OK (Complex) (ļæ½3.4.6)
19543
* (if the {type definition} is complex) or as defined in
19544
* Type Derivation OK (Simple) (ļæ½3.14.6) (if the {type definition} is
19547
* NOTE: {substitution group exclusions} means the values of the
19548
* attribute "final".
19551
if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
19554
if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
19555
set |= SUBSET_EXTENSION;
19556
if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
19557
set |= SUBSET_RESTRICTION;
19559
if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
19560
WXS_ELEM_TYPEDEF(head), set) != 0) {
19561
xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
19563
ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
19564
xmlSchemaPCustomErrExt(pctxt,
19565
XML_SCHEMAP_E_PROPS_CORRECT_4,
19566
WXS_BASIC_CAST elemDecl, NULL,
19567
"The type definition '%s' was "
19568
"either rejected by the substitution group "
19569
"affiliation '%s', or not validly derived from its type "
19571
xmlSchemaGetComponentQName(&strA, typeDef),
19572
xmlSchemaGetComponentQName(&strB, head),
19573
xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
19574
FREE_AND_NULL(strA)
19575
FREE_AND_NULL(strB)
19576
FREE_AND_NULL(strC)
19581
* SPEC (5) "If the {type definition} or {type definition}'s
19583
* is or is derived from ID then there must not be a {value constraint}.
19584
* Note: The use of ID as a type definition for elements goes beyond
19585
* XML 1.0, and should be avoided if backwards compatibility is desired"
19587
if ((elemDecl->value != NULL) &&
19588
((WXS_IS_SIMPLE(typeDef) &&
19589
xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19590
(WXS_IS_COMPLEX(typeDef) &&
19591
WXS_HAS_SIMPLE_CONTENT(typeDef) &&
19592
xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19593
XML_SCHEMAS_ID)))) {
19595
ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
19596
xmlSchemaPCustomErr(pctxt,
19597
XML_SCHEMAP_E_PROPS_CORRECT_5,
19598
WXS_BASIC_CAST elemDecl, NULL,
19599
"The type definition (or type definition's content type) is or "
19600
"is derived from ID; value constraints are not allowed in "
19601
"conjunction with such a type definition", NULL);
19602
} else if (elemDecl->value != NULL) {
19604
xmlNodePtr node = NULL;
19607
* SPEC (2) "If there is a {value constraint}, the canonical lexical
19608
* representation of its value must be ļæ½validļæ½ with respect to the
19609
* {type definition} as defined in Element Default Valid (Immediate)
19612
if (typeDef == NULL) {
19613
xmlSchemaPErr(pctxt, elemDecl->node,
19614
XML_SCHEMAP_INTERNAL,
19615
"Internal error: xmlSchemaCheckElemPropsCorrect, "
19616
"type is missing... skipping validation of "
19617
"the value constraint", NULL, NULL);
19620
if (elemDecl->node != NULL) {
19621
if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
19622
node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19625
node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19626
BAD_CAST "default");
19628
vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19629
typeDef, elemDecl->value, &(elemDecl->defVal));
19632
PERROR_INT("xmlSchemaElemCheckValConstr",
19633
"failed to validate the value constraint of an "
19634
"element declaration");
19645
* xmlSchemaCheckElemSubstGroup:
19646
* @ctxt: a schema parser context
19647
* @decl: the element declaration
19648
* @name: the name of the attribute
19650
* Schema Component Constraint:
19651
* Substitution Group (cos-equiv-class)
19653
* In Libxml2 the subst. groups will be precomputed, in terms of that
19654
* a list will be built for each subst. group head, holding all direct
19655
* referents to this head.
19656
* NOTE that this function needs:
19657
* 1. circular subst. groups to be checked beforehand
19658
* 2. the declaration's type to be derived from the head's type
19664
xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19665
xmlSchemaElementPtr elemDecl)
19667
if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
19668
/* SPEC (1) "Its {abstract} is false." */
19669
(elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
19672
xmlSchemaElementPtr head;
19673
xmlSchemaTypePtr headType, type;
19676
* SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19677
* {disallowed substitutions} as the blocking constraint, as defined in
19678
* Substitution Group OK (Transitive) (ļæ½3.3.6)."
19680
for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
19681
head = WXS_SUBST_HEAD(head)) {
19685
* The blocking constraints.
19687
if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
19689
headType = head->subtypes;
19690
type = elemDecl->subtypes;
19691
if (headType == type)
19693
if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
19694
set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19695
if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
19696
set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19698
* SPEC: Substitution Group OK (Transitive) (2.3)
19699
* "The set of all {derivation method}s involved in the
19700
* derivation of D's {type definition} from C's {type definition}
19701
* does not intersect with the union of the blocking constraint,
19702
* C's {prohibited substitutions} (if C is complex, otherwise the
19703
* empty set) and the {prohibited substitutions} (respectively the
19704
* empty set) of any intermediate {type definition}s in the
19705
* derivation of D's {type definition} from C's {type definition}."
19708
* OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19709
* subst.head axis, the methSet does not need to be computed for
19710
* the full depth over and over.
19713
* The set of all {derivation method}s involved in the derivation
19715
while ((type != NULL) && (type != headType)) {
19716
if ((WXS_IS_EXTENSION(type)) &&
19717
((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19718
methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19720
if (WXS_IS_RESTRICTION(type) &&
19721
((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19722
methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19724
type = type->baseType;
19727
* The {prohibited substitutions} of all intermediate types +
19730
type = elemDecl->subtypes->baseType;
19731
while (type != NULL) {
19732
if (WXS_IS_COMPLEX(type)) {
19734
XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19735
((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
19736
set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19738
XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19739
((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19740
set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19743
if (type == headType)
19745
type = type->baseType;
19748
(((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19749
(methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
19750
((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19751
(methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
19755
xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
19756
if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
19757
head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
19762
#ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
19764
* xmlSchemaCheckElementDeclComponent
19765
* @pctxt: the schema parser context
19766
* @ctxtComponent: the context component (an element declaration)
19767
* @ctxtParticle: the first particle of the context component
19768
* @searchParticle: the element declaration particle to be analysed
19770
* Schema Component Constraint: Element Declarations Consistent
19773
xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
19774
xmlSchemaBasicItemPtr ctxtComponent,
19775
xmlSchemaParticlePtr ctxtParticle,
19776
xmlSchemaParticlePtr searchParticle,
19777
xmlSchemaParticlePtr curParticle,
19783
xmlSchemaParticlePtr cur = curParticle;
19784
if (curParticle == NULL) {
19787
if (WXS_PARTICLE_TERM(curParticle) == NULL) {
19789
* Just return in this case. A missing "term" of the particle
19790
* might arise due to an invalid "term" component.
19794
while (cur != NULL) {
19795
switch (WXS_PARTICLE_TERM(cur)->type) {
19796
case XML_SCHEMA_TYPE_ANY:
19798
case XML_SCHEMA_TYPE_ELEMENT:
19800
ret = xmlSchemaCheckElementDeclConsistent(pctxt,
19801
ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
19805
xmlSchemaElementPtr elem =
19806
WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
19808
* SPEC Element Declarations Consistent:
19809
* "If the {particles} contains, either directly,
19810
* indirectly (that is, within the {particles} of a
19811
* contained model group, recursively) or ļæ½implicitlyļæ½
19812
* two or more element declaration particles with
19813
* the same {name} and {target namespace}, then
19814
* all their type definitions must be the same
19815
* top-level definition [...]"
19817
if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
19818
WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
19819
xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19820
WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
19822
xmlChar *strA = NULL, *strB = NULL;
19824
xmlSchemaCustomErr(ACTXT_CAST pctxt,
19825
/* TODO: error code */
19826
XML_SCHEMAP_COS_NONAMBIG,
19827
WXS_ITEM_NODE(cur), NULL,
19828
"In the content model of %s, there are multiple "
19829
"element declarations for '%s' with different "
19830
"type definitions",
19831
xmlSchemaGetComponentDesignation(&strA,
19833
xmlSchemaFormatQName(&strB,
19834
WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19835
WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
19836
FREE_AND_NULL(strA);
19837
FREE_AND_NULL(strB);
19838
return(XML_SCHEMAP_COS_NONAMBIG);
19842
case XML_SCHEMA_TYPE_SEQUENCE: {
19845
case XML_SCHEMA_TYPE_CHOICE:{
19847
xmlSchemaTreeItemPtr sub;
19849
sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr)
19850
while (sub != NULL) {
19851
ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
19852
ctxtParticle, ctxtElem);
19860
case XML_SCHEMA_TYPE_ALL:
19862
case XML_SCHEMA_TYPE_GROUP:
19865
xmlSchemaInternalErr2(ACTXT_CAST pctxt,
19866
"xmlSchemaCheckElementDeclConsistent",
19867
"found unexpected term of type '%s' in content model",
19868
WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
19871
cur = (xmlSchemaParticlePtr) cur->next;
19880
* xmlSchemaCheckElementDeclComponent
19881
* @item: an schema element declaration/particle
19882
* @ctxt: a schema parser context
19883
* @name: the name of the attribute
19885
* Validates the value constraints of an element declaration.
19886
* Adds substitution group members.
19889
xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
19890
xmlSchemaParserCtxtPtr ctxt)
19892
if (elemDecl == NULL)
19894
if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
19896
elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
19897
if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
19899
* Adds substitution group members.
19901
xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
19906
* xmlSchemaResolveModelGroupParticleReferences:
19907
* @particle: a particle component
19908
* @ctxt: a parser context
19910
* Resolves references of a model group's {particles} to
19911
* model group definitions and to element declarations.
19914
xmlSchemaResolveModelGroupParticleReferences(
19915
xmlSchemaParserCtxtPtr ctxt,
19916
xmlSchemaModelGroupPtr mg)
19918
xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
19919
xmlSchemaQNameRefPtr ref;
19920
xmlSchemaBasicItemPtr refItem;
19923
* URGENT TODO: Test this.
19925
while (particle != NULL) {
19926
if ((WXS_PARTICLE_TERM(particle) == NULL) ||
19927
((WXS_PARTICLE_TERM(particle))->type !=
19928
XML_SCHEMA_EXTRA_QNAMEREF))
19930
goto next_particle;
19932
ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
19934
* Resolve the reference.
19935
* NULL the {term} by default.
19937
particle->children = NULL;
19939
refItem = xmlSchemaGetNamedComponent(ctxt->schema,
19940
ref->itemType, ref->name, ref->targetNamespace);
19941
if (refItem == NULL) {
19942
xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
19943
NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
19944
ref->targetNamespace, ref->itemType, NULL);
19945
/* TODO: remove the particle. */
19946
goto next_particle;
19948
if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
19949
if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
19950
/* TODO: remove the particle. */
19951
goto next_particle;
19953
* NOTE that we will assign the model group definition
19954
* itself to the "term" of the particle. This will ease
19955
* the check for circular model group definitions. After
19956
* that the "term" will be assigned the model group of the
19957
* model group definition.
19959
if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
19960
XML_SCHEMA_TYPE_ALL) {
19962
* SPEC cos-all-limited (1)
19963
* SPEC cos-all-limited (1.2)
19964
* "It appears only as the value of one or both of the
19965
* following properties:"
19966
* (1.1) "the {model group} property of a model group
19968
* (1.2) "the {term} property of a particle [... of] the "
19969
* {content type} of a complex type definition."
19971
xmlSchemaCustomErr(ACTXT_CAST ctxt,
19972
/* TODO: error code */
19973
XML_SCHEMAP_COS_ALL_LIMITED,
19974
WXS_ITEM_NODE(particle), NULL,
19975
"A model group definition is referenced, but "
19976
"it contains an 'all' model group, which "
19977
"cannot be contained by model groups",
19979
/* TODO: remove the particle. */
19980
goto next_particle;
19982
particle->children = (xmlSchemaTreeItemPtr) refItem;
19985
* TODO: Are referenced element declarations the only
19986
* other components we expect here?
19988
particle->children = (xmlSchemaTreeItemPtr) refItem;
19991
particle = WXS_PTC_CAST particle->next;
19996
xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
19999
xmlSchemaTypePtr tx, ty, ptx, pty;
20002
while (x != NULL) {
20004
tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
20005
ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
20006
ptx = xmlSchemaGetPrimitiveType(tx);
20007
pty = xmlSchemaGetPrimitiveType(ty);
20009
* (1) if a datatype T' is ļæ½derivedļæ½ by ļæ½restrictionļæ½ from an
20010
* atomic datatype T then the ļæ½value spaceļæ½ of T' is a subset of
20011
* the ļæ½value spaceļæ½ of T. */
20013
* (2) if datatypes T' and T'' are ļæ½derivedļæ½ by ļæ½restrictionļæ½
20014
* from a common atomic ancestor T then the ļæ½value spaceļæ½s of T'
20015
* and T'' may overlap.
20020
* We assume computed values to be normalized, so do a fast
20021
* string comparison for string based types.
20023
if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
20024
WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
20026
xmlSchemaValueGetAsString(x),
20027
xmlSchemaValueGetAsString(y)))
20030
ret = xmlSchemaCompareValuesWhtsp(
20031
x, XML_SCHEMA_WHITESPACE_PRESERVE,
20032
y, XML_SCHEMA_WHITESPACE_PRESERVE);
20041
x = xmlSchemaValueGetNext(x);
20043
y = xmlSchemaValueGetNext(y);
20046
} else if (xmlSchemaValueGetNext(y) != NULL)
20055
* xmlSchemaResolveAttrUseReferences:
20056
* @item: an attribute use
20057
* @ctxt: a parser context
20059
* Resolves the referenced attribute declaration.
20062
xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
20063
xmlSchemaParserCtxtPtr ctxt)
20065
if ((ctxt == NULL) || (ause == NULL))
20067
if ((ause->attrDecl == NULL) ||
20068
(ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
20072
xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
20075
* TODO: Evaluate, what errors could occur if the declaration is not
20078
ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
20079
ref->name, ref->targetNamespace);
20080
if (ause->attrDecl == NULL) {
20081
xmlSchemaPResCompAttrErr(ctxt,
20082
XML_SCHEMAP_SRC_RESOLVE,
20083
WXS_BASIC_CAST ause, ause->node,
20084
"ref", ref->name, ref->targetNamespace,
20085
XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20086
return(ctxt->err);;
20093
* xmlSchemaCheckAttrUsePropsCorrect:
20094
* @ctxt: a parser context
20095
* @use: an attribute use
20097
* Schema Component Constraint:
20098
* Attribute Use Correct (au-props-correct)
20102
xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
20103
xmlSchemaAttributeUsePtr use)
20105
if ((ctxt == NULL) || (use == NULL))
20107
if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
20108
((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
20112
* SPEC au-props-correct (1)
20113
* "The values of the properties of an attribute use must be as
20114
* described in the property tableau in The Attribute Use Schema
20115
* Component (ļæ½3.5.1), modulo the impact of Missing
20116
* Sub-components (ļæ½5.3)."
20119
if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
20120
((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
20121
((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20123
xmlSchemaPCustomErr(ctxt,
20124
XML_SCHEMAP_AU_PROPS_CORRECT_2,
20125
WXS_BASIC_CAST use, NULL,
20126
"The attribute declaration has a 'fixed' value constraint "
20127
", thus the attribute use must also have a 'fixed' value "
20133
* Compute and check the value constraint's value.
20135
if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
20138
* TODO: The spec seems to be missing a check of the
20139
* value constraint of the attribute use. We will do it here.
20142
* SPEC a-props-correct (3)
20144
if (xmlSchemaIsDerivedFromBuiltInType(
20145
WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
20147
xmlSchemaCustomErr(ACTXT_CAST ctxt,
20148
XML_SCHEMAP_AU_PROPS_CORRECT,
20149
NULL, WXS_BASIC_CAST use,
20150
"Value constraints are not allowed if the type definition "
20151
"is or is derived from xs:ID",
20156
ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
20157
use->node, WXS_ATTRUSE_TYPEDEF(use),
20158
use->defValue, &(use->defVal),
20162
PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20163
"calling xmlSchemaVCheckCVCSimpleType()");
20166
xmlSchemaCustomErr(ACTXT_CAST ctxt,
20167
XML_SCHEMAP_AU_PROPS_CORRECT,
20168
NULL, WXS_BASIC_CAST use,
20169
"The value of the value constraint is not valid",
20175
* SPEC au-props-correct (2)
20176
* "If the {attribute declaration} has a fixed
20177
* {value constraint}, then if the attribute use itself has a
20178
* {value constraint}, it must also be fixed and its value must match
20179
* that of the {attribute declaration}'s {value constraint}."
20181
if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
20182
(((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20184
if (! xmlSchemaAreValuesEqual(use->defVal,
20185
(WXS_ATTRUSE_DECL(use))->defVal))
20187
xmlSchemaPCustomErr(ctxt,
20188
XML_SCHEMAP_AU_PROPS_CORRECT_2,
20189
WXS_BASIC_CAST use, NULL,
20190
"The 'fixed' value constraint of the attribute use "
20191
"must match the attribute declaration's value "
20193
(WXS_ATTRUSE_DECL(use))->defValue);
20204
* xmlSchemaResolveAttrTypeReferences:
20205
* @item: an attribute declaration
20206
* @ctxt: a parser context
20208
* Resolves the referenced type definition component.
20211
xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
20212
xmlSchemaParserCtxtPtr ctxt)
20215
* The simple type definition corresponding to the <simpleType> element
20216
* information item in the [children], if present, otherwise the simple
20217
* type definition ļæ½resolvedļæ½ to by the ļæ½actual valueļæ½ of the type
20218
* [attribute], if present, otherwise the ļæ½simple ur-type definitionļæ½.
20220
if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
20222
item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
20223
if (item->subtypes != NULL)
20225
if (item->typeName != NULL) {
20226
xmlSchemaTypePtr type;
20228
type = xmlSchemaGetType(ctxt->schema, item->typeName,
20230
if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
20231
xmlSchemaPResCompAttrErr(ctxt,
20232
XML_SCHEMAP_SRC_RESOLVE,
20233
WXS_BASIC_CAST item, item->node,
20234
"type", item->typeName, item->typeNs,
20235
XML_SCHEMA_TYPE_SIMPLE, NULL);
20238
item->subtypes = type;
20242
* The type defaults to the xs:anySimpleType.
20244
item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
20250
* xmlSchemaResolveIDCKeyReferences:
20251
* @idc: the identity-constraint definition
20252
* @ctxt: the schema parser context
20253
* @name: the attribute name
20255
* Resolve keyRef references to key/unique IDCs.
20256
* Schema Component Constraint:
20257
* Identity-constraint Definition Properties Correct (c-props-correct)
20260
xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
20261
xmlSchemaParserCtxtPtr pctxt)
20263
if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
20265
if (idc->ref->name != NULL) {
20266
idc->ref->item = (xmlSchemaBasicItemPtr)
20267
xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
20268
idc->ref->targetNamespace);
20269
if (idc->ref->item == NULL) {
20271
* TODO: It is actually not an error to fail to resolve
20272
* at this stage. BUT we need to be that strict!
20274
xmlSchemaPResCompAttrErr(pctxt,
20275
XML_SCHEMAP_SRC_RESOLVE,
20276
WXS_BASIC_CAST idc, idc->node,
20277
"refer", idc->ref->name,
20278
idc->ref->targetNamespace,
20279
XML_SCHEMA_TYPE_IDC_KEY, NULL);
20280
return(pctxt->err);
20281
} else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
20283
* SPEC c-props-correct (1)
20285
xmlSchemaCustomErr(ACTXT_CAST pctxt,
20286
XML_SCHEMAP_C_PROPS_CORRECT,
20287
NULL, WXS_BASIC_CAST idc,
20288
"The keyref references a keyref",
20290
idc->ref->item = NULL;
20291
return(pctxt->err);
20293
if (idc->nbFields !=
20294
((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
20295
xmlChar *str = NULL;
20296
xmlSchemaIDCPtr refer;
20298
refer = (xmlSchemaIDCPtr) idc->ref->item;
20300
* SPEC c-props-correct(2)
20301
* "If the {identity-constraint category} is keyref,
20302
* the cardinality of the {fields} must equal that of
20303
* the {fields} of the {referenced key}.
20305
xmlSchemaCustomErr(ACTXT_CAST pctxt,
20306
XML_SCHEMAP_C_PROPS_CORRECT,
20307
NULL, WXS_BASIC_CAST idc,
20308
"The cardinality of the keyref differs from the "
20309
"cardinality of the referenced key/unique '%s'",
20310
xmlSchemaFormatQName(&str, refer->targetNamespace,
20314
return(pctxt->err);
20322
xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20323
xmlSchemaParserCtxtPtr pctxt)
20325
if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20326
prohib->targetNamespace) == NULL) {
20328
xmlSchemaPResCompAttrErr(pctxt,
20329
XML_SCHEMAP_SRC_RESOLVE,
20330
NULL, prohib->node,
20331
"ref", prohib->name, prohib->targetNamespace,
20332
XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20333
return(XML_SCHEMAP_SRC_RESOLVE);
20338
#define WXS_REDEFINED_TYPE(c) \
20339
(((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20341
#define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20342
(((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20344
#define WXS_REDEFINED_ATTR_GROUP(c) \
20345
(((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20348
xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20351
xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20352
xmlSchemaBasicItemPtr prev, item;
20359
item = redef->item;
20361
* First try to locate the redefined component in the
20362
* schema graph starting with the redefined schema.
20363
* NOTE: According to this schema bug entry:
20364
* http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20365
* it's not clear if the referenced component needs to originate
20366
* from the <redefine>d schema _document_ or the schema; the latter
20367
* would include all imported and included sub-schemas of the
20368
* <redefine>d schema. Currenlty we latter approach is used.
20369
* SUPPLEMENT: It seems that the WG moves towards the latter
20370
* approach, so we are doing it right.
20373
prev = xmlSchemaFindRedefCompInGraph(
20374
redef->targetBucket, item->type,
20375
redef->refName, redef->refTargetNs);
20376
if (prev == NULL) {
20377
xmlChar *str = NULL;
20381
* SPEC src-redefine:
20382
* (6.2.1) "The ļæ½actual valueļæ½ of its own name attribute plus
20383
* target namespace must successfully ļæ½resolveļæ½ to a model
20384
* group definition in I."
20385
* (7.2.1) "The ļæ½actual valueļæ½ of its own name attribute plus
20386
* target namespace must successfully ļæ½resolveļæ½ to an attribute
20387
* group definition in I."
20390
* Note that, if we are redefining with the use of references
20391
* to components, the spec assumes the src-resolve to be used;
20392
* but this won't assure that we search only *inside* the
20393
* redefined schema.
20395
if (redef->reference)
20396
node = WXS_ITEM_NODE(redef->reference);
20398
node = WXS_ITEM_NODE(item);
20399
xmlSchemaCustomErr(ACTXT_CAST pctxt,
20401
* TODO: error code.
20402
* Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20405
XML_SCHEMAP_SRC_REDEFINE, node, NULL,
20406
"The %s '%s' to be redefined could not be found in "
20407
"the redefined schema",
20408
WXS_ITEM_TYPE_NAME(item),
20409
xmlSchemaFormatQName(&str, redef->refTargetNs,
20411
FREE_AND_NULL(str);
20413
redef = redef->next;
20417
* TODO: Obtaining and setting the redefinition state is really
20421
switch (item->type) {
20422
case XML_SCHEMA_TYPE_COMPLEX:
20423
case XML_SCHEMA_TYPE_SIMPLE:
20424
if ((WXS_TYPE_CAST prev)->flags &
20425
XML_SCHEMAS_TYPE_REDEFINED)
20430
/* Mark it as redefined. */
20431
(WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
20433
* Assign the redefined type to the
20434
* base type of the redefining type.
20437
((xmlSchemaTypePtr) item)->baseType =
20438
(xmlSchemaTypePtr) prev;
20440
case XML_SCHEMA_TYPE_GROUP:
20441
if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
20442
XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20447
/* Mark it as redefined. */
20448
(WXS_MODEL_GROUPDEF_CAST prev)->flags |=
20449
XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
20450
if (redef->reference != NULL) {
20452
* Overwrite the QName-reference with the
20453
* referenced model group def.
20455
(WXS_PTC_CAST redef->reference)->children =
20456
WXS_TREE_CAST prev;
20458
redef->target = prev;
20460
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20461
if ((WXS_ATTR_GROUP_CAST prev)->flags &
20462
XML_SCHEMAS_ATTRGROUP_REDEFINED)
20467
(WXS_ATTR_GROUP_CAST prev)->flags |=
20468
XML_SCHEMAS_ATTRGROUP_REDEFINED;
20469
if (redef->reference != NULL) {
20471
* Assign the redefined attribute group to the
20472
* QName-reference component.
20473
* This is the easy case, since we will just
20474
* expand the redefined group.
20476
(WXS_QNAME_CAST redef->reference)->item = prev;
20477
redef->target = NULL;
20480
* This is the complicated case: we need
20481
* to apply src-redefine (7.2.2) at a later
20482
* stage, i.e. when attribute group references
20483
* have beed expanded and simple types have
20486
redef->target = prev;
20490
PERROR_INT("xmlSchemaResolveRedefReferences",
20491
"Unexpected redefined component type");
20494
if (wasRedefined) {
20495
xmlChar *str = NULL;
20498
if (redef->reference)
20499
node = WXS_ITEM_NODE(redef->reference);
20501
node = WXS_ITEM_NODE(redef->item);
20503
xmlSchemaCustomErr(ACTXT_CAST pctxt,
20504
/* TODO: error code. */
20505
XML_SCHEMAP_SRC_REDEFINE,
20507
"The referenced %s was already redefined. Multiple "
20508
"redefinition of the same component is not supported",
20509
xmlSchemaGetComponentDesignation(&str, prev),
20513
redef = redef->next;
20516
redef = redef->next;
20517
} while (redef != NULL);
20523
xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20526
xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20527
xmlSchemaBasicItemPtr item;
20533
if (redef->target == NULL) {
20534
redef = redef->next;
20537
item = redef->item;
20539
switch (item->type) {
20540
case XML_SCHEMA_TYPE_SIMPLE:
20541
case XML_SCHEMA_TYPE_COMPLEX:
20543
* Since the spec wants the {name} of the redefined
20544
* type to be 'absent', we'll NULL it.
20546
(WXS_TYPE_CAST redef->target)->name = NULL;
20549
* TODO: Seems like there's nothing more to do. The normal
20550
* inheritance mechanism is used. But not 100% sure.
20553
case XML_SCHEMA_TYPE_GROUP:
20556
* SPEC src-redefine:
20557
* (6.2.2) "The {model group} of the model group definition
20558
* which corresponds to it per XML Representation of Model
20559
* Group Definition Schema Components (ļæ½3.7.2) must be a
20560
* ļæ½valid restrictionļæ½ of the {model group} of that model
20561
* group definition in I, as defined in Particle Valid
20562
* (Restriction) (ļæ½3.9.6)."
20565
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20567
* SPEC src-redefine:
20568
* (7.2.2) "The {attribute uses} and {attribute wildcard} of
20569
* the attribute group definition which corresponds to it
20570
* per XML Representation of Attribute Group Definition Schema
20571
* Components (ļæ½3.6.2) must be ļæ½valid restrictionsļæ½ of the
20572
* {attribute uses} and {attribute wildcard} of that attribute
20573
* group definition in I, as defined in clause 2, clause 3 and
20574
* clause 4 of Derivation Valid (Restriction, Complex)
20575
* (ļæ½3.4.6) (where references to the base type definition are
20576
* understood as references to the attribute group definition
20579
err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20580
XML_SCHEMA_ACTION_REDEFINE,
20581
item, redef->target,
20582
(WXS_ATTR_GROUP_CAST item)->attrUses,
20583
(WXS_ATTR_GROUP_CAST redef->target)->attrUses,
20584
(WXS_ATTR_GROUP_CAST item)->attributeWildcard,
20585
(WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
20592
redef = redef->next;
20593
} while (redef != NULL);
20599
xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20600
xmlSchemaBucketPtr bucket)
20602
xmlSchemaBasicItemPtr item;
20604
xmlHashTablePtr *table;
20605
const xmlChar *name;
20608
#define WXS_GET_GLOBAL_HASH(c, slot) { \
20609
if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20610
table = &(WXS_IMPBUCKET((c))->schema->slot); \
20612
table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20615
* Add global components to the schema's hash tables.
20616
* This is the place where duplicate components will be
20618
* TODO: I think normally we should support imports of the
20619
* same namespace from multiple locations. We don't do currently,
20620
* but if we do then according to:
20621
* http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20622
* we would need, if imported directly, to import redefined
20623
* components as well to be able to catch clashing components.
20624
* (I hope I'll still know what this means after some months :-()
20626
if (bucket == NULL)
20628
if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
20630
bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
20632
for (i = 0; i < bucket->globals->nbItems; i++) {
20633
item = bucket->globals->items[i];
20635
switch (item->type) {
20636
case XML_SCHEMA_TYPE_COMPLEX:
20637
case XML_SCHEMA_TYPE_SIMPLE:
20638
if (WXS_REDEFINED_TYPE(item))
20640
name = (WXS_TYPE_CAST item)->name;
20641
WXS_GET_GLOBAL_HASH(bucket, typeDecl)
20643
case XML_SCHEMA_TYPE_ELEMENT:
20644
name = (WXS_ELEM_CAST item)->name;
20645
WXS_GET_GLOBAL_HASH(bucket, elemDecl)
20647
case XML_SCHEMA_TYPE_ATTRIBUTE:
20648
name = (WXS_ATTR_CAST item)->name;
20649
WXS_GET_GLOBAL_HASH(bucket, attrDecl)
20651
case XML_SCHEMA_TYPE_GROUP:
20652
if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
20654
name = (WXS_MODEL_GROUPDEF_CAST item)->name;
20655
WXS_GET_GLOBAL_HASH(bucket, groupDecl)
20657
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20658
if (WXS_REDEFINED_ATTR_GROUP(item))
20660
name = (WXS_ATTR_GROUP_CAST item)->name;
20661
WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
20663
case XML_SCHEMA_TYPE_IDC_KEY:
20664
case XML_SCHEMA_TYPE_IDC_UNIQUE:
20665
case XML_SCHEMA_TYPE_IDC_KEYREF:
20666
name = (WXS_IDC_CAST item)->name;
20667
WXS_GET_GLOBAL_HASH(bucket, idcDef)
20669
case XML_SCHEMA_TYPE_NOTATION:
20670
name = ((xmlSchemaNotationPtr) item)->name;
20671
WXS_GET_GLOBAL_HASH(bucket, notaDecl)
20674
PERROR_INT("xmlSchemaAddComponents",
20675
"Unexpected global component type");
20678
if (*table == NULL) {
20679
*table = xmlHashCreateDict(10, pctxt->dict);
20680
if (*table == NULL) {
20681
PERROR_INT("xmlSchemaAddComponents",
20682
"failed to create a component hash table");
20686
err = xmlHashAddEntry(*table, name, item);
20688
xmlChar *str = NULL;
20690
xmlSchemaCustomErr(ACTXT_CAST pctxt,
20691
XML_SCHEMAP_REDEFINED_TYPE,
20692
WXS_ITEM_NODE(item),
20693
WXS_BASIC_CAST item,
20694
"A global %s '%s' does already exist",
20695
WXS_ITEM_TYPE_NAME(item),
20696
xmlSchemaGetComponentQName(&str, item));
20697
FREE_AND_NULL(str);
20701
* Process imported/included schemas.
20703
if (bucket->relations != NULL) {
20704
xmlSchemaSchemaRelationPtr rel = bucket->relations;
20706
if ((rel->bucket != NULL) &&
20707
((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
20708
if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20712
} while (rel != NULL);
20718
xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20719
xmlSchemaBucketPtr rootBucket)
20721
xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20722
xmlSchemaTreeItemPtr item, *items;
20723
int nbItems, i, ret = 0;
20724
xmlSchemaBucketPtr oldbucket = con->bucket;
20725
xmlSchemaElementPtr elemDecl;
20727
#define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20729
if ((con->pending == NULL) ||
20730
(con->pending->nbItems == 0))
20734
* Since xmlSchemaFixupComplexType() will create new particles
20735
* (local components), and those particle components need a bucket
20736
* on the constructor, we'll assure here that the constructor has
20738
* TODO: Think about storing locals _only_ on the main bucket.
20740
if (con->bucket == NULL)
20741
con->bucket = rootBucket;
20744
* SPEC (src-redefine):
20745
* (6.2) "If it has no such self-reference, then all of the
20746
* following must be true:"
20748
* (6.2.2) The {model group} of the model group definition which
20749
* corresponds to it per XML Representation of Model Group
20750
* Definition Schema Components (ļæ½3.7.2) must be a ļæ½valid
20751
* restrictionļæ½ of the {model group} of that model group definition
20752
* in I, as defined in Particle Valid (Restriction) (ļæ½3.9.6)."
20754
xmlSchemaCheckSRCRedefineFirst(pctxt);
20757
* Add global components to the schemata's hash tables.
20759
xmlSchemaAddComponents(pctxt, rootBucket);
20761
pctxt->ctxtType = NULL;
20762
items = (xmlSchemaTreeItemPtr *) con->pending->items;
20763
nbItems = con->pending->nbItems;
20765
* Now that we have parsed *all* the schema document(s) and converted
20766
* them to schema components, we can resolve references, apply component
20767
* constraints, create the FSA from the content model, etc.
20770
* Resolve references of..
20772
* 1. element declarations:
20773
* - the type definition
20774
* - the substitution group affiliation
20775
* 2. simple/complex types:
20776
* - the base type definition
20777
* - the memberTypes of union types
20778
* - the itemType of list types
20779
* 3. attributes declarations and attribute uses:
20780
* - the type definition
20781
* - if an attribute use, then the attribute declaration
20782
* 4. attribute group references:
20783
* - the attribute group definition
20785
* - the term of the particle (e.g. a model group)
20786
* 6. IDC key-references:
20787
* - the referenced IDC 'key' or 'unique' definition
20788
* 7. Attribute prohibitions which had a "ref" attribute.
20790
for (i = 0; i < nbItems; i++) {
20792
switch (item->type) {
20793
case XML_SCHEMA_TYPE_ELEMENT:
20794
xmlSchemaResolveElementReferences(
20795
(xmlSchemaElementPtr) item, pctxt);
20798
case XML_SCHEMA_TYPE_COMPLEX:
20799
case XML_SCHEMA_TYPE_SIMPLE:
20800
xmlSchemaResolveTypeReferences(
20801
(xmlSchemaTypePtr) item, pctxt);
20804
case XML_SCHEMA_TYPE_ATTRIBUTE:
20805
xmlSchemaResolveAttrTypeReferences(
20806
(xmlSchemaAttributePtr) item, pctxt);
20809
case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
20810
xmlSchemaResolveAttrUseReferences(
20811
(xmlSchemaAttributeUsePtr) item, pctxt);
20814
case XML_SCHEMA_EXTRA_QNAMEREF:
20815
if ((WXS_QNAME_CAST item)->itemType ==
20816
XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
20818
xmlSchemaResolveAttrGroupReferences(
20819
WXS_QNAME_CAST item, pctxt);
20823
case XML_SCHEMA_TYPE_SEQUENCE:
20824
case XML_SCHEMA_TYPE_CHOICE:
20825
case XML_SCHEMA_TYPE_ALL:
20826
xmlSchemaResolveModelGroupParticleReferences(pctxt,
20827
WXS_MODEL_GROUP_CAST item);
20830
case XML_SCHEMA_TYPE_IDC_KEY:
20831
case XML_SCHEMA_TYPE_IDC_UNIQUE:
20832
case XML_SCHEMA_TYPE_IDC_KEYREF:
20833
xmlSchemaResolveIDCKeyReferences(
20834
(xmlSchemaIDCPtr) item, pctxt);
20837
case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
20839
* Handle attribue prohibition which had a
20842
xmlSchemaResolveAttrUseProhibReferences(
20843
WXS_ATTR_PROHIB_CAST item, pctxt);
20850
if (pctxt->nberrors != 0)
20854
* Now that all references are resolved we
20855
* can check for circularity of...
20856
* 1. the base axis of type definitions
20857
* 2. nested model group definitions
20858
* 3. nested attribute group definitions
20859
* TODO: check for circual substitution groups.
20861
for (i = 0; i < nbItems; i++) {
20864
* Let's better stop on the first error here.
20866
switch (item->type) {
20867
case XML_SCHEMA_TYPE_COMPLEX:
20868
case XML_SCHEMA_TYPE_SIMPLE:
20869
xmlSchemaCheckTypeDefCircular(
20870
(xmlSchemaTypePtr) item, pctxt);
20872
if (pctxt->nberrors != 0)
20875
case XML_SCHEMA_TYPE_GROUP:
20876
xmlSchemaCheckGroupDefCircular(
20877
(xmlSchemaModelGroupDefPtr) item, pctxt);
20879
if (pctxt->nberrors != 0)
20882
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20883
xmlSchemaCheckAttrGroupCircular(
20884
(xmlSchemaAttributeGroupPtr) item, pctxt);
20886
if (pctxt->nberrors != 0)
20893
if (pctxt->nberrors != 0)
20896
* Model group definition references:
20897
* Such a reference is reflected by a particle at the component
20898
* level. Until now the 'term' of such particles pointed
20899
* to the model group definition; this was done, in order to
20900
* ease circularity checks. Now we need to set the 'term' of
20901
* such particles to the model group of the model group definition.
20903
for (i = 0; i < nbItems; i++) {
20905
switch (item->type) {
20906
case XML_SCHEMA_TYPE_SEQUENCE:
20907
case XML_SCHEMA_TYPE_CHOICE:
20908
xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
20909
WXS_MODEL_GROUP_CAST item);
20915
if (pctxt->nberrors != 0)
20918
* Expand attribute group references of attribute group definitions.
20920
for (i = 0; i < nbItems; i++) {
20922
switch (item->type) {
20923
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20924
if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
20925
WXS_ATTR_GROUP_HAS_REFS(item))
20927
xmlSchemaAttributeGroupExpandRefs(pctxt,
20928
WXS_ATTR_GROUP_CAST item);
20936
if (pctxt->nberrors != 0)
20939
* First compute the variety of simple types. This is needed as
20940
* a seperate step, since otherwise we won't be able to detect
20941
* circular union types in all cases.
20943
for (i = 0; i < nbItems; i++) {
20945
switch (item->type) {
20946
case XML_SCHEMA_TYPE_SIMPLE:
20947
if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
20948
xmlSchemaFixupSimpleTypeStageOne(pctxt,
20949
(xmlSchemaTypePtr) item);
20957
if (pctxt->nberrors != 0)
20960
* Detect circular union types. Note that this needs the variety to
20961
* be already computed.
20963
for (i = 0; i < nbItems; i++) {
20965
switch (item->type) {
20966
case XML_SCHEMA_TYPE_SIMPLE:
20967
if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
20968
xmlSchemaCheckUnionTypeDefCircular(pctxt,
20969
(xmlSchemaTypePtr) item);
20977
if (pctxt->nberrors != 0)
20981
* Do the complete type fixup for simple types.
20983
for (i = 0; i < nbItems; i++) {
20985
switch (item->type) {
20986
case XML_SCHEMA_TYPE_SIMPLE:
20987
if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
20988
xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
20996
if (pctxt->nberrors != 0)
20999
* At this point we need build and check all simple types.
21002
* Apply contraints for attribute declarations.
21004
for (i = 0; i < nbItems; i++) {
21006
switch (item->type) {
21007
case XML_SCHEMA_TYPE_ATTRIBUTE:
21008
xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
21015
if (pctxt->nberrors != 0)
21018
* Apply constraints for attribute uses.
21020
for (i = 0; i < nbItems; i++) {
21022
switch (item->type) {
21023
case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21024
if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
21025
xmlSchemaCheckAttrUsePropsCorrect(pctxt,
21026
WXS_ATTR_USE_CAST item);
21034
if (pctxt->nberrors != 0)
21038
* Apply constraints for attribute group definitions.
21040
for (i = 0; i < nbItems; i++) {
21042
switch (item->type) {
21043
case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21044
if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
21045
( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
21047
xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
21055
if (pctxt->nberrors != 0)
21059
* Apply constraints for redefinitions.
21061
if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
21062
xmlSchemaCheckSRCRedefineSecond(pctxt);
21063
if (pctxt->nberrors != 0)
21067
* Complex types are builded and checked.
21069
for (i = 0; i < nbItems; i++) {
21070
item = con->pending->items[i];
21071
switch (item->type) {
21072
case XML_SCHEMA_TYPE_COMPLEX:
21073
if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21074
xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
21082
if (pctxt->nberrors != 0)
21086
* The list could have changed, since xmlSchemaFixupComplexType()
21087
* will create particles and model groups in some cases.
21089
items = (xmlSchemaTreeItemPtr *) con->pending->items;
21090
nbItems = con->pending->nbItems;
21093
* Apply some constraints for element declarations.
21095
for (i = 0; i < nbItems; i++) {
21097
switch (item->type) {
21098
case XML_SCHEMA_TYPE_ELEMENT:
21099
elemDecl = (xmlSchemaElementPtr) item;
21101
if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
21103
xmlSchemaCheckElementDeclComponent(
21104
(xmlSchemaElementPtr) elemDecl, pctxt);
21108
#ifdef WXS_ELEM_DECL_CONS_ENABLED
21110
* Schema Component Constraint: Element Declarations Consistent
21111
* Apply this constraint to local types of element declarations.
21113
if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
21114
(WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
21115
(WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
21117
xmlSchemaCheckElementDeclConsistent(pctxt,
21118
WXS_BASIC_CAST elemDecl,
21119
WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
21128
if (pctxt->nberrors != 0)
21132
* Finally we can build the automaton from the content model of
21136
for (i = 0; i < nbItems; i++) {
21138
switch (item->type) {
21139
case XML_SCHEMA_TYPE_COMPLEX:
21140
xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
21147
if (pctxt->nberrors != 0)
21150
* URGENT TODO: cos-element-consistent
21163
* Reset the constructor. This is needed for XSI acquisition, since
21164
* those items will be processed over and over again for every XSI
21165
* if not cleared here.
21167
con->bucket = oldbucket;
21168
con->pending->nbItems = 0;
21169
if (con->substGroups != NULL) {
21170
xmlHashFree(con->substGroups,
21171
(xmlHashDeallocator) xmlSchemaSubstGroupFree);
21172
con->substGroups = NULL;
21174
if (con->redefs != NULL) {
21175
xmlSchemaRedefListFree(con->redefs);
21176
con->redefs = NULL;
21182
* @ctxt: a schema validation context
21184
* parse a schema definition resource and build an internal
21185
* XML Shema struture which can be used to validate instances.
21187
* Returns the internal XML Schema structure built from the resource or
21188
* NULL in case of error
21191
xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
21193
xmlSchemaPtr mainSchema = NULL;
21194
xmlSchemaBucketPtr bucket = NULL;
21198
* This one is used if the schema to be parsed was specified via
21199
* the API; i.e. not automatically by the validated instance document.
21202
xmlSchemaInitTypes();
21207
/* TODO: Init the context. Is this all we need?*/
21208
ctxt->nberrors = 0;
21212
/* Create the *main* schema. */
21213
mainSchema = xmlSchemaNewSchema(ctxt);
21214
if (mainSchema == NULL)
21217
* Create the schema constructor.
21219
if (ctxt->constructor == NULL) {
21220
ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
21221
if (ctxt->constructor == NULL)
21223
/* Take ownership of the constructor to be able to free it. */
21224
ctxt->ownsConstructor = 1;
21226
ctxt->constructor->mainSchema = mainSchema;
21228
* Locate and add the schema document.
21230
res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
21231
ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
21232
NULL, NULL, &bucket);
21238
if (bucket == NULL) {
21239
/* TODO: Error code, actually we failed to *locate* the schema. */
21241
xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21243
"Failed to locate the main schema resource at '%s'",
21246
xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21248
"Failed to locate the main schema resource",
21252
/* Then do the parsing for good. */
21253
if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
21255
if (ctxt->nberrors != 0)
21258
mainSchema->doc = bucket->doc;
21259
mainSchema->preserve = ctxt->preserve;
21261
ctxt->schema = mainSchema;
21263
if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
21267
* TODO: This is not nice, since we cannot distinguish from the
21268
* result if there was an internal error or not.
21271
if (ctxt->nberrors != 0) {
21273
xmlSchemaFree(mainSchema);
21276
if (ctxt->constructor) {
21277
xmlSchemaConstructionCtxtFree(ctxt->constructor);
21278
ctxt->constructor = NULL;
21279
ctxt->ownsConstructor = 0;
21282
ctxt->schema = NULL;
21283
return(mainSchema);
21286
* Quite verbose, but should catch internal errors, which were
21287
* not communitated.
21290
xmlSchemaFree(mainSchema);
21293
if (ctxt->constructor) {
21294
xmlSchemaConstructionCtxtFree(ctxt->constructor);
21295
ctxt->constructor = NULL;
21296
ctxt->ownsConstructor = 0;
21298
PERROR_INT2("xmlSchemaParse",
21299
"An internal error occured");
21300
ctxt->schema = NULL;
21305
* xmlSchemaSetParserErrors:
21306
* @ctxt: a schema validation context
21307
* @err: the error callback
21308
* @warn: the warning callback
21309
* @ctx: contextual data for the callbacks
21311
* Set the callback functions used to handle errors for a validation context
21314
xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21315
xmlSchemaValidityErrorFunc err,
21316
xmlSchemaValidityWarningFunc warn, void *ctx)
21321
ctxt->warning = warn;
21322
ctxt->errCtxt = ctx;
21323
if (ctxt->vctxt != NULL)
21324
xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21328
* xmlSchemaSetParserStructuredErrors:
21329
* @ctxt: a schema parser context
21330
* @serror: the structured error function
21331
* @ctx: the functions context
21333
* Set the structured error callback
21336
xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
21337
xmlStructuredErrorFunc serror,
21342
ctxt->serror = serror;
21343
ctxt->errCtxt = ctx;
21344
if (ctxt->vctxt != NULL)
21345
xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21349
* xmlSchemaGetParserErrors:
21350
* @ctxt: a XMl-Schema parser context
21351
* @err: the error callback result
21352
* @warn: the warning callback result
21353
* @ctx: contextual data for the callbacks result
21355
* Get the callback information used to handle errors for a parser context
21357
* Returns -1 in case of failure, 0 otherwise
21360
xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21361
xmlSchemaValidityErrorFunc * err,
21362
xmlSchemaValidityWarningFunc * warn, void **ctx)
21367
*err = ctxt->error;
21369
*warn = ctxt->warning;
21371
*ctx = ctxt->errCtxt;
21376
* xmlSchemaFacetTypeToString:
21377
* @type: the facet type
21379
* Convert the xmlSchemaTypeType to a char string.
21381
* Returns the char string representation of the facet type if the
21382
* type is a facet and an "Internal Error" string otherwise.
21384
static const xmlChar *
21385
xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21388
case XML_SCHEMA_FACET_PATTERN:
21389
return (BAD_CAST "pattern");
21390
case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21391
return (BAD_CAST "maxExclusive");
21392
case XML_SCHEMA_FACET_MAXINCLUSIVE:
21393
return (BAD_CAST "maxInclusive");
21394
case XML_SCHEMA_FACET_MINEXCLUSIVE:
21395
return (BAD_CAST "minExclusive");
21396
case XML_SCHEMA_FACET_MININCLUSIVE:
21397
return (BAD_CAST "minInclusive");
21398
case XML_SCHEMA_FACET_WHITESPACE:
21399
return (BAD_CAST "whiteSpace");
21400
case XML_SCHEMA_FACET_ENUMERATION:
21401
return (BAD_CAST "enumeration");
21402
case XML_SCHEMA_FACET_LENGTH:
21403
return (BAD_CAST "length");
21404
case XML_SCHEMA_FACET_MAXLENGTH:
21405
return (BAD_CAST "maxLength");
21406
case XML_SCHEMA_FACET_MINLENGTH:
21407
return (BAD_CAST "minLength");
21408
case XML_SCHEMA_FACET_TOTALDIGITS:
21409
return (BAD_CAST "totalDigits");
21410
case XML_SCHEMA_FACET_FRACTIONDIGITS:
21411
return (BAD_CAST "fractionDigits");
21415
return (BAD_CAST "Internal Error");
21418
static xmlSchemaWhitespaceValueType
21419
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21422
* The normalization type can be changed only for types which are derived
21425
if (type->type == XML_SCHEMA_TYPE_BASIC) {
21427
* Note that we assume a whitespace of preserve for anySimpleType.
21429
if ((type->builtInType == XML_SCHEMAS_STRING) ||
21430
(type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21431
return(XML_SCHEMA_WHITESPACE_PRESERVE);
21432
else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21433
return(XML_SCHEMA_WHITESPACE_REPLACE);
21436
* For all ļæ½atomicļæ½ datatypes other than string (and types ļæ½derivedļæ½
21437
* by ļæ½restrictionļæ½ from it) the value of whiteSpace is fixed to
21439
* Note that this includes built-in list datatypes.
21441
return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21443
} else if (WXS_IS_LIST(type)) {
21445
* For list types the facet "whiteSpace" is fixed to "collapse".
21447
return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21448
} else if (WXS_IS_UNION(type)) {
21449
return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21450
} else if (WXS_IS_ATOMIC(type)) {
21451
if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
21452
return (XML_SCHEMA_WHITESPACE_PRESERVE);
21453
else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
21454
return (XML_SCHEMA_WHITESPACE_REPLACE);
21456
return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21461
/************************************************************************
21463
* Simple type validation *
21465
************************************************************************/
21468
/************************************************************************
21470
* DOM Validation code *
21472
************************************************************************/
21475
* xmlSchemaAssembleByLocation:
21476
* @pctxt: a schema parser context
21477
* @vctxt: a schema validation context
21478
* @schema: the existing schema
21479
* @node: the node that fired the assembling
21480
* @nsName: the namespace name of the new schema
21481
* @location: the location of the schema
21483
* Expands an existing schema by an additional schema.
21485
* Returns 0 if the new schema is correct, a positive error code
21486
* number otherwise and -1 in case of an internal or API error.
21489
xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21490
xmlSchemaPtr schema,
21492
const xmlChar *nsName,
21493
const xmlChar *location)
21496
xmlSchemaParserCtxtPtr pctxt;
21497
xmlSchemaBucketPtr bucket = NULL;
21499
if ((vctxt == NULL) || (schema == NULL))
21502
if (vctxt->pctxt == NULL) {
21503
VERROR_INT("xmlSchemaAssembleByLocation",
21504
"no parser context available");
21507
pctxt = vctxt->pctxt;
21508
if (pctxt->constructor == NULL) {
21509
PERROR_INT("xmlSchemaAssembleByLocation",
21514
* Acquire the schema document.
21516
location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21519
* Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21520
* the process will automatically change this to
21521
* XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21523
ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
21524
location, NULL, NULL, 0, node, NULL, nsName,
21528
if (bucket == NULL) {
21530
* Generate a warning that the document could not be located.
21532
xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21534
"The document at location '%s' could not be acquired",
21535
location, NULL, NULL);
21539
* The first located schema will be handled as if all other
21540
* schemas imported by XSI were imported by this first schema.
21542
if ((bucket != NULL) &&
21543
(WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
21544
WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
21546
* TODO: Is this handled like an import? I.e. is it not an error
21547
* if the schema cannot be located?
21549
if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
21552
* We will reuse the parser context for every schema imported
21553
* directly via XSI. So reset the context.
21555
pctxt->nberrors = 0;
21557
pctxt->doc = bucket->doc;
21559
ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21564
/* Paranoid error channelling. */
21565
if ((ret == 0) && (pctxt->nberrors != 0))
21567
if (pctxt->nberrors == 0) {
21569
* Only bother to fixup pending components, if there was
21571
* For every XSI acquired schema (and its sub-schemata) we will
21572
* fixup the components.
21574
xmlSchemaFixupComponents(pctxt, bucket);
21577
* Not nice, but we need somehow to channel the schema parser
21578
* error to the validation context.
21580
if ((ret != 0) && (vctxt->err == 0))
21582
vctxt->nberrors += pctxt->nberrors;
21584
/* Add to validation error sum. */
21585
vctxt->nberrors += pctxt->nberrors;
21594
static xmlSchemaAttrInfoPtr
21595
xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21598
if (vctxt->nbAttrInfos == 0)
21602
xmlSchemaAttrInfoPtr iattr;
21604
for (i = 0; i < vctxt->nbAttrInfos; i++) {
21605
iattr = vctxt->attrInfos[i];
21606
if (iattr->metaType == metaType)
21615
* xmlSchemaAssembleByXSI:
21616
* @vctxt: a schema validation context
21618
* Expands an existing schema by an additional schema using
21619
* the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21620
* of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21621
* must be set to 1.
21623
* Returns 0 if the new schema is correct, a positive error code
21624
* number otherwise and -1 in case of an internal or API error.
21627
xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21629
const xmlChar *cur, *end;
21630
const xmlChar *nsname = NULL, *location;
21633
xmlSchemaAttrInfoPtr iattr;
21636
* Parse the value; we will assume an even number of values
21637
* to be given (this is how Xerces and XSV work).
21639
* URGENT TODO: !! This needs to work for both
21640
* @noNamespaceSchemaLocation AND @schemaLocation on the same
21643
iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21644
XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
21646
iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21647
XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
21650
cur = iattr->value;
21653
* TODO: Move the string parsing mechanism away from here.
21655
if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
21657
* Get the namespace name.
21659
while (IS_BLANK_CH(*cur))
21662
while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21666
count++; /* TODO: Don't use the schema's dict. */
21667
nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21673
while (IS_BLANK_CH(*cur))
21676
while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21679
if (iattr->metaType ==
21680
XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
21683
* If using @schemaLocation then tuples are expected.
21684
* I.e. the namespace name *and* the document's URI.
21686
xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21688
"The value must consist of tuples: the target namespace "
21689
"name and the document's URI", NULL, NULL, NULL);
21693
count++; /* TODO: Don't use the schema's dict. */
21694
location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21696
ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21697
iattr->node, nsname, location);
21699
VERROR_INT("xmlSchemaAssembleByXSI",
21700
"assembling schemata");
21703
} while (*cur != 0);
21707
static const xmlChar *
21708
xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21709
const xmlChar *prefix)
21711
if (vctxt->sax != NULL) {
21713
xmlSchemaNodeInfoPtr inode;
21715
for (i = vctxt->depth; i >= 0; i--) {
21716
if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21717
inode = vctxt->elemInfos[i];
21718
for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21719
if (((prefix == NULL) &&
21720
(inode->nsBindings[j] == NULL)) ||
21721
((prefix != NULL) && xmlStrEqual(prefix,
21722
inode->nsBindings[j]))) {
21725
* Note that the namespace bindings are already
21726
* in a string dict.
21728
return (inode->nsBindings[j+1]);
21734
#ifdef LIBXML_WRITER_ENABLED
21735
} else if (vctxt->reader != NULL) {
21738
nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21739
if (nsName != NULL) {
21740
const xmlChar *ret;
21742
ret = xmlDictLookup(vctxt->dict, nsName, -1);
21751
if ((vctxt->inode->node == NULL) ||
21752
(vctxt->inode->node->doc == NULL)) {
21753
VERROR_INT("xmlSchemaLookupNamespace",
21754
"no node or node's doc avaliable");
21757
ns = xmlSearchNs(vctxt->inode->node->doc,
21758
vctxt->inode->node, prefix);
21766
* This one works on the schema of the validation context.
21769
xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
21770
xmlSchemaPtr schema,
21772
const xmlChar *value,
21773
xmlSchemaValPtr *val,
21778
if (vctxt && (vctxt->schema == NULL)) {
21779
VERROR_INT("xmlSchemaValidateNotation",
21780
"a schema is needed on the validation context");
21783
ret = xmlValidateQName(value, 1);
21787
xmlChar *localName = NULL;
21788
xmlChar *prefix = NULL;
21790
localName = xmlSplitQName2(value, &prefix);
21791
if (prefix != NULL) {
21792
const xmlChar *nsName = NULL;
21795
nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
21796
else if (node != NULL) {
21797
xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
21802
xmlFree(localName);
21805
if (nsName == NULL) {
21807
xmlFree(localName);
21810
if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
21811
if ((valNeeded) && (val != NULL)) {
21812
(*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
21813
xmlStrdup(nsName));
21820
xmlFree(localName);
21822
if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
21823
if (valNeeded && (val != NULL)) {
21824
(*val) = xmlSchemaNewNOTATIONValue(
21825
BAD_CAST xmlStrdup(value), NULL);
21837
xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
21838
const xmlChar* lname,
21839
const xmlChar* nsname)
21843
lname = xmlDictLookup(vctxt->dict, lname, -1);
21846
if (nsname != NULL) {
21847
nsname = xmlDictLookup(vctxt->dict, nsname, -1);
21848
if (nsname == NULL)
21851
for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
21852
if ((vctxt->nodeQNames->items [i] == lname) &&
21853
(vctxt->nodeQNames->items[i +1] == nsname))
21854
/* Already there */
21857
/* Add new entry. */
21858
i = vctxt->nodeQNames->nbItems;
21859
xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
21860
xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
21864
/************************************************************************
21866
* Validation of identity-constraints (IDC) *
21868
************************************************************************/
21871
* xmlSchemaAugmentIDC:
21872
* @idcDef: the IDC definition
21874
* Creates an augmented IDC definition item.
21876
* Returns the item, or NULL on internal errors.
21879
xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
21880
xmlSchemaValidCtxtPtr vctxt)
21882
xmlSchemaIDCAugPtr aidc;
21884
aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
21885
if (aidc == NULL) {
21886
xmlSchemaVErrMemory(vctxt,
21887
"xmlSchemaAugmentIDC: allocating an augmented IDC definition",
21891
aidc->keyrefDepth = -1;
21892
aidc->def = idcDef;
21894
if (vctxt->aidcs == NULL)
21895
vctxt->aidcs = aidc;
21897
aidc->next = vctxt->aidcs;
21898
vctxt->aidcs = aidc;
21901
* Save if we have keyrefs at all.
21903
if ((vctxt->hasKeyrefs == 0) &&
21904
(idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
21905
vctxt->hasKeyrefs = 1;
21909
* xmlSchemaAugmentImportedIDC:
21910
* @imported: the imported schema
21912
* Creates an augmented IDC definition for the imported schema.
21915
xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
21916
if (imported->schema->idcDef != NULL) {
21917
xmlHashScan(imported->schema->idcDef ,
21918
(xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
21923
* xmlSchemaIDCNewBinding:
21924
* @idcDef: the IDC definition of this binding
21926
* Creates a new IDC binding.
21928
* Returns the new IDC binding, NULL on internal errors.
21930
static xmlSchemaPSVIIDCBindingPtr
21931
xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
21933
xmlSchemaPSVIIDCBindingPtr ret;
21935
ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
21936
sizeof(xmlSchemaPSVIIDCBinding));
21938
xmlSchemaVErrMemory(NULL,
21939
"allocating a PSVI IDC binding item", NULL);
21942
memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
21943
ret->definition = idcDef;
21948
* xmlSchemaIDCStoreNodeTableItem:
21949
* @vctxt: the WXS validation context
21950
* @item: the IDC node table item
21952
* The validation context is used to store IDC node table items.
21953
* They are stored to avoid copying them if IDC node-tables are merged
21954
* with corresponding parent IDC node-tables (bubbling).
21956
* Returns 0 if succeeded, -1 on internal errors.
21959
xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
21960
xmlSchemaPSVIIDCNodePtr item)
21963
* Add to gobal list.
21965
if (vctxt->idcNodes == NULL) {
21966
vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
21967
xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
21968
if (vctxt->idcNodes == NULL) {
21969
xmlSchemaVErrMemory(vctxt,
21970
"allocating the IDC node table item list", NULL);
21973
vctxt->sizeIdcNodes = 20;
21974
} else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
21975
vctxt->sizeIdcNodes *= 2;
21976
vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
21977
xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
21978
sizeof(xmlSchemaPSVIIDCNodePtr));
21979
if (vctxt->idcNodes == NULL) {
21980
xmlSchemaVErrMemory(vctxt,
21981
"re-allocating the IDC node table item list", NULL);
21985
vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
21991
* xmlSchemaIDCStoreKey:
21992
* @vctxt: the WXS validation context
21993
* @item: the IDC key
21995
* The validation context is used to store an IDC key.
21997
* Returns 0 if succeeded, -1 on internal errors.
22000
xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
22001
xmlSchemaPSVIIDCKeyPtr key)
22004
* Add to gobal list.
22006
if (vctxt->idcKeys == NULL) {
22007
vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22008
xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
22009
if (vctxt->idcKeys == NULL) {
22010
xmlSchemaVErrMemory(vctxt,
22011
"allocating the IDC key storage list", NULL);
22014
vctxt->sizeIdcKeys = 40;
22015
} else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
22016
vctxt->sizeIdcKeys *= 2;
22017
vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22018
xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
22019
sizeof(xmlSchemaPSVIIDCKeyPtr));
22020
if (vctxt->idcKeys == NULL) {
22021
xmlSchemaVErrMemory(vctxt,
22022
"re-allocating the IDC key storage list", NULL);
22026
vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
22032
* xmlSchemaIDCAppendNodeTableItem:
22033
* @bind: the IDC binding
22034
* @ntItem: the node-table item
22036
* Appends the IDC node-table item to the binding.
22038
* Returns 0 on success and -1 on internal errors.
22041
xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
22042
xmlSchemaPSVIIDCNodePtr ntItem)
22044
if (bind->nodeTable == NULL) {
22045
bind->sizeNodes = 10;
22046
bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22047
xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
22048
if (bind->nodeTable == NULL) {
22049
xmlSchemaVErrMemory(NULL,
22050
"allocating an array of IDC node-table items", NULL);
22053
} else if (bind->sizeNodes <= bind->nbNodes) {
22054
bind->sizeNodes *= 2;
22055
bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22056
xmlRealloc(bind->nodeTable, bind->sizeNodes *
22057
sizeof(xmlSchemaPSVIIDCNodePtr));
22058
if (bind->nodeTable == NULL) {
22059
xmlSchemaVErrMemory(NULL,
22060
"re-allocating an array of IDC node-table items", NULL);
22064
bind->nodeTable[bind->nbNodes++] = ntItem;
22069
* xmlSchemaIDCAcquireBinding:
22070
* @vctxt: the WXS validation context
22071
* @matcher: the IDC matcher
22073
* Looks up an PSVI IDC binding, for the IDC definition and
22074
* of the given matcher. If none found, a new one is created
22075
* and added to the IDC table.
22077
* Returns an IDC binding or NULL on internal errors.
22079
static xmlSchemaPSVIIDCBindingPtr
22080
xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
22081
xmlSchemaIDCMatcherPtr matcher)
22083
xmlSchemaNodeInfoPtr ielem;
22085
ielem = vctxt->elemInfos[matcher->depth];
22087
if (ielem->idcTable == NULL) {
22088
ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
22089
if (ielem->idcTable == NULL)
22091
return(ielem->idcTable);
22093
xmlSchemaPSVIIDCBindingPtr bind = NULL;
22095
bind = ielem->idcTable;
22097
if (bind->definition == matcher->aidc->def)
22099
if (bind->next == NULL) {
22100
bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
22101
if (bind->next == NULL)
22103
return(bind->next);
22106
} while (bind != NULL);
22111
static xmlSchemaItemListPtr
22112
xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
22113
xmlSchemaIDCMatcherPtr matcher)
22115
if (matcher->targets == NULL)
22116
matcher->targets = xmlSchemaItemListCreate();
22117
return(matcher->targets);
22121
* xmlSchemaIDCFreeKey:
22122
* @key: the IDC key
22124
* Frees an IDC key together with its compiled value.
22127
xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
22129
if (key->val != NULL)
22130
xmlSchemaFreeValue(key->val);
22135
* xmlSchemaIDCFreeBinding:
22137
* Frees an IDC binding. Note that the node table-items
22141
xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
22143
if (bind->nodeTable != NULL)
22144
xmlFree(bind->nodeTable);
22145
if (bind->dupls != NULL)
22146
xmlSchemaItemListFree(bind->dupls);
22151
* xmlSchemaIDCFreeIDCTable:
22152
* @bind: the first IDC binding in the list
22154
* Frees an IDC table, i.e. all the IDC bindings in the list.
22157
xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
22159
xmlSchemaPSVIIDCBindingPtr prev;
22161
while (bind != NULL) {
22164
xmlSchemaIDCFreeBinding(prev);
22169
* xmlSchemaIDCFreeMatcherList:
22170
* @matcher: the first IDC matcher in the list
22172
* Frees a list of IDC matchers.
22175
xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
22177
xmlSchemaIDCMatcherPtr next;
22179
while (matcher != NULL) {
22180
next = matcher->next;
22181
if (matcher->keySeqs != NULL) {
22183
for (i = 0; i < matcher->sizeKeySeqs; i++)
22184
if (matcher->keySeqs[i] != NULL)
22185
xmlFree(matcher->keySeqs[i]);
22186
xmlFree(matcher->keySeqs);
22188
if (matcher->targets != NULL) {
22189
if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22191
xmlSchemaPSVIIDCNodePtr idcNode;
22193
* Node-table items for keyrefs are not stored globally
22194
* to the validation context, since they are not bubbled.
22195
* We need to free them here.
22197
for (i = 0; i < matcher->targets->nbItems; i++) {
22199
(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22200
xmlFree(idcNode->keys);
22204
xmlSchemaItemListFree(matcher->targets);
22212
* xmlSchemaIDCReleaseMatcherList:
22213
* @vctxt: the WXS validation context
22214
* @matcher: the first IDC matcher in the list
22216
* Caches a list of IDC matchers for reuse.
22219
xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
22220
xmlSchemaIDCMatcherPtr matcher)
22222
xmlSchemaIDCMatcherPtr next;
22224
while (matcher != NULL) {
22225
next = matcher->next;
22226
if (matcher->keySeqs != NULL) {
22229
* Don't free the array, but only the content.
22231
for (i = 0; i < matcher->sizeKeySeqs; i++)
22232
if (matcher->keySeqs[i] != NULL) {
22233
xmlFree(matcher->keySeqs[i]);
22234
matcher->keySeqs[i] = NULL;
22237
if (matcher->targets) {
22238
if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22240
xmlSchemaPSVIIDCNodePtr idcNode;
22242
* Node-table items for keyrefs are not stored globally
22243
* to the validation context, since they are not bubbled.
22244
* We need to free them here.
22246
for (i = 0; i < matcher->targets->nbItems; i++) {
22248
(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22249
xmlFree(idcNode->keys);
22253
xmlSchemaItemListFree(matcher->targets);
22254
matcher->targets = NULL;
22256
matcher->next = NULL;
22258
* Cache the matcher.
22260
if (vctxt->idcMatcherCache != NULL)
22261
matcher->nextCached = vctxt->idcMatcherCache;
22262
vctxt->idcMatcherCache = matcher;
22269
* xmlSchemaIDCAddStateObject:
22270
* @vctxt: the WXS validation context
22271
* @matcher: the IDC matcher
22272
* @sel: the XPath information
22273
* @parent: the parent "selector" state object if any
22274
* @type: "selector" or "field"
22276
* Creates/reuses and activates state objects for the given
22277
* XPath information; if the XPath expression consists of unions,
22278
* multiple state objects are created for every unioned expression.
22280
* Returns 0 on success and -1 on internal errors.
22283
xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
22284
xmlSchemaIDCMatcherPtr matcher,
22285
xmlSchemaIDCSelectPtr sel,
22288
xmlSchemaIDCStateObjPtr sto;
22291
* Reuse the state objects from the pool.
22293
if (vctxt->xpathStatePool != NULL) {
22294
sto = vctxt->xpathStatePool;
22295
vctxt->xpathStatePool = sto->next;
22299
* Create a new state object.
22301
sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22303
xmlSchemaVErrMemory(NULL,
22304
"allocating an IDC state object", NULL);
22307
memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22310
* Add to global list.
22312
if (vctxt->xpathStates != NULL)
22313
sto->next = vctxt->xpathStates;
22314
vctxt->xpathStates = sto;
22317
* Free the old xpath validation context.
22319
if (sto->xpathCtxt != NULL)
22320
xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22323
* Create a new XPath (pattern) validation context.
22325
sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22326
(xmlPatternPtr) sel->xpathComp);
22327
if (sto->xpathCtxt == NULL) {
22328
VERROR_INT("xmlSchemaIDCAddStateObject",
22329
"failed to create an XPath validation context");
22333
sto->depth = vctxt->depth;
22334
sto->matcher = matcher;
22336
sto->nbHistory = 0;
22339
xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n",
22346
* xmlSchemaXPathEvaluate:
22347
* @vctxt: the WXS validation context
22348
* @nodeType: the nodeType of the current node
22350
* Evaluates all active XPath state objects.
22352
* Returns the number of IC "field" state objects which resolved to
22353
* this node, 0 if none resolved and -1 on internal errors.
22356
xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22357
xmlElementType nodeType)
22359
xmlSchemaIDCStateObjPtr sto, head = NULL, first;
22360
int res, resolved = 0, depth = vctxt->depth;
22362
if (vctxt->xpathStates == NULL)
22365
if (nodeType == XML_ATTRIBUTE_NODE)
22369
xmlChar *str = NULL;
22370
xmlGenericError(xmlGenericErrorContext,
22371
"IDC: EVAL on %s, depth %d, type %d\n",
22372
xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22373
vctxt->inode->localName), depth, nodeType);
22378
* Process all active XPath state objects.
22380
first = vctxt->xpathStates;
22382
while (sto != head) {
22384
if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
22385
xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n",
22386
sto->matcher->aidc->def->name, sto->sel->xpath);
22388
xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n",
22389
sto->matcher->aidc->def->name, sto->sel->xpath);
22391
if (nodeType == XML_ELEMENT_NODE)
22392
res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22393
vctxt->inode->localName, vctxt->inode->nsName);
22395
res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22396
vctxt->inode->localName, vctxt->inode->nsName);
22399
VERROR_INT("xmlSchemaXPathEvaluate",
22400
"calling xmlStreamPush()");
22409
xmlGenericError(xmlGenericErrorContext, "IDC: "
22413
* Register a match in the state object history.
22415
if (sto->history == NULL) {
22416
sto->history = (int *) xmlMalloc(5 * sizeof(int));
22417
if (sto->history == NULL) {
22418
xmlSchemaVErrMemory(NULL,
22419
"allocating the state object history", NULL);
22422
sto->sizeHistory = 5;
22423
} else if (sto->sizeHistory <= sto->nbHistory) {
22424
sto->sizeHistory *= 2;
22425
sto->history = (int *) xmlRealloc(sto->history,
22426
sto->sizeHistory * sizeof(int));
22427
if (sto->history == NULL) {
22428
xmlSchemaVErrMemory(NULL,
22429
"re-allocating the state object history", NULL);
22433
sto->history[sto->nbHistory++] = depth;
22436
xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n",
22440
if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22441
xmlSchemaIDCSelectPtr sel;
22443
* Activate state objects for the IDC fields of
22444
* the IDC selector.
22447
xmlGenericError(xmlGenericErrorContext, "IDC: "
22448
"activating field states\n");
22450
sel = sto->matcher->aidc->def->fields;
22451
while (sel != NULL) {
22452
if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22453
sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
22457
} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22459
* An IDC key node was found by the IDC field.
22462
xmlGenericError(xmlGenericErrorContext,
22463
"IDC: key found\n");
22466
* Notify that the character value of this node is
22469
if (resolved == 0) {
22470
if ((vctxt->inode->flags &
22471
XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
22472
vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
22477
if (sto->next == NULL) {
22479
* Evaluate field state objects created on this node as well.
22482
sto = vctxt->xpathStates;
22489
static const xmlChar *
22490
xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22492
xmlSchemaPSVIIDCKeyPtr *seq,
22496
xmlChar *value = NULL;
22498
*buf = xmlStrdup(BAD_CAST "[");
22499
for (i = 0; i < count; i++) {
22500
*buf = xmlStrcat(*buf, BAD_CAST "'");
22501
res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22502
xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22505
*buf = xmlStrcat(*buf, BAD_CAST value);
22507
VERROR_INT("xmlSchemaFormatIDCKeySequence",
22508
"failed to compute a canonical value");
22509
*buf = xmlStrcat(*buf, BAD_CAST "???");
22512
*buf = xmlStrcat(*buf, BAD_CAST "', ");
22514
*buf = xmlStrcat(*buf, BAD_CAST "'");
22515
if (value != NULL) {
22520
*buf = xmlStrcat(*buf, BAD_CAST "]");
22522
return (BAD_CAST *buf);
22526
* xmlSchemaXPathPop:
22527
* @vctxt: the WXS validation context
22529
* Pops all XPath states.
22531
* Returns 0 on success and -1 on internal errors.
22534
xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22536
xmlSchemaIDCStateObjPtr sto;
22539
if (vctxt->xpathStates == NULL)
22541
sto = vctxt->xpathStates;
22543
res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22547
} while (sto != NULL);
22552
* xmlSchemaXPathProcessHistory:
22553
* @vctxt: the WXS validation context
22554
* @type: the simple/complex type of the current node if any at all
22555
* @val: the precompiled value
22557
* Processes and pops the history items of the IDC state objects.
22558
* IDC key-sequences are validated/created on IDC bindings.
22560
* Returns 0 on success and -1 on internal errors.
22563
xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22566
xmlSchemaIDCStateObjPtr sto, nextsto;
22567
int res, matchDepth;
22568
xmlSchemaPSVIIDCKeyPtr key = NULL;
22569
xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
22571
if (vctxt->xpathStates == NULL)
22573
sto = vctxt->xpathStates;
22577
xmlChar *str = NULL;
22578
xmlGenericError(xmlGenericErrorContext,
22579
"IDC: BACK on %s, depth %d\n",
22580
xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22581
vctxt->inode->localName), vctxt->depth);
22586
* Evaluate the state objects.
22588
while (sto != NULL) {
22589
res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22591
VERROR_INT("xmlSchemaXPathProcessHistory",
22592
"calling xmlStreamPop()");
22596
xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n",
22599
if (sto->nbHistory == 0)
22600
goto deregister_check;
22602
matchDepth = sto->history[sto->nbHistory -1];
22605
* Only matches at the current depth are of interest.
22607
if (matchDepth != depth) {
22611
if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22613
* NOTE: According to
22614
* http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22615
* ... the simple-content of complex types is also allowed.
22618
if (WXS_IS_COMPLEX(type)) {
22619
if (WXS_HAS_SIMPLE_CONTENT(type)) {
22621
* Sanity check for complex types with simple content.
22623
simpleType = type->contentTypeDef;
22624
if (simpleType == NULL) {
22625
VERROR_INT("xmlSchemaXPathProcessHistory",
22626
"field resolves to a CT with simple content "
22627
"but the CT is missing the ST definition");
22634
if (simpleType == NULL) {
22635
xmlChar *str = NULL;
22638
* Not qualified if the field resolves to a node of non
22641
xmlSchemaCustomErr(ACTXT_CAST vctxt,
22642
XML_SCHEMAV_CVC_IDC, NULL,
22643
WXS_BASIC_CAST sto->matcher->aidc->def,
22644
"The XPath '%s' of a field of %s does evaluate to a node of "
22647
xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22648
FREE_AND_NULL(str);
22650
goto deregister_check;
22653
if ((key == NULL) && (vctxt->inode->val == NULL)) {
22655
* Failed to provide the normalized value; maybe
22656
* the value was invalid.
22658
VERROR(XML_SCHEMAV_CVC_IDC,
22659
WXS_BASIC_CAST sto->matcher->aidc->def,
22660
"Warning: No precomputed value available, the value "
22661
"was either invalid or something strange happend");
22663
goto deregister_check;
22665
xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22666
xmlSchemaPSVIIDCKeyPtr *keySeq;
22670
* The key will be anchored on the matcher's list of
22671
* key-sequences. The position in this list is determined
22672
* by the target node's depth relative to the matcher's
22673
* depth of creation (i.e. the depth of the scope element).
22675
* Element Depth Pos List-entries
22678
* <target/> 2 2 target
22682
* The size of the list is only dependant on the depth of
22684
* An entry will be NULLed in selector_leave, i.e. when
22685
* we hit the target's
22687
pos = sto->depth - matcher->depth;
22688
idx = sto->sel->index;
22691
* Create/grow the array of key-sequences.
22693
if (matcher->keySeqs == NULL) {
22695
matcher->sizeKeySeqs = pos * 2;
22697
matcher->sizeKeySeqs = 10;
22698
matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22699
xmlMalloc(matcher->sizeKeySeqs *
22700
sizeof(xmlSchemaPSVIIDCKeyPtr *));
22701
if (matcher->keySeqs == NULL) {
22702
xmlSchemaVErrMemory(NULL,
22703
"allocating an array of key-sequences",
22707
memset(matcher->keySeqs, 0,
22708
matcher->sizeKeySeqs *
22709
sizeof(xmlSchemaPSVIIDCKeyPtr *));
22710
} else if (pos >= matcher->sizeKeySeqs) {
22711
int i = matcher->sizeKeySeqs;
22713
matcher->sizeKeySeqs *= 2;
22714
matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22715
xmlRealloc(matcher->keySeqs,
22716
matcher->sizeKeySeqs *
22717
sizeof(xmlSchemaPSVIIDCKeyPtr *));
22718
if (matcher->keySeqs == NULL) {
22719
xmlSchemaVErrMemory(NULL,
22720
"reallocating an array of key-sequences",
22725
* The array needs to be NULLed.
22726
* TODO: Use memset?
22728
for (; i < matcher->sizeKeySeqs; i++)
22729
matcher->keySeqs[i] = NULL;
22733
* Get/create the key-sequence.
22735
keySeq = matcher->keySeqs[pos];
22736
if (keySeq == NULL) {
22737
goto create_sequence;
22738
} else if (keySeq[idx] != NULL) {
22739
xmlChar *str = NULL;
22741
* cvc-identity-constraint:
22742
* 3 For each node in the ļæ½target node setļæ½ all
22743
* of the {fields}, with that node as the context
22744
* node, evaluate to either an empty node-set or
22745
* a node-set with exactly one member, which must
22746
* have a simple type.
22748
* The key was already set; report an error.
22750
xmlSchemaCustomErr(ACTXT_CAST vctxt,
22751
XML_SCHEMAV_CVC_IDC, NULL,
22752
WXS_BASIC_CAST matcher->aidc->def,
22753
"The XPath '%s' of a field of %s evaluates to a "
22754
"node-set with more than one member",
22756
xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
22757
FREE_AND_NULL(str);
22759
goto deregister_check;
22765
* Create a key-sequence.
22767
keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
22768
matcher->aidc->def->nbFields *
22769
sizeof(xmlSchemaPSVIIDCKeyPtr));
22770
if (keySeq == NULL) {
22771
xmlSchemaVErrMemory(NULL,
22772
"allocating an IDC key-sequence", NULL);
22775
memset(keySeq, 0, matcher->aidc->def->nbFields *
22776
sizeof(xmlSchemaPSVIIDCKeyPtr));
22777
matcher->keySeqs[pos] = keySeq;
22780
* Create a key once per node only.
22783
key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
22784
sizeof(xmlSchemaPSVIIDCKey));
22786
xmlSchemaVErrMemory(NULL,
22787
"allocating a IDC key", NULL);
22789
matcher->keySeqs[pos] = NULL;
22793
* Consume the compiled value.
22795
key->type = simpleType;
22796
key->val = vctxt->inode->val;
22797
vctxt->inode->val = NULL;
22799
* Store the key in a global list.
22801
if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
22802
xmlSchemaIDCFreeKey(key);
22808
} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22810
xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
22811
/* xmlSchemaPSVIIDCBindingPtr bind; */
22812
xmlSchemaPSVIIDCNodePtr ntItem;
22813
xmlSchemaIDCMatcherPtr matcher;
22814
xmlSchemaIDCPtr idc;
22815
xmlSchemaItemListPtr targets;
22816
int pos, i, j, nbKeys;
22818
* Here we have the following scenario:
22819
* An IDC 'selector' state object resolved to a target node,
22820
* during the time this target node was in the
22821
* ancestor-or-self axis, the 'field' state object(s) looked
22822
* out for matching nodes to create a key-sequence for this
22823
* target node. Now we are back to this target node and need
22824
* to put the key-sequence, together with the target node
22825
* itself, into the node-table of the corresponding IDC
22828
matcher = sto->matcher;
22829
idc = matcher->aidc->def;
22830
nbKeys = idc->nbFields;
22831
pos = depth - matcher->depth;
22833
* Check if the matcher has any key-sequences at all, plus
22834
* if it has a key-sequence for the current target node.
22836
if ((matcher->keySeqs == NULL) ||
22837
(matcher->sizeKeySeqs <= pos)) {
22838
if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22839
goto selector_key_error;
22841
goto selector_leave;
22844
keySeq = &(matcher->keySeqs[pos]);
22845
if (*keySeq == NULL) {
22846
if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22847
goto selector_key_error;
22849
goto selector_leave;
22852
for (i = 0; i < nbKeys; i++) {
22853
if ((*keySeq)[i] == NULL) {
22855
* Not qualified, if not all fields did resolve.
22857
if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
22859
* All fields of a "key" IDC must resolve.
22861
goto selector_key_error;
22863
goto selector_leave;
22867
* All fields did resolve.
22871
* 4.1 If the {identity-constraint category} is unique(/key),
22872
* then no two members of the ļæ½qualified node setļæ½ have
22873
* ļæ½key-sequencesļæ½ whose members are pairwise equal, as
22874
* defined by Equal in [XML Schemas: Datatypes].
22876
* Get the IDC binding from the matcher and check for
22877
* duplicate key-sequences.
22880
bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
22882
targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
22883
if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
22884
(targets->nbItems != 0)) {
22885
xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
22890
* Compare the key-sequences, key by key.
22894
((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
22895
for (j = 0; j < nbKeys; j++) {
22896
ckey = (*keySeq)[j];
22898
res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
22901
} else if (res == 0) {
22903
* One of the keys differs, so the key-sequence
22904
* won't be equal; get out.
22911
* Duplicate key-sequence found.
22916
} while (i < targets->nbItems);
22917
if (i != targets->nbItems) {
22918
xmlChar *str = NULL, *strB = NULL;
22920
* TODO: Try to report the key-sequence.
22922
xmlSchemaCustomErr(ACTXT_CAST vctxt,
22923
XML_SCHEMAV_CVC_IDC, NULL,
22924
WXS_BASIC_CAST idc,
22925
"Duplicate key-sequence %s in %s",
22926
xmlSchemaFormatIDCKeySequence(vctxt, &str,
22927
(*keySeq), nbKeys),
22928
xmlSchemaGetIDCDesignation(&strB, idc));
22929
FREE_AND_NULL(str);
22930
FREE_AND_NULL(strB);
22931
goto selector_leave;
22935
* Add a node-table item to the IDC binding.
22937
ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
22938
sizeof(xmlSchemaPSVIIDCNode));
22939
if (ntItem == NULL) {
22940
xmlSchemaVErrMemory(NULL,
22941
"allocating an IDC node-table item", NULL);
22946
memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
22949
* Store the node-table item in a global list.
22951
if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
22952
if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
22958
ntItem->nodeQNameID = -1;
22961
* Save a cached QName for this node on the IDC node, to be
22962
* able to report it, even if the node is not saved.
22964
ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
22965
vctxt->inode->localName, vctxt->inode->nsName);
22966
if (ntItem->nodeQNameID == -1) {
22974
* Init the node-table item: Save the node, position and
22975
* consume the key-sequence.
22977
ntItem->node = vctxt->node;
22978
ntItem->nodeLine = vctxt->inode->nodeLine;
22979
ntItem->keys = *keySeq;
22982
if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1) {
22984
if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
22985
if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
22987
* Free the item, since keyref items won't be
22988
* put on a global list.
22990
xmlFree(ntItem->keys);
22996
goto selector_leave;
22997
selector_key_error:
22999
xmlChar *str = NULL;
23001
* 4.2.1 (KEY) The ļæ½target node setļæ½ and the
23002
* ļæ½qualified node setļæ½ are equal, that is, every
23003
* member of the ļæ½target node setļæ½ is also a member
23004
* of the ļæ½qualified node setļæ½ and vice versa.
23006
xmlSchemaCustomErr(ACTXT_CAST vctxt,
23007
XML_SCHEMAV_CVC_IDC, NULL,
23008
WXS_BASIC_CAST idc,
23009
"Not all fields of %s evaluate to a node",
23010
xmlSchemaGetIDCDesignation(&str, idc), NULL);
23011
FREE_AND_NULL(str);
23015
* Free the key-sequence if not added to the IDC table.
23017
if ((keySeq != NULL) && (*keySeq != NULL)) {
23021
} /* if selector */
23027
* Deregister state objects if they reach the depth of creation.
23029
if ((sto->nbHistory == 0) && (sto->depth == depth)) {
23031
xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n",
23034
if (vctxt->xpathStates != sto) {
23035
VERROR_INT("xmlSchemaXPathProcessHistory",
23036
"The state object to be removed is not the first "
23039
nextsto = sto->next;
23041
* Unlink from the list of active XPath state objects.
23043
vctxt->xpathStates = sto->next;
23044
sto->next = vctxt->xpathStatePool;
23046
* Link it to the pool of reusable state objects.
23048
vctxt->xpathStatePool = sto;
23052
} /* while (sto != NULL) */
23057
* xmlSchemaIDCRegisterMatchers:
23058
* @vctxt: the WXS validation context
23059
* @elemDecl: the element declaration
23061
* Creates helper objects to evaluate IDC selectors/fields
23064
* Returns 0 if OK and -1 on internal errors.
23067
xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
23068
xmlSchemaElementPtr elemDecl)
23070
xmlSchemaIDCMatcherPtr matcher, last = NULL;
23071
xmlSchemaIDCPtr idc, refIdc;
23072
xmlSchemaIDCAugPtr aidc;
23074
idc = (xmlSchemaIDCPtr) elemDecl->idcs;
23080
xmlChar *str = NULL;
23081
xmlGenericError(xmlGenericErrorContext,
23082
"IDC: REGISTER on %s, depth %d\n",
23083
(char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
23084
vctxt->inode->localName), vctxt->depth);
23088
if (vctxt->inode->idcMatchers != NULL) {
23089
VERROR_INT("xmlSchemaIDCRegisterMatchers",
23090
"The chain of IDC matchers is expected to be empty");
23094
if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23096
* Since IDCs bubbles are expensive we need to know the
23097
* depth at which the bubbles should stop; this will be
23098
* the depth of the top-most keyref IDC. If no keyref
23099
* references a key/unique IDC, the keyrefDepth will
23100
* be -1, indicating that no bubbles are needed.
23102
refIdc = (xmlSchemaIDCPtr) idc->ref->item;
23103
if (refIdc != NULL) {
23105
* Remember that we have keyrefs on this node.
23107
vctxt->inode->hasKeyrefs = 1;
23109
* Lookup the referenced augmented IDC info.
23111
aidc = vctxt->aidcs;
23112
while (aidc != NULL) {
23113
if (aidc->def == refIdc)
23117
if (aidc == NULL) {
23118
VERROR_INT("xmlSchemaIDCRegisterMatchers",
23119
"Could not find an augmented IDC item for an IDC "
23123
if ((aidc->keyrefDepth == -1) ||
23124
(vctxt->depth < aidc->keyrefDepth))
23125
aidc->keyrefDepth = vctxt->depth;
23129
* Lookup the augmented IDC item for the IDC definition.
23131
aidc = vctxt->aidcs;
23132
while (aidc != NULL) {
23133
if (aidc->def == idc)
23137
if (aidc == NULL) {
23138
VERROR_INT("xmlSchemaIDCRegisterMatchers",
23139
"Could not find an augmented IDC item for an IDC definition");
23143
* Create an IDC matcher for every IDC definition.
23145
if (vctxt->idcMatcherCache != NULL) {
23147
* Reuse a cached matcher.
23149
matcher = vctxt->idcMatcherCache;
23150
vctxt->idcMatcherCache = matcher->nextCached;
23151
matcher->nextCached = NULL;
23153
matcher = (xmlSchemaIDCMatcherPtr)
23154
xmlMalloc(sizeof(xmlSchemaIDCMatcher));
23155
if (matcher == NULL) {
23156
xmlSchemaVErrMemory(vctxt,
23157
"allocating an IDC matcher", NULL);
23160
memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
23163
vctxt->inode->idcMatchers = matcher;
23165
last->next = matcher;
23168
matcher->type = IDC_MATCHER;
23169
matcher->depth = vctxt->depth;
23170
matcher->aidc = aidc;
23171
matcher->idcType = aidc->def->type;
23173
xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n");
23176
* Init the automaton state object.
23178
if (xmlSchemaIDCAddStateObject(vctxt, matcher,
23179
idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
23183
} while (idc != NULL);
23188
xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
23189
xmlSchemaNodeInfoPtr ielem)
23191
xmlSchemaPSVIIDCBindingPtr bind;
23192
int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
23193
xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
23194
xmlSchemaPSVIIDCNodePtr *targets, *dupls;
23196
xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
23197
/* vctxt->createIDCNodeTables */
23198
while (matcher != NULL) {
23200
* Skip keyref IDCs and empty IDC target-lists.
23202
if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
23203
WXS_ILIST_IS_EMPTY(matcher->targets))
23205
matcher = matcher->next;
23209
* If we _want_ the IDC node-table to be created in any case
23210
* then do so. Otherwise create them only if keyrefs need them.
23212
if ((! vctxt->createIDCNodeTables) &&
23213
((matcher->aidc->keyrefDepth == -1) ||
23214
(matcher->aidc->keyrefDepth > vctxt->depth)))
23216
matcher = matcher->next;
23220
* Get/create the IDC binding on this element for the IDC definition.
23222
bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23224
if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
23225
dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23226
nbDupls = bind->dupls->nbItems;
23231
if (bind->nodeTable != NULL) {
23232
nbNodeTable = bind->nbNodes;
23237
if ((nbNodeTable == 0) && (nbDupls == 0)) {
23239
* Transfer all IDC target-nodes to the IDC node-table.
23242
(xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23243
bind->sizeNodes = matcher->targets->sizeItems;
23244
bind->nbNodes = matcher->targets->nbItems;
23246
matcher->targets->items = NULL;
23247
matcher->targets->sizeItems = 0;
23248
matcher->targets->nbItems = 0;
23251
* Compare the key-sequences and add to the IDC node-table.
23253
nbTargets = matcher->targets->nbItems;
23254
targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23255
nbFields = matcher->aidc->def->nbFields;
23258
keys = targets[i]->keys;
23261
* Search in already found duplicates first.
23265
if (nbFields == 1) {
23266
res = xmlSchemaAreValuesEqual(keys[0]->val,
23267
dupls[j]->keys[0]->val);
23269
goto internal_error;
23272
* Equal key-sequence.
23278
ntkeys = dupls[j]->keys;
23279
for (k = 0; k < nbFields; k++) {
23280
res = xmlSchemaAreValuesEqual(keys[k]->val,
23283
goto internal_error;
23286
* One of the keys differs.
23293
* Equal key-sequence found.
23299
} while (j < nbDupls);
23304
if (nbFields == 1) {
23305
res = xmlSchemaAreValuesEqual(keys[0]->val,
23306
bind->nodeTable[j]->keys[0]->val);
23308
goto internal_error;
23311
* The key-sequence differs.
23313
goto next_node_table_entry;
23317
ntkeys = bind->nodeTable[j]->keys;
23318
for (k = 0; k < nbFields; k++) {
23319
res = xmlSchemaAreValuesEqual(keys[k]->val,
23322
goto internal_error;
23325
* One of the keys differs.
23327
goto next_node_table_entry;
23332
* Add the duplicate to the list of duplicates.
23334
if (bind->dupls == NULL) {
23335
bind->dupls = xmlSchemaItemListCreate();
23336
if (bind->dupls == NULL)
23337
goto internal_error;
23339
if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23340
goto internal_error;
23342
* Remove the duplicate entry from the IDC node-table.
23344
bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23349
next_node_table_entry:
23351
} while (j < nbNodeTable);
23354
* If everything is fine, then add the IDC target-node to
23355
* the IDC node-table.
23357
if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23358
goto internal_error;
23362
} while (i < nbTargets);
23364
matcher = matcher->next;
23373
* xmlSchemaBubbleIDCNodeTables:
23374
* @depth: the current tree depth
23376
* Merges IDC bindings of an element at @depth into the corresponding IDC
23377
* bindings of its parent element. If a duplicate note-table entry is found,
23378
* both, the parent node-table entry and child entry are discarded from the
23379
* node-table of the parent.
23381
* Returns 0 if OK and -1 on internal errors.
23384
xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23386
xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23387
xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
23388
xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
23389
xmlSchemaIDCAugPtr aidc;
23390
int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23392
bind = vctxt->inode->idcTable;
23393
if (bind == NULL) {
23394
/* Fine, no table, no bubbles. */
23398
parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23400
* Walk all bindings; create new or add to existing bindings.
23401
* Remove duplicate key-sequences.
23403
while (bind != NULL) {
23405
if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
23408
* Check if the key/unique IDC table needs to be bubbled.
23410
if (! vctxt->createIDCNodeTables) {
23411
aidc = vctxt->aidcs;
23413
if (aidc->def == bind->definition) {
23414
if ((aidc->keyrefDepth == -1) ||
23415
(aidc->keyrefDepth >= vctxt->depth)) {
23421
} while (aidc != NULL);
23424
if (parTable != NULL)
23425
parBind = *parTable;
23427
* Search a matching parent binding for the
23430
while (parBind != NULL) {
23431
if (parBind->definition == bind->definition)
23433
parBind = parBind->next;
23436
if (parBind != NULL) {
23438
* Compare every node-table entry of the child node,
23439
* i.e. the key-sequence within, ...
23441
oldNum = parBind->nbNodes; /* Skip newly added items. */
23443
if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
23444
oldDupls = parBind->dupls->nbItems;
23445
dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23451
parNodes = parBind->nodeTable;
23452
nbFields = bind->definition->nbFields;
23454
for (i = 0; i < bind->nbNodes; i++) {
23455
node = bind->nodeTable[i];
23459
* ...with every key-sequence of the parent node, already
23460
* evaluated to be a duplicate key-sequence.
23464
while (j < oldDupls) {
23465
if (nbFields == 1) {
23466
ret = xmlSchemaAreValuesEqual(
23467
node->keys[0]->val,
23468
dupls[j]->keys[0]->val);
23470
goto internal_error;
23476
parNode = dupls[j];
23477
for (k = 0; k < nbFields; k++) {
23478
ret = xmlSchemaAreValuesEqual(
23479
node->keys[k]->val,
23480
parNode->keys[k]->val);
23482
goto internal_error;
23488
/* Duplicate found. */
23492
if (j != oldDupls) {
23493
/* Duplicate found. Skip this entry. */
23498
* ... and with every key-sequence of the parent node.
23502
while (j < oldNum) {
23503
parNode = parNodes[j];
23504
if (nbFields == 1) {
23505
ret = xmlSchemaAreValuesEqual(
23506
node->keys[0]->val,
23507
parNode->keys[0]->val);
23509
goto internal_error;
23515
for (k = 0; k < nbFields; k++) {
23516
ret = xmlSchemaAreValuesEqual(
23517
node->keys[k]->val,
23518
parNode->keys[k]->val);
23520
goto internal_error;
23526
/* Duplicate found. */
23532
* Handle duplicates. Move the duplicate in
23533
* the parent's node-table to the list of
23537
parBind->nbNodes--;
23539
* Move last old item to pos of duplicate.
23541
parNodes[j] = parNodes[oldNum];
23543
if (parBind->nbNodes != oldNum) {
23545
* If new items exist, move last new item to
23546
* last of old items.
23549
parNodes[parBind->nbNodes];
23551
if (parBind->dupls == NULL) {
23552
parBind->dupls = xmlSchemaItemListCreate();
23553
if (parBind->dupls == NULL)
23554
goto internal_error;
23556
xmlSchemaItemListAdd(parBind->dupls, parNode);
23559
* Add the node-table entry (node and key-sequence) of
23560
* the child node to the node table of the parent node.
23562
if (parBind->nodeTable == NULL) {
23563
parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23564
xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
23565
if (parBind->nodeTable == NULL) {
23566
xmlSchemaVErrMemory(NULL,
23567
"allocating IDC list of node-table items", NULL);
23568
goto internal_error;
23570
parBind->sizeNodes = 1;
23571
} else if (parBind->nbNodes >= parBind->sizeNodes) {
23572
parBind->sizeNodes *= 2;
23573
parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23574
xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
23575
sizeof(xmlSchemaPSVIIDCNodePtr));
23576
if (parBind->nodeTable == NULL) {
23577
xmlSchemaVErrMemory(NULL,
23578
"re-allocating IDC list of node-table items", NULL);
23579
goto internal_error;
23582
parNodes = parBind->nodeTable;
23584
* Append the new node-table entry to the 'new node-table
23585
* entries' section.
23587
parNodes[parBind->nbNodes++] = node;
23595
* No binding for the IDC was found: create a new one and
23596
* copy all node-tables.
23598
parBind = xmlSchemaIDCNewBinding(bind->definition);
23599
if (parBind == NULL)
23600
goto internal_error;
23603
* TODO: Hmm, how to optimize the initial number of
23604
* allocated entries?
23606
if (bind->nbNodes != 0) {
23608
* Add all IDC node-table entries.
23610
if (! vctxt->psviExposeIDCNodeTables) {
23612
* Just move the entries.
23613
* NOTE: this is quite save here, since
23614
* all the keyref lookups have already been
23617
parBind->nodeTable = bind->nodeTable;
23618
bind->nodeTable = NULL;
23619
parBind->sizeNodes = bind->sizeNodes;
23620
bind->sizeNodes = 0;
23621
parBind->nbNodes = bind->nbNodes;
23625
* Copy the entries.
23627
parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23628
xmlMalloc(bind->nbNodes *
23629
sizeof(xmlSchemaPSVIIDCNodePtr));
23630
if (parBind->nodeTable == NULL) {
23631
xmlSchemaVErrMemory(NULL,
23632
"allocating an array of IDC node-table "
23634
xmlSchemaIDCFreeBinding(parBind);
23635
goto internal_error;
23637
parBind->sizeNodes = bind->nbNodes;
23638
parBind->nbNodes = bind->nbNodes;
23639
memcpy(parBind->nodeTable, bind->nodeTable,
23640
bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23645
* Move the duplicates.
23647
if (parBind->dupls != NULL)
23648
xmlSchemaItemListFree(parBind->dupls);
23649
parBind->dupls = bind->dupls;
23650
bind->dupls = NULL;
23652
if (*parTable == NULL)
23653
*parTable = parBind;
23655
parBind->next = *parTable;
23656
*parTable = parBind;
23670
* xmlSchemaCheckCVCIDCKeyRef:
23671
* @vctxt: the WXS validation context
23672
* @elemDecl: the element declaration
23674
* Check the cvc-idc-keyref constraints.
23677
xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
23679
xmlSchemaIDCMatcherPtr matcher;
23680
xmlSchemaPSVIIDCBindingPtr bind;
23682
matcher = vctxt->inode->idcMatchers;
23686
while (matcher != NULL) {
23687
if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
23688
matcher->targets &&
23689
matcher->targets->nbItems)
23691
int i, j, k, res, nbFields, hasDupls;
23692
xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
23693
xmlSchemaPSVIIDCNodePtr refNode = NULL;
23695
nbFields = matcher->aidc->def->nbFields;
23698
* Find the IDC node-table for the referenced IDC key/unique.
23700
bind = vctxt->inode->idcTable;
23701
while (bind != NULL) {
23702
if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
23707
hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
23709
* Search for a matching key-sequences.
23711
for (i = 0; i < matcher->targets->nbItems; i++) {
23713
refNode = matcher->targets->items[i];
23714
if (bind != NULL) {
23715
refKeys = refNode->keys;
23716
for (j = 0; j < bind->nbNodes; j++) {
23717
keys = bind->nodeTable[j]->keys;
23718
for (k = 0; k < nbFields; k++) {
23719
res = xmlSchemaAreValuesEqual(keys[k]->val,
23723
else if (res == -1) {
23734
if ((res == 0) && hasDupls) {
23736
* Search in duplicates
23738
for (j = 0; j < bind->dupls->nbItems; j++) {
23739
keys = ((xmlSchemaPSVIIDCNodePtr)
23740
bind->dupls->items[j])->keys;
23741
for (k = 0; k < nbFields; k++) {
23742
res = xmlSchemaAreValuesEqual(keys[k]->val,
23746
else if (res == -1) {
23752
* Match in duplicates found.
23754
xmlChar *str = NULL, *strB = NULL;
23755
xmlSchemaKeyrefErr(vctxt,
23756
XML_SCHEMAV_CVC_IDC, refNode,
23757
(xmlSchemaTypePtr) matcher->aidc->def,
23758
"More than one match found for "
23759
"key-sequence %s of keyref '%s'",
23760
xmlSchemaFormatIDCKeySequence(vctxt, &str,
23761
refNode->keys, nbFields),
23762
xmlSchemaGetComponentQName(&strB,
23763
matcher->aidc->def));
23764
FREE_AND_NULL(str);
23765
FREE_AND_NULL(strB);
23773
xmlChar *str = NULL, *strB = NULL;
23774
xmlSchemaKeyrefErr(vctxt,
23775
XML_SCHEMAV_CVC_IDC, refNode,
23776
(xmlSchemaTypePtr) matcher->aidc->def,
23777
"No match found for key-sequence %s of keyref '%s'",
23778
xmlSchemaFormatIDCKeySequence(vctxt, &str,
23779
refNode->keys, nbFields),
23780
xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
23781
FREE_AND_NULL(str);
23782
FREE_AND_NULL(strB);
23786
matcher = matcher->next;
23788
/* TODO: Return an error if any error encountered. */
23792
/************************************************************************
23794
* XML Reader validation code *
23796
************************************************************************/
23798
static xmlSchemaAttrInfoPtr
23799
xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
23801
xmlSchemaAttrInfoPtr iattr;
23803
* Grow/create list of attribute infos.
23805
if (vctxt->attrInfos == NULL) {
23806
vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23807
xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
23808
vctxt->sizeAttrInfos = 1;
23809
if (vctxt->attrInfos == NULL) {
23810
xmlSchemaVErrMemory(vctxt,
23811
"allocating attribute info list", NULL);
23814
} else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
23815
vctxt->sizeAttrInfos++;
23816
vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23817
xmlRealloc(vctxt->attrInfos,
23818
vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
23819
if (vctxt->attrInfos == NULL) {
23820
xmlSchemaVErrMemory(vctxt,
23821
"re-allocating attribute info list", NULL);
23825
iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
23826
if (iattr->localName != NULL) {
23827
VERROR_INT("xmlSchemaGetFreshAttrInfo",
23828
"attr info not cleared");
23831
iattr->nodeType = XML_ATTRIBUTE_NODE;
23835
* Create an attribute info.
23837
iattr = (xmlSchemaAttrInfoPtr)
23838
xmlMalloc(sizeof(xmlSchemaAttrInfo));
23839
if (iattr == NULL) {
23840
xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
23843
memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
23844
iattr->nodeType = XML_ATTRIBUTE_NODE;
23845
vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
23851
xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
23852
xmlNodePtr attrNode,
23854
const xmlChar *localName,
23855
const xmlChar *nsName,
23860
xmlSchemaAttrInfoPtr attr;
23862
attr = xmlSchemaGetFreshAttrInfo(vctxt);
23863
if (attr == NULL) {
23864
VERROR_INT("xmlSchemaPushAttribute",
23865
"calling xmlSchemaGetFreshAttrInfo()");
23868
attr->node = attrNode;
23869
attr->nodeLine = nodeLine;
23870
attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
23871
attr->localName = localName;
23872
attr->nsName = nsName;
23874
attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
23876
* Evaluate if it's an XSI attribute.
23878
if (nsName != NULL) {
23879
if (xmlStrEqual(localName, BAD_CAST "nil")) {
23880
if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23881
attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
23883
} else if (xmlStrEqual(localName, BAD_CAST "type")) {
23884
if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23885
attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
23887
} else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
23888
if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23889
attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
23891
} else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
23892
if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23893
attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
23895
} else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
23896
attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
23899
attr->value = value;
23901
attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
23902
if (attr->metaType != 0)
23903
attr->state = XML_SCHEMAS_ATTR_META;
23908
* xmlSchemaClearElemInfo:
23909
* @vctxt: the WXS validation context
23910
* @ielem: the element information item
23913
xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
23914
xmlSchemaNodeInfoPtr ielem)
23916
ielem->hasKeyrefs = 0;
23917
ielem->appliedXPath = 0;
23918
if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
23919
FREE_AND_NULL(ielem->localName);
23920
FREE_AND_NULL(ielem->nsName);
23922
ielem->localName = NULL;
23923
ielem->nsName = NULL;
23925
if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
23926
FREE_AND_NULL(ielem->value);
23928
ielem->value = NULL;
23930
if (ielem->val != NULL) {
23932
* PSVI TODO: Be careful not to free it when the value is
23933
* exposed via PSVI.
23935
xmlSchemaFreeValue(ielem->val);
23938
if (ielem->idcMatchers != NULL) {
23940
* REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
23943
xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
23945
xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
23947
ielem->idcMatchers = NULL;
23949
if (ielem->idcTable != NULL) {
23951
* OPTIMIZE TODO: Use a pool of IDC tables??.
23953
xmlSchemaIDCFreeIDCTable(ielem->idcTable);
23954
ielem->idcTable = NULL;
23956
if (ielem->regexCtxt != NULL) {
23957
xmlRegFreeExecCtxt(ielem->regexCtxt);
23958
ielem->regexCtxt = NULL;
23960
if (ielem->nsBindings != NULL) {
23961
xmlFree((xmlChar **)ielem->nsBindings);
23962
ielem->nsBindings = NULL;
23963
ielem->nbNsBindings = 0;
23964
ielem->sizeNsBindings = 0;
23969
* xmlSchemaGetFreshElemInfo:
23970
* @vctxt: the schema validation context
23972
* Creates/reuses and initializes the element info item for
23973
* the currect tree depth.
23975
* Returns the element info item or NULL on API or internal errors.
23977
static xmlSchemaNodeInfoPtr
23978
xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
23980
xmlSchemaNodeInfoPtr info = NULL;
23982
if (vctxt->depth > vctxt->sizeElemInfos) {
23983
VERROR_INT("xmlSchemaGetFreshElemInfo",
23984
"inconsistent depth encountered");
23987
if (vctxt->elemInfos == NULL) {
23988
vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
23989
xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
23990
if (vctxt->elemInfos == NULL) {
23991
xmlSchemaVErrMemory(vctxt,
23992
"allocating the element info array", NULL);
23995
memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
23996
vctxt->sizeElemInfos = 10;
23997
} else if (vctxt->sizeElemInfos <= vctxt->depth) {
23998
int i = vctxt->sizeElemInfos;
24000
vctxt->sizeElemInfos *= 2;
24001
vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24002
xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
24003
sizeof(xmlSchemaNodeInfoPtr));
24004
if (vctxt->elemInfos == NULL) {
24005
xmlSchemaVErrMemory(vctxt,
24006
"re-allocating the element info array", NULL);
24010
* We need the new memory to be NULLed.
24011
* TODO: Use memset instead?
24013
for (; i < vctxt->sizeElemInfos; i++)
24014
vctxt->elemInfos[i] = NULL;
24016
info = vctxt->elemInfos[vctxt->depth];
24018
if (info == NULL) {
24019
info = (xmlSchemaNodeInfoPtr)
24020
xmlMalloc(sizeof(xmlSchemaNodeInfo));
24021
if (info == NULL) {
24022
xmlSchemaVErrMemory(vctxt,
24023
"allocating an element info", NULL);
24026
vctxt->elemInfos[vctxt->depth] = info;
24028
if (info->localName != NULL) {
24029
VERROR_INT("xmlSchemaGetFreshElemInfo",
24030
"elem info has not been cleared");
24034
memset(info, 0, sizeof(xmlSchemaNodeInfo));
24035
info->nodeType = XML_ELEMENT_NODE;
24036
info->depth = vctxt->depth;
24041
#define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24042
#define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24043
#define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24046
xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
24048
xmlSchemaTypePtr type,
24049
xmlSchemaValType valType,
24050
const xmlChar * value,
24051
xmlSchemaValPtr val,
24052
unsigned long length,
24055
int ret, error = 0;
24057
xmlSchemaTypePtr tmpType;
24058
xmlSchemaFacetLinkPtr facetLink;
24059
xmlSchemaFacetPtr facet;
24060
unsigned long len = 0;
24061
xmlSchemaWhitespaceValueType ws;
24064
* In Libxml2, derived built-in types have currently no explicit facets.
24066
if (type->type == XML_SCHEMA_TYPE_BASIC)
24070
* NOTE: Do not jump away, if the facetSet of the given type is
24071
* empty: until now, "pattern" and "enumeration" facets of the
24072
* *base types* need to be checked as well.
24074
if (type->facetSet == NULL)
24075
goto pattern_and_enum;
24077
if (! WXS_IS_ATOMIC(type)) {
24078
if (WXS_IS_LIST(type))
24081
goto pattern_and_enum;
24084
* Whitespace handling is only of importance for string-based
24087
tmpType = xmlSchemaGetPrimitiveType(type);
24088
if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
24089
WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
24090
ws = xmlSchemaGetWhiteSpaceFacetValue(type);
24092
ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
24094
* If the value was not computed (for string or
24095
* anySimpleType based types), then use the provided
24101
valType = xmlSchemaGetValType(val);
24104
for (facetLink = type->facetSet; facetLink != NULL;
24105
facetLink = facetLink->next) {
24107
* Skip the pattern "whiteSpace": it is used to
24108
* format the character content beforehand.
24110
switch (facetLink->facet->type) {
24111
case XML_SCHEMA_FACET_WHITESPACE:
24112
case XML_SCHEMA_FACET_PATTERN:
24113
case XML_SCHEMA_FACET_ENUMERATION:
24115
case XML_SCHEMA_FACET_LENGTH:
24116
case XML_SCHEMA_FACET_MINLENGTH:
24117
case XML_SCHEMA_FACET_MAXLENGTH:
24118
ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
24119
valType, value, val, &len, ws);
24122
ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
24123
valType, value, val, ws);
24127
AERROR_INT("xmlSchemaValidateFacets",
24128
"validating against a atomic type facet");
24130
} else if (ret > 0) {
24132
xmlSchemaFacetErr(actxt, ret, node,
24133
value, len, type, facetLink->facet, NULL, NULL, NULL);
24143
if (! WXS_IS_LIST(type))
24144
goto pattern_and_enum;
24146
* "length", "minLength" and "maxLength" of list types.
24149
for (facetLink = type->facetSet; facetLink != NULL;
24150
facetLink = facetLink->next) {
24152
switch (facetLink->facet->type) {
24153
case XML_SCHEMA_FACET_LENGTH:
24154
case XML_SCHEMA_FACET_MINLENGTH:
24155
case XML_SCHEMA_FACET_MAXLENGTH:
24156
ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
24157
value, length, NULL);
24163
AERROR_INT("xmlSchemaValidateFacets",
24164
"validating against a list type facet");
24166
} else if (ret > 0) {
24168
xmlSchemaFacetErr(actxt, ret, node,
24169
value, length, type, facetLink->facet, NULL, NULL, NULL);
24182
* Process enumerations. Facet values are in the value space
24183
* of the defining type's base type. This seems to be a bug in the
24184
* XML Schema 1.0 spec. Use the whitespace type of the base type.
24185
* Only the first set of enumerations in the ancestor-or-self axis
24186
* is used for validation.
24191
for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
24192
if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
24195
ret = xmlSchemaAreValuesEqual(facet->val, val);
24198
else if (ret < 0) {
24199
AERROR_INT("xmlSchemaValidateFacets",
24200
"validating against an enumeration facet");
24207
* Break on the first set of enumerations. Any additional
24208
* enumerations which might be existent on the ancestors
24209
* of the current type are restricted by this set; thus
24210
* *must* *not* be taken into account.
24214
tmpType = tmpType->baseType;
24215
} while ((tmpType != NULL) &&
24216
(tmpType->type != XML_SCHEMA_TYPE_BASIC));
24217
if (found && (ret == 0)) {
24218
ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
24220
xmlSchemaFacetErr(actxt, ret, node,
24221
value, 0, type, NULL, NULL, NULL, NULL);
24232
* Process patters. Pattern facets are ORed at type level
24233
* and ANDed if derived. Walk the base type axis.
24239
for (facetLink = tmpType->facetSet; facetLink != NULL;
24240
facetLink = facetLink->next) {
24241
if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
24245
* NOTE that for patterns, @value needs to be the
24246
* normalized vaule.
24248
ret = xmlRegexpExec(facetLink->facet->regexp, value);
24251
else if (ret < 0) {
24252
AERROR_INT("xmlSchemaValidateFacets",
24253
"validating against a pattern facet");
24257
* Save the last non-validating facet.
24259
facet = facetLink->facet;
24262
if (found && (ret != 1)) {
24263
ret = XML_SCHEMAV_CVC_PATTERN_VALID;
24265
xmlSchemaFacetErr(actxt, ret, node,
24266
value, 0, type, facet, NULL, NULL, NULL);
24273
tmpType = tmpType->baseType;
24274
} while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24281
xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
24282
const xmlChar *value)
24284
switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
24285
case XML_SCHEMA_WHITESPACE_COLLAPSE:
24286
return (xmlSchemaCollapseString(value));
24287
case XML_SCHEMA_WHITESPACE_REPLACE:
24288
return (xmlSchemaWhiteSpaceReplace(value));
24295
xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24296
const xmlChar *value,
24297
xmlSchemaValPtr *val,
24301
const xmlChar *nsName;
24302
xmlChar *local, *prefix = NULL;
24304
ret = xmlValidateQName(value, 1);
24307
VERROR_INT("xmlSchemaValidateQName",
24308
"calling xmlValidateQName()");
24311
return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
24314
* NOTE: xmlSplitQName2 will always return a duplicated
24317
local = xmlSplitQName2(value, &prefix);
24319
local = xmlStrdup(value);
24321
* OPTIMIZE TODO: Use flags for:
24322
* - is there any namespace binding?
24323
* - is there a default namespace?
24325
nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24327
if (prefix != NULL) {
24330
* A namespace must be found if the prefix is
24333
if (nsName == NULL) {
24334
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24335
xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
24336
WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24337
"The QName value '%s' has no "
24338
"corresponding namespace declaration in "
24339
"scope", value, NULL);
24345
if (valNeeded && val) {
24346
if (nsName != NULL)
24347
*val = xmlSchemaNewQNameValue(
24348
BAD_CAST xmlStrdup(nsName), BAD_CAST local);
24350
*val = xmlSchemaNewQNameValue(NULL,
24361
xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24363
xmlSchemaTypePtr type,
24364
const xmlChar *value,
24365
xmlSchemaValPtr *retVal,
24370
int ret = 0, valNeeded = (retVal) ? 1 : 0;
24371
xmlSchemaValPtr val = NULL;
24372
/* xmlSchemaWhitespaceValueType ws; */
24373
xmlChar *normValue = NULL;
24375
#define NORMALIZE(atype) \
24376
if ((! isNormalized) && \
24377
(normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24378
normValue = xmlSchemaNormalizeValue(atype, value); \
24379
if (normValue != NULL) \
24380
value = normValue; \
24381
isNormalized = 1; \
24384
if ((retVal != NULL) && (*retVal != NULL)) {
24385
xmlSchemaFreeValue(*retVal);
24389
* 3.14.4 Simple Type Definition Validation Rules
24390
* Validation Rule: String Valid
24393
* 1 It is schema-valid with respect to that definition as defined
24394
* by Datatype Valid in [XML Schemas: Datatypes].
24397
* 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24398
* the empty set, as defined in Type Derivation OK (Simple) (ļæ½3.14.6), then
24399
* the string must be a ļæ½declared entity nameļæ½.
24402
* 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24403
* given the empty set, as defined in Type Derivation OK (Simple) (ļæ½3.14.6),
24404
* then every whitespace-delimited substring of the string must be a ļæ½declared
24408
* 2.3 otherwise no further condition applies.
24410
if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
24413
value = BAD_CAST "";
24414
if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
24415
xmlSchemaTypePtr biType; /* The built-in type. */
24417
* SPEC (1.2.1) "if {variety} is ļæ½atomicļæ½ then the string must ļæ½matchļæ½
24418
* a literal in the ļæ½lexical spaceļæ½ of {base type definition}"
24421
* Whitespace-normalize.
24424
if (type->type != XML_SCHEMA_TYPE_BASIC) {
24426
* Get the built-in type.
24428
biType = type->baseType;
24429
while ((biType != NULL) &&
24430
(biType->type != XML_SCHEMA_TYPE_BASIC))
24431
biType = biType->baseType;
24433
if (biType == NULL) {
24434
AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24435
"could not get the built-in type");
24436
goto internal_error;
24441
* NOTATIONs need to be processed here, since they need
24442
* to lookup in the hashtable of NOTATION declarations of the schema.
24444
if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
24445
switch (biType->builtInType) {
24446
case XML_SCHEMAS_NOTATION:
24447
ret = xmlSchemaValidateNotation(
24448
(xmlSchemaValidCtxtPtr) actxt,
24449
((xmlSchemaValidCtxtPtr) actxt)->schema,
24450
NULL, value, &val, valNeeded);
24452
case XML_SCHEMAS_QNAME:
24453
ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24454
value, &val, valNeeded);
24457
/* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24459
ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24460
value, &val, NULL);
24462
ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24463
value, NULL, NULL);
24466
} else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
24467
switch (biType->builtInType) {
24468
case XML_SCHEMAS_NOTATION:
24469
ret = xmlSchemaValidateNotation(NULL,
24470
((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24471
value, &val, valNeeded);
24474
/* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24476
ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24477
value, &val, node);
24479
ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24480
value, NULL, node);
24485
* Validation via a public API is not implemented yet.
24488
goto internal_error;
24492
AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24493
"validating against a built-in type");
24494
goto internal_error;
24496
if (WXS_IS_LIST(type))
24497
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24499
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24501
if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24505
ret = xmlSchemaValidateFacets(actxt, node, type,
24506
(xmlSchemaValType) biType->builtInType, value, val,
24510
AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24511
"validating facets of atomic simple type");
24512
goto internal_error;
24514
if (WXS_IS_LIST(type))
24515
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24517
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24520
if (fireErrors && (ret > 0))
24521
xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24522
} else if (WXS_IS_LIST(type)) {
24524
xmlSchemaTypePtr itemType;
24525
const xmlChar *cur, *end;
24526
xmlChar *tmpValue = NULL;
24527
unsigned long len = 0;
24528
xmlSchemaValPtr prevVal = NULL, curVal = NULL;
24529
/* 1.2.2 if {variety} is ļæ½listļæ½ then the string must be a sequence
24530
* of white space separated tokens, each of which ļæ½matchļæ½es a literal
24531
* in the ļæ½lexical spaceļæ½ of {item type definition}
24534
* Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24535
* the list type has an enum or pattern facet.
24539
* VAL TODO: Optimize validation of empty values.
24540
* VAL TODO: We do not have computed values for lists.
24542
itemType = WXS_LIST_ITEMTYPE(type);
24545
while (IS_BLANK_CH(*cur))
24548
while ((*end != 0) && (!(IS_BLANK_CH(*end))))
24552
tmpValue = xmlStrndup(cur, end - cur);
24556
ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24557
tmpValue, &curVal, fireErrors, 0, 1);
24559
ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24560
tmpValue, NULL, fireErrors, 0, 1);
24561
FREE_AND_NULL(tmpValue);
24562
if (curVal != NULL) {
24564
* Add to list of computed values.
24569
xmlSchemaValueAppend(prevVal, curVal);
24575
AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24576
"validating an item of list simple type");
24577
goto internal_error;
24579
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24583
} while (*cur != 0);
24584
FREE_AND_NULL(tmpValue);
24585
if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24587
* Apply facets (pattern, enumeration).
24589
ret = xmlSchemaValidateFacets(actxt, node, type,
24590
XML_SCHEMAS_UNKNOWN, value, val,
24594
AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24595
"validating facets of list simple type");
24596
goto internal_error;
24598
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24601
if (fireErrors && (ret > 0)) {
24603
* Report the normalized value.
24607
xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24609
} else if (WXS_IS_UNION(type)) {
24610
xmlSchemaTypeLinkPtr memberLink;
24612
* TODO: For all datatypes ļæ½derivedļæ½ by ļæ½unionļæ½ whiteSpace does
24613
* not apply directly; however, the normalization behavior of ļæ½unionļæ½
24614
* types is controlled by the value of whiteSpace on that one of the
24615
* ļæ½memberTypesļæ½ against which the ļæ½unionļæ½ is successfully validated.
24617
* This means that the value is normalized by the first validating
24618
* member type, then the facets of the union type are applied. This
24619
* needs changing of the value!
24623
* 1.2.3 if {variety} is ļæ½unionļæ½ then the string must ļæ½matchļæ½ a
24624
* literal in the ļæ½lexical spaceļæ½ of at least one member of
24625
* {member type definitions}
24627
memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24628
if (memberLink == NULL) {
24629
AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24630
"union simple type has no member types");
24631
goto internal_error;
24634
* Always normalize union type values, since we currently
24635
* cannot store the whitespace information with the value
24636
* itself; otherwise a later value-comparison would be
24639
while (memberLink != NULL) {
24641
ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24642
memberLink->type, value, &val, 0, 1, 0);
24644
ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24645
memberLink->type, value, NULL, 0, 1, 0);
24648
memberLink = memberLink->next;
24652
AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24653
"validating members of union simple type");
24654
goto internal_error;
24656
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24659
* Apply facets (pattern, enumeration).
24661
if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24663
* The normalization behavior of ļæ½unionļæ½ types is controlled by
24664
* the value of whiteSpace on that one of the ļæ½memberTypesļæ½
24665
* against which the ļæ½unionļæ½ is successfully validated.
24667
NORMALIZE(memberLink->type);
24668
ret = xmlSchemaValidateFacets(actxt, node, type,
24669
XML_SCHEMAS_UNKNOWN, value, val,
24673
AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24674
"validating facets of union simple type");
24675
goto internal_error;
24677
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24680
if (fireErrors && (ret > 0))
24681
xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24684
if (normValue != NULL)
24685
xmlFree(normValue);
24687
if (retVal != NULL)
24689
else if (val != NULL)
24690
xmlSchemaFreeValue(val);
24691
} else if (val != NULL)
24692
xmlSchemaFreeValue(val);
24695
if (normValue != NULL)
24696
xmlFree(normValue);
24698
xmlSchemaFreeValue(val);
24703
xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
24704
const xmlChar *value,
24705
const xmlChar **nsName,
24706
const xmlChar **localName)
24710
if ((nsName == NULL) || (localName == NULL))
24715
ret = xmlValidateQName(value, 1);
24719
xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
24720
XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24721
value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
24725
xmlChar *local = NULL;
24729
* NOTE: xmlSplitQName2 will return a duplicated
24732
local = xmlSplitQName2(value, &prefix);
24734
*localName = xmlDictLookup(vctxt->dict, value, -1);
24736
*localName = xmlDictLookup(vctxt->dict, local, -1);
24740
*nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24742
if (prefix != NULL) {
24745
* A namespace must be found if the prefix is NOT NULL.
24747
if (*nsName == NULL) {
24748
xmlSchemaCustomErr(ACTXT_CAST vctxt,
24749
XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24750
WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24751
"The QName value '%s' has no "
24752
"corresponding namespace declaration in scope",
24762
xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
24763
xmlSchemaAttrInfoPtr iattr,
24764
xmlSchemaTypePtr *localType,
24765
xmlSchemaElementPtr elemDecl)
24769
* cvc-elt (3.3.4) : (4)
24771
* Schema-Validity Assessment (Element) (cvc-assess-elt)
24772
* (1.2.1.2.1) - (1.2.1.2.4)
24773
* Handle 'xsi:type'.
24775
if (localType == NULL)
24781
const xmlChar *nsName = NULL, *local = NULL;
24783
* TODO: We should report a *warning* that the type was overriden
24786
ACTIVATE_ATTRIBUTE(iattr);
24788
* (cvc-elt) (3.3.4) : (4.1)
24789
* (cvc-assess-elt) (1.2.1.2.2)
24791
ret = xmlSchemaVExpandQName(vctxt, iattr->value,
24795
VERROR_INT("xmlSchemaValidateElementByDeclaration",
24796
"calling xmlSchemaQNameExpand() to validate the "
24797
"attribute 'xsi:type'");
24798
goto internal_error;
24803
* (cvc-elt) (3.3.4) : (4.2)
24804
* (cvc-assess-elt) (1.2.1.2.3)
24806
*localType = xmlSchemaGetType(vctxt->schema, local, nsName);
24807
if (*localType == NULL) {
24808
xmlChar *str = NULL;
24810
xmlSchemaCustomErr(ACTXT_CAST vctxt,
24811
XML_SCHEMAV_CVC_ELT_4_2, NULL,
24812
WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24813
"The QName value '%s' of the xsi:type attribute does not "
24814
"resolve to a type definition",
24815
xmlSchemaFormatQName(&str, nsName, local), NULL);
24816
FREE_AND_NULL(str);
24820
if (elemDecl != NULL) {
24824
* SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
24825
* "The ļæ½local type definitionļæ½ must be validly
24826
* derived from the {type definition} given the union of
24827
* the {disallowed substitutions} and the {type definition}'s
24828
* {prohibited substitutions}, as defined in
24829
* Type Derivation OK (Complex) (ļæ½3.4.6)
24830
* (if it is a complex type definition),
24831
* or given {disallowed substitutions} as defined in Type
24832
* Derivation OK (Simple) (ļæ½3.14.6) (if it is a simple type
24835
* {disallowed substitutions}: the "block" on the element decl.
24836
* {prohibited substitutions}: the "block" on the type def.
24839
* OPTIMIZE TODO: We could map types already evaluated
24840
* to be validly derived from other types to avoid checking
24841
* this over and over for the same types.
24843
if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
24844
(elemDecl->subtypes->flags &
24845
XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
24846
set |= SUBSET_EXTENSION;
24848
if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
24849
(elemDecl->subtypes->flags &
24850
XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
24851
set |= SUBSET_RESTRICTION;
24854
* REMOVED and CHANGED since this produced a parser context
24855
* which adds to the string dict of the schema. So this would
24856
* change the schema and we don't want this. We don't need
24857
* the parser context anymore.
24859
* if ((vctxt->pctxt == NULL) &&
24860
* (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
24864
if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
24865
elemDecl->subtypes, set) != 0) {
24866
xmlChar *str = NULL;
24868
xmlSchemaCustomErr(ACTXT_CAST vctxt,
24869
XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
24870
"The type definition '%s', specified by xsi:type, is "
24871
"blocked or not validly derived from the type definition "
24872
"of the element declaration",
24873
xmlSchemaFormatQName(&str,
24874
(*localType)->targetNamespace,
24875
(*localType)->name),
24877
FREE_AND_NULL(str);
24892
xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
24894
xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
24895
xmlSchemaTypePtr actualType;
24898
* cvc-elt (3.3.4) : 1
24900
if (elemDecl == NULL) {
24901
VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
24902
"No matching declaration available");
24903
return (vctxt->err);
24905
actualType = WXS_ELEM_TYPEDEF(elemDecl);
24907
* cvc-elt (3.3.4) : 2
24909
if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
24910
VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
24911
"The element declaration is abstract");
24912
return (vctxt->err);
24914
if (actualType == NULL) {
24915
VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
24916
"The type definition is absent");
24917
return (XML_SCHEMAV_CVC_TYPE_1);
24919
if (vctxt->nbAttrInfos != 0) {
24921
xmlSchemaAttrInfoPtr iattr;
24923
* cvc-elt (3.3.4) : 3
24924
* Handle 'xsi:nil'.
24926
iattr = xmlSchemaGetMetaAttrInfo(vctxt,
24927
XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
24929
ACTIVATE_ATTRIBUTE(iattr);
24931
* Validate the value.
24933
ret = xmlSchemaVCheckCVCSimpleType(
24934
ACTXT_CAST vctxt, NULL,
24935
xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
24936
iattr->value, &(iattr->val), 1, 0, 0);
24939
VERROR_INT("xmlSchemaValidateElemDecl",
24940
"calling xmlSchemaVCheckCVCSimpleType() to "
24941
"validate the attribute 'xsi:nil'");
24945
if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
24947
* cvc-elt (3.3.4) : 3.1
24949
VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
24950
"The element is not 'nillable'");
24951
/* Does not return an error on purpose. */
24953
if (xmlSchemaValueGetAsBoolean(iattr->val)) {
24955
* cvc-elt (3.3.4) : 3.2.2
24957
if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
24958
(elemDecl->value != NULL)) {
24959
VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
24960
"The element cannot be 'nilled' because "
24961
"there is a fixed value constraint defined "
24963
/* Does not return an error on purpose. */
24965
vctxt->inode->flags |=
24966
XML_SCHEMA_ELEM_INFO_NILLED;
24972
* cvc-elt (3.3.4) : 4
24973
* Handle 'xsi:type'.
24975
iattr = xmlSchemaGetMetaAttrInfo(vctxt,
24976
XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
24978
xmlSchemaTypePtr localType = NULL;
24980
ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
24984
VERROR_INT("xmlSchemaValidateElemDecl",
24985
"calling xmlSchemaProcessXSIType() to "
24986
"process the attribute 'xsi:type'");
24989
/* Does not return an error on purpose. */
24991
if (localType != NULL) {
24992
vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
24993
actualType = localType;
24998
* IDC: Register identity-constraint XPath matchers.
25000
if ((elemDecl->idcs != NULL) &&
25001
(xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
25004
* No actual type definition.
25006
if (actualType == NULL) {
25007
VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25008
"The type definition is absent");
25009
return (XML_SCHEMAV_CVC_TYPE_1);
25012
* Remember the actual type definition.
25014
vctxt->inode->typeDef = actualType;
25020
xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
25022
xmlSchemaAttrInfoPtr iattr;
25026
* SPEC cvc-type (3.1.1)
25027
* "The attributes of must be empty, excepting those whose namespace
25028
* name is identical to http://www.w3.org/2001/XMLSchema-instance and
25029
* whose local name is one of type, nil, schemaLocation or
25030
* noNamespaceSchemaLocation."
25032
if (vctxt->nbAttrInfos == 0)
25034
for (i = 0; i < vctxt->nbAttrInfos; i++) {
25035
iattr = vctxt->attrInfos[i];
25036
if (! iattr->metaType) {
25037
ACTIVATE_ATTRIBUTE(iattr)
25038
xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25039
XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
25040
ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
25048
* Cleanup currently used attribute infos.
25051
xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
25054
xmlSchemaAttrInfoPtr attr;
25056
if (vctxt->nbAttrInfos == 0)
25058
for (i = 0; i < vctxt->nbAttrInfos; i++) {
25059
attr = vctxt->attrInfos[i];
25060
if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
25061
if (attr->localName != NULL)
25062
xmlFree((xmlChar *) attr->localName);
25063
if (attr->nsName != NULL)
25064
xmlFree((xmlChar *) attr->nsName);
25066
if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
25067
if (attr->value != NULL)
25068
xmlFree((xmlChar *) attr->value);
25070
if (attr->val != NULL) {
25071
xmlSchemaFreeValue(attr->val);
25074
memset(attr, 0, sizeof(xmlSchemaAttrInfo));
25076
vctxt->nbAttrInfos = 0;
25080
* 3.4.4 Complex Type Definition Validation Rules
25081
* Element Locally Valid (Complex Type) (cvc-complex-type)
25082
* 3.2.4 Attribute Declaration Validation Rules
25083
* Validation Rule: Attribute Locally Valid (cvc-attribute)
25084
* Attribute Locally Valid (Use) (cvc-au)
25086
* Only "assessed" attribute information items will be visible to
25087
* IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25090
xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
25092
xmlSchemaTypePtr type = vctxt->inode->typeDef;
25093
xmlSchemaItemListPtr attrUseList;
25094
xmlSchemaAttributeUsePtr attrUse = NULL;
25095
xmlSchemaAttributePtr attrDecl = NULL;
25096
xmlSchemaAttrInfoPtr iattr, tmpiattr;
25097
int i, j, found, nbAttrs, nbUses;
25098
int xpathRes = 0, res, wildIDs = 0, fixed;
25099
xmlNodePtr defAttrOwnerElem = NULL;
25102
* SPEC (cvc-attribute)
25103
* (1) "The declaration must not be ļæ½absentļæ½ (see Missing
25104
* Sub-components (ļæ½5.3) for how this can fail to be
25106
* (2) "Its {type definition} must not be absent."
25108
* NOTE (1) + (2): This is not handled here, since we currently do not
25109
* allow validation against schemas which have missing sub-components.
25111
* SPEC (cvc-complex-type)
25112
* (3) "For each attribute information item in the element information
25113
* item's [attributes] excepting those whose [namespace name] is
25114
* identical to http://www.w3.org/2001/XMLSchema-instance and whose
25115
* [local name] is one of type, nil, schemaLocation or
25116
* noNamespaceSchemaLocation, the appropriate case among the following
25120
attrUseList = (xmlSchemaItemListPtr) type->attrUses;
25122
* @nbAttrs is the number of attributes present in the instance.
25124
nbAttrs = vctxt->nbAttrInfos;
25125
if (attrUseList != NULL)
25126
nbUses = attrUseList->nbItems;
25129
for (i = 0; i < nbUses; i++) {
25131
attrUse = attrUseList->items[i];
25132
attrDecl = WXS_ATTRUSE_DECL(attrUse);
25133
for (j = 0; j < nbAttrs; j++) {
25134
iattr = vctxt->attrInfos[j];
25136
* SPEC (cvc-complex-type) (3)
25137
* Skip meta attributes.
25139
if (iattr->metaType)
25141
if (iattr->localName[0] != attrDecl->name[0])
25143
if (!xmlStrEqual(iattr->localName, attrDecl->name))
25145
if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
25149
* SPEC (cvc-complex-type)
25150
* (3.1) "If there is among the {attribute uses} an attribute
25151
* use with an {attribute declaration} whose {name} matches
25152
* the attribute information item's [local name] and whose
25153
* {target namespace} is identical to the attribute information
25154
* item's [namespace name] (where an ļæ½absentļæ½ {target namespace}
25155
* is taken to be identical to a [namespace name] with no value),
25156
* then the attribute information must be ļæ½validļæ½ with respect
25157
* to that attribute use as per Attribute Locally Valid (Use)
25158
* (ļæ½3.5.4). In this case the {attribute declaration} of that
25159
* attribute use is the ļæ½context-determined declarationļæ½ for the
25160
* attribute information item with respect to Schema-Validity
25161
* Assessment (Attribute) (ļæ½3.2.4) and
25162
* Assessment Outcome (Attribute) (ļæ½3.2.5).
25164
iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25165
iattr->use = attrUse;
25167
* Context-determined declaration.
25169
iattr->decl = attrDecl;
25170
iattr->typeDef = attrDecl->subtypes;
25177
if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
25179
* Handle non-existent, required attributes.
25181
* SPEC (cvc-complex-type)
25182
* (4) "The {attribute declaration} of each attribute use in
25183
* the {attribute uses} whose {required} is true matches one
25184
* of the attribute information items in the element information
25185
* item's [attributes] as per clause 3.1 above."
25187
tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25188
if (tmpiattr == NULL) {
25190
"xmlSchemaVAttributesComplex",
25191
"calling xmlSchemaGetFreshAttrInfo()");
25194
tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
25195
tmpiattr->use = attrUse;
25196
tmpiattr->decl = attrDecl;
25197
} else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
25198
((attrUse->defValue != NULL) ||
25199
(attrDecl->defValue != NULL))) {
25201
* Handle non-existent, optional, default/fixed attributes.
25203
tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25204
if (tmpiattr == NULL) {
25206
"xmlSchemaVAttributesComplex",
25207
"calling xmlSchemaGetFreshAttrInfo()");
25210
tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
25211
tmpiattr->use = attrUse;
25212
tmpiattr->decl = attrDecl;
25213
tmpiattr->typeDef = attrDecl->subtypes;
25214
tmpiattr->localName = attrDecl->name;
25215
tmpiattr->nsName = attrDecl->targetNamespace;
25219
if (vctxt->nbAttrInfos == 0)
25221
nbUses = vctxt->nbAttrInfos;
25223
* Validate against the wildcard.
25225
if (type->attributeWildcard != NULL) {
25227
* SPEC (cvc-complex-type)
25228
* (3.2.1) "There must be an {attribute wildcard}."
25230
for (i = 0; i < nbAttrs; i++) {
25231
iattr = vctxt->attrInfos[i];
25233
* SPEC (cvc-complex-type) (3)
25234
* Skip meta attributes.
25236
if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
25239
* SPEC (cvc-complex-type)
25240
* (3.2.2) "The attribute information item must be ļæ½validļæ½ with
25241
* respect to it as defined in Item Valid (Wildcard) (ļæ½3.10.4)."
25243
* SPEC Item Valid (Wildcard) (cvc-wildcard)
25244
* "... its [namespace name] must be ļæ½validļæ½ with respect to
25245
* the wildcard constraint, as defined in Wildcard allows
25246
* Namespace Name (ļæ½3.10.4)."
25248
if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
25249
iattr->nsName) == 0) {
25251
* Handle processContents.
25253
* SPEC (cvc-wildcard):
25254
* processContents | context-determined declaration:
25255
* "strict" "mustFind"
25259
if (type->attributeWildcard->processContents ==
25260
XML_SCHEMAS_ANY_SKIP) {
25262
* context-determined declaration = "skip"
25264
* SPEC PSVI Assessment Outcome (Attribute)
25265
* [validity] = "notKnown"
25266
* [validation attempted] = "none"
25268
iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
25272
* Find an attribute declaration.
25274
iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
25275
iattr->localName, iattr->nsName);
25276
if (iattr->decl != NULL) {
25277
iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25279
* SPEC (cvc-complex-type)
25280
* (5) "Let [Definition:] the wild IDs be the set of
25281
* all attribute information item to which clause 3.2
25282
* applied and whose ļæ½validationļæ½ resulted in a
25283
* ļæ½context-determined declarationļæ½ of mustFind or no
25284
* ļæ½context-determined declarationļæ½ at all, and whose
25285
* [local name] and [namespace name] resolve (as
25286
* defined by QName resolution (Instance) (ļæ½3.15.4)) to
25287
* an attribute declaration whose {type definition} is
25288
* or is derived from ID. Then all of the following
25291
iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
25292
if (xmlSchemaIsDerivedFromBuiltInType(
25293
iattr->typeDef, XML_SCHEMAS_ID)) {
25295
* SPEC (5.1) "There must be no more than one
25296
* item in ļæ½wild IDsļæ½."
25298
if (wildIDs != 0) {
25300
iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
25306
* SPEC (cvc-complex-type)
25307
* (5.2) "If ļæ½wild IDsļæ½ is non-empty, there must not
25308
* be any attribute uses among the {attribute uses}
25309
* whose {attribute declaration}'s {type definition}
25310
* is or is derived from ID."
25312
for (j = 0; j < attrUseList->nbItems; j++) {
25313
if (xmlSchemaIsDerivedFromBuiltInType(
25314
WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
25316
/* URGENT VAL TODO: implement */
25317
iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
25323
} else if (type->attributeWildcard->processContents ==
25324
XML_SCHEMAS_ANY_LAX) {
25325
iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
25327
* SPEC PSVI Assessment Outcome (Attribute)
25328
* [validity] = "notKnown"
25329
* [validation attempted] = "none"
25332
iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
25338
if (vctxt->nbAttrInfos == 0)
25342
* Get the owner element; needed for creation of default attributes.
25343
* This fixes bug #341337, reported by David Grohmann.
25345
if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25346
xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25347
if (ielem && ielem->node && ielem->node->doc)
25348
defAttrOwnerElem = ielem->node;
25351
* Validate values, create default attributes, evaluate IDCs.
25353
for (i = 0; i < vctxt->nbAttrInfos; i++) {
25354
iattr = vctxt->attrInfos[i];
25356
* VAL TODO: Note that we won't try to resolve IDCs to
25357
* "lax" and "skip" validated attributes. Check what to
25360
if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
25361
(iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
25364
* VAL TODO: What to do if the type definition is missing?
25366
if (iattr->typeDef == NULL) {
25367
iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
25371
ACTIVATE_ATTRIBUTE(iattr);
25375
if (vctxt->xpathStates != NULL) {
25379
xpathRes = xmlSchemaXPathEvaluate(vctxt,
25380
XML_ATTRIBUTE_NODE);
25381
if (xpathRes == -1) {
25382
VERROR_INT("xmlSchemaVAttributesComplex",
25383
"calling xmlSchemaXPathEvaluate()");
25384
goto internal_error;
25388
if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
25390
* Default/fixed attributes.
25391
* We need the value only if we need to resolve IDCs or
25392
* will create default attributes.
25394
if ((xpathRes) || (defAttrOwnerElem)) {
25395
if (iattr->use->defValue != NULL) {
25396
iattr->value = (xmlChar *) iattr->use->defValue;
25397
iattr->val = iattr->use->defVal;
25399
iattr->value = (xmlChar *) iattr->decl->defValue;
25400
iattr->val = iattr->decl->defVal;
25403
* IDCs will consume the precomputed default value,
25404
* so we need to clone it.
25406
if (iattr->val == NULL) {
25407
VERROR_INT("xmlSchemaVAttributesComplex",
25408
"default/fixed value on an attribute use was "
25409
"not precomputed");
25410
goto internal_error;
25412
iattr->val = xmlSchemaCopyValue(iattr->val);
25413
if (iattr->val == NULL) {
25414
VERROR_INT("xmlSchemaVAttributesComplex",
25415
"calling xmlSchemaCopyValue()");
25416
goto internal_error;
25420
* PSVI: Add the default attribute to the current element.
25421
* VAL TODO: Should we use the *normalized* value? This currently
25422
* uses the *initial* value.
25425
if (defAttrOwnerElem) {
25426
xmlChar *normValue;
25427
const xmlChar *value;
25429
value = iattr->value;
25431
* Normalize the value.
25433
normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25435
if (normValue != NULL)
25436
value = BAD_CAST normValue;
25438
if (iattr->nsName == NULL) {
25439
if (xmlNewProp(defAttrOwnerElem,
25440
iattr->localName, value) == NULL) {
25441
VERROR_INT("xmlSchemaVAttributesComplex",
25442
"callling xmlNewProp()");
25443
if (normValue != NULL)
25444
xmlFree(normValue);
25445
goto internal_error;
25450
ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25451
defAttrOwnerElem, iattr->nsName);
25453
xmlChar prefix[12];
25457
* Create a namespace declaration on the validation
25458
* root node if no namespace declaration is in scope.
25461
snprintf((char *) prefix, 12, "p%d", counter++);
25462
ns = xmlSearchNs(defAttrOwnerElem->doc,
25463
defAttrOwnerElem, BAD_CAST prefix);
25464
if (counter > 1000) {
25466
"xmlSchemaVAttributesComplex",
25467
"could not compute a ns prefix for a "
25468
"default/fixed attribute");
25469
if (normValue != NULL)
25470
xmlFree(normValue);
25471
goto internal_error;
25473
} while (ns != NULL);
25474
ns = xmlNewNs(vctxt->validationRoot,
25475
iattr->nsName, BAD_CAST prefix);
25479
* http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25480
* If we have QNames: do we need to ensure there's a
25481
* prefix defined for the QName?
25483
xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25485
if (normValue != NULL)
25486
xmlFree(normValue);
25489
* Go directly to IDC evaluation.
25494
* Validate the value.
25496
if (vctxt->value != NULL) {
25498
* Free last computed value; just for safety reasons.
25500
xmlSchemaFreeValue(vctxt->value);
25501
vctxt->value = NULL;
25504
* Note that the attribute *use* can be unavailable, if
25505
* the attribute was a wild attribute.
25507
if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
25508
((iattr->use != NULL) &&
25509
(iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
25514
* SPEC (cvc-attribute)
25515
* (3) "The item's ļæ½normalized valueļæ½ must be locally ļæ½validļæ½
25516
* with respect to that {type definition} as per
25517
* String Valid (ļæ½3.14.4)."
25519
* VAL TODO: Do we already have the
25520
* "normalized attribute value" here?
25522
if (xpathRes || fixed) {
25523
iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
25525
* Request a computed value.
25527
res = xmlSchemaVCheckCVCSimpleType(
25529
iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25532
res = xmlSchemaVCheckCVCSimpleType(
25534
iattr->node, iattr->typeDef, iattr->value, NULL,
25540
VERROR_INT("xmlSchemaVAttributesComplex",
25541
"calling xmlSchemaStreamValidateSimpleTypeValue()");
25542
goto internal_error;
25544
iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
25546
* SPEC PSVI Assessment Outcome (Attribute)
25547
* [validity] = "invalid"
25554
* SPEC Attribute Locally Valid (Use) (cvc-au)
25555
* "For an attribute information item to beļæ½validļæ½
25556
* with respect to an attribute use its *normalized*
25557
* valueļæ½ must match the *canonical* lexical
25558
* representation of the attribute use's {value
25559
* constraint}value, if it is present and fixed."
25561
* VAL TODO: The requirement for the *canonical* value
25562
* will be removed in XML Schema 1.1.
25565
* SPEC Attribute Locally Valid (cvc-attribute)
25566
* (4) "The item's *actual* valueļæ½ must match the *value* of
25567
* the {value constraint}, if it is present and fixed."
25569
if (iattr->val == NULL) {
25570
/* VAL TODO: A value was not precomputed. */
25574
if ((iattr->use != NULL) &&
25575
(iattr->use->defValue != NULL)) {
25576
if (iattr->use->defVal == NULL) {
25577
/* VAL TODO: A default value was not precomputed. */
25581
iattr->vcValue = iattr->use->defValue;
25583
if (xmlSchemaCompareValuesWhtsp(attr->val,
25584
(xmlSchemaWhitespaceValueType) ws,
25586
(xmlSchemaWhitespaceValueType) ws) != 0) {
25588
if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25589
iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25591
if (iattr->decl->defVal == NULL) {
25592
/* VAL TODO: A default value was not precomputed. */
25596
iattr->vcValue = iattr->decl->defValue;
25598
if (xmlSchemaCompareValuesWhtsp(attr->val,
25599
(xmlSchemaWhitespaceValueType) ws,
25601
(xmlSchemaWhitespaceValueType) ws) != 0) {
25603
if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25604
iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25607
* [validity] = "valid"
25615
if (xmlSchemaXPathProcessHistory(vctxt,
25616
vctxt->depth +1) == -1) {
25617
VERROR_INT("xmlSchemaVAttributesComplex",
25618
"calling xmlSchemaXPathEvaluate()");
25619
goto internal_error;
25621
} else if (vctxt->xpathStates != NULL)
25622
xmlSchemaXPathPop(vctxt);
25628
for (i = 0; i < vctxt->nbAttrInfos; i++) {
25629
iattr = vctxt->attrInfos[i];
25630
if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
25631
(iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
25632
(iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
25633
(iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
25635
ACTIVATE_ATTRIBUTE(iattr);
25636
switch (iattr->state) {
25637
case XML_SCHEMAS_ATTR_ERR_MISSING: {
25638
xmlChar *str = NULL;
25640
xmlSchemaCustomErr(ACTXT_CAST vctxt,
25641
XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
25642
"The attribute '%s' is required but missing",
25643
xmlSchemaFormatQName(&str,
25644
iattr->decl->targetNamespace,
25645
iattr->decl->name),
25650
case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
25651
VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
25652
"The type definition is absent");
25654
case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
25655
xmlSchemaCustomErr(ACTXT_CAST vctxt,
25656
XML_SCHEMAV_CVC_AU, NULL, NULL,
25657
"The value '%s' does not match the fixed "
25658
"value constraint '%s'",
25659
iattr->value, iattr->vcValue);
25661
case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
25662
VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
25663
"No matching global attribute declaration available, but "
25664
"demanded by the strict wildcard");
25666
case XML_SCHEMAS_ATTR_UNKNOWN:
25667
if (iattr->metaType)
25670
* MAYBE VAL TODO: One might report different error messages
25671
* for the following errors.
25673
if (type->attributeWildcard == NULL) {
25674
xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25675
XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
25677
xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25678
XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
25694
xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
25697
xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
25699
* The namespace of the element was already identified to be
25700
* matching the wildcard.
25702
if ((skip == NULL) || (wild == NULL) ||
25703
(wild->type != XML_SCHEMA_TYPE_ANY)) {
25704
VERROR_INT("xmlSchemaValidateElemWildcard",
25709
if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
25711
* URGENT VAL TODO: Either we need to position the stream to the
25712
* next sibling, or walk the whole subtree.
25718
xmlSchemaElementPtr decl = NULL;
25720
decl = xmlSchemaGetElem(vctxt->schema,
25721
vctxt->inode->localName, vctxt->inode->nsName);
25722
if (decl != NULL) {
25723
vctxt->inode->decl = decl;
25727
if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
25728
/* VAL TODO: Change to proper error code. */
25729
VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
25730
"No matching global element declaration available, but "
25731
"demanded by the strict wildcard");
25732
return (vctxt->err);
25734
if (vctxt->nbAttrInfos != 0) {
25735
xmlSchemaAttrInfoPtr iattr;
25737
* SPEC Validation Rule: Schema-Validity Assessment (Element)
25738
* (1.2.1.2.1) - (1.2.1.2.3 )
25740
* Use the xsi:type attribute for the type definition.
25742
iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25743
XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25744
if (iattr != NULL) {
25745
if (xmlSchemaProcessXSIType(vctxt, iattr,
25746
&(vctxt->inode->typeDef), NULL) == -1) {
25747
VERROR_INT("xmlSchemaValidateElemWildcard",
25748
"calling xmlSchemaProcessXSIType() to "
25749
"process the attribute 'xsi:nil'");
25753
* Don't return an error on purpose.
25759
* SPEC Validation Rule: Schema-Validity Assessment (Element)
25761
* Fallback to "anyType".
25763
vctxt->inode->typeDef =
25764
xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
25769
* xmlSchemaCheckCOSValidDefault:
25771
* This will be called if: not nilled, no content and a default/fixed
25772
* value is provided.
25776
xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
25777
const xmlChar *value,
25778
xmlSchemaValPtr *val)
25781
xmlSchemaNodeInfoPtr inode = vctxt->inode;
25784
* cos-valid-default:
25785
* Schema Component Constraint: Element Default Valid (Immediate)
25786
* For a string to be a valid default with respect to a type
25787
* definition the appropriate case among the following must be true:
25789
if WXS_IS_COMPLEX(inode->typeDef) {
25793
* SPEC (2.1) "its {content type} must be a simple type definition
25795
* SPEC (2.2.2) "If the {content type} is mixed, then the {content
25796
* type}'s particle must be ļæ½emptiableļæ½ as defined by
25797
* Particle Emptiable (ļæ½3.9.6)."
25799
if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
25800
((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
25801
(! WXS_EMPTIABLE(inode->typeDef)))) {
25802
ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
25803
/* NOTE that this covers (2.2.2) as well. */
25805
"For a string to be a valid default, the type definition "
25806
"must be a simple type or a complex type with simple content "
25807
"or mixed content and a particle emptiable");
25812
* 1 If the type definition is a simple type definition, then the string
25813
* must be ļæ½validļæ½ with respect to that definition as defined by String
25814
* Valid (ļæ½3.14.4).
25818
* 2.2.1 If the {content type} is a simple type definition, then the
25819
* string must be ļæ½validļæ½ with respect to that simple type definition
25820
* as defined by String Valid (ļæ½3.14.4).
25822
if (WXS_IS_SIMPLE(inode->typeDef)) {
25824
ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25825
NULL, inode->typeDef, value, val, 1, 1, 0);
25827
} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25829
ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25830
NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
25833
VERROR_INT("xmlSchemaCheckCOSValidDefault",
25834
"calling xmlSchemaVCheckCVCSimpleType()");
25840
xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
25841
const xmlChar * name ATTRIBUTE_UNUSED,
25842
xmlSchemaElementPtr item,
25843
xmlSchemaNodeInfoPtr inode)
25845
inode->decl = item;
25846
#ifdef DEBUG_CONTENT
25848
xmlChar *str = NULL;
25850
if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
25851
xmlGenericError(xmlGenericErrorContext,
25852
"AUTOMATON callback for '%s' [declaration]\n",
25853
xmlSchemaFormatQName(&str,
25854
inode->localName, inode->nsName));
25856
xmlGenericError(xmlGenericErrorContext,
25857
"AUTOMATON callback for '%s' [wildcard]\n",
25858
xmlSchemaFormatQName(&str,
25859
inode->localName, inode->nsName));
25868
xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
25870
vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
25871
if (vctxt->inode == NULL) {
25872
VERROR_INT("xmlSchemaValidatorPushElem",
25873
"calling xmlSchemaGetFreshElemInfo()");
25876
vctxt->nbAttrInfos = 0;
25881
xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
25882
xmlSchemaNodeInfoPtr inode,
25883
xmlSchemaTypePtr type,
25884
const xmlChar *value)
25886
if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
25887
return (xmlSchemaVCheckCVCSimpleType(
25888
ACTXT_CAST vctxt, NULL,
25889
type, value, &(inode->val), 1, 1, 0));
25891
return (xmlSchemaVCheckCVCSimpleType(
25892
ACTXT_CAST vctxt, NULL,
25893
type, value, NULL, 1, 0, 0));
25899
* Process END of element.
25902
xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
25905
xmlSchemaNodeInfoPtr inode = vctxt->inode;
25907
if (vctxt->nbAttrInfos != 0)
25908
xmlSchemaClearAttrInfos(vctxt);
25909
if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
25911
* This element was not expected;
25912
* we will not validate child elements of broken parents.
25913
* Skip validation of all content of the parent.
25915
vctxt->skipDepth = vctxt->depth -1;
25918
if ((inode->typeDef == NULL) ||
25919
(inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
25921
* 1. the type definition might be missing if the element was
25923
* 2. it might be abstract.
25928
* Check the content model.
25930
if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
25931
(inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
25934
* Workaround for "anyType".
25936
if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
25937
goto character_content;
25939
if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
25940
xmlChar *values[10];
25941
int terminal, nbval = 10, nbneg;
25943
if (inode->regexCtxt == NULL) {
25945
* Create the regex context.
25948
xmlRegNewExecCtxt(inode->typeDef->contModel,
25949
(xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
25951
if (inode->regexCtxt == NULL) {
25952
VERROR_INT("xmlSchemaValidatorPopElem",
25953
"failed to create a regex context");
25954
goto internal_error;
25956
#ifdef DEBUG_AUTOMATA
25957
xmlGenericError(xmlGenericErrorContext,
25958
"AUTOMATON create on '%s'\n", inode->localName);
25962
* Get hold of the still expected content, since a further
25963
* call to xmlRegExecPushString() will loose this information.
25965
xmlRegExecNextValues(inode->regexCtxt,
25966
&nbval, &nbneg, &values[0], &terminal);
25967
ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
25968
if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
25970
* Still missing something.
25974
XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
25975
xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
25976
XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
25977
"Missing child element(s)",
25978
nbval, nbneg, values);
25979
#ifdef DEBUG_AUTOMATA
25980
xmlGenericError(xmlGenericErrorContext,
25981
"AUTOMATON missing ERROR on '%s'\n",
25986
* Content model is satisfied.
25989
#ifdef DEBUG_AUTOMATA
25990
xmlGenericError(xmlGenericErrorContext,
25991
"AUTOMATON succeeded on '%s'\n",
25998
if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
26003
if (vctxt->value != NULL) {
26004
xmlSchemaFreeValue(vctxt->value);
26005
vctxt->value = NULL;
26008
* Check character content.
26010
if (inode->decl == NULL) {
26012
* Speedup if no declaration exists.
26014
if (WXS_IS_SIMPLE(inode->typeDef)) {
26015
ret = xmlSchemaVCheckINodeDataType(vctxt,
26016
inode, inode->typeDef, inode->value);
26017
} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26018
ret = xmlSchemaVCheckINodeDataType(vctxt,
26019
inode, inode->typeDef->contentTypeDef,
26023
VERROR_INT("xmlSchemaValidatorPopElem",
26024
"calling xmlSchemaVCheckCVCSimpleType()");
26025
goto internal_error;
26030
* cvc-elt (3.3.4) : 5
26031
* The appropriate case among the following must be true:
26034
* cvc-elt (3.3.4) : 5.1
26035
* If the declaration has a {value constraint},
26036
* the item has neither element nor character [children] and
26037
* clause 3.2 has not applied, then all of the following must be true:
26039
if ((inode->decl->value != NULL) &&
26040
(inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
26041
(! INODE_NILLED(inode))) {
26043
* cvc-elt (3.3.4) : 5.1.1
26044
* If the ļæ½actual type definitionļæ½ is a ļæ½local type definitionļæ½
26045
* then the canonical lexical representation of the {value constraint}
26046
* value must be a valid default for the ļæ½actual type definitionļæ½ as
26047
* defined in Element Default Valid (Immediate) (ļæ½3.3.6).
26050
* NOTE: 'local' above means types acquired by xsi:type.
26051
* NOTE: Although the *canonical* value is stated, it is not
26052
* relevant if canonical or not. Additionally XML Schema 1.1
26053
* will removed this requirement as well.
26055
if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
26057
ret = xmlSchemaCheckCOSValidDefault(vctxt,
26058
inode->decl->value, &(inode->val));
26061
VERROR_INT("xmlSchemaValidatorPopElem",
26062
"calling xmlSchemaCheckCOSValidDefault()");
26063
goto internal_error;
26068
* Stop here, to avoid redundant validation of the value
26074
* cvc-elt (3.3.4) : 5.1.2
26075
* The element information item with the canonical lexical
26076
* representation of the {value constraint} value used as its
26077
* ļæ½normalized valueļæ½ must be ļæ½validļæ½ with respect to the
26078
* ļæ½actual type definitionļæ½ as defined by Element Locally Valid (Type)
26081
if (WXS_IS_SIMPLE(inode->typeDef)) {
26082
ret = xmlSchemaVCheckINodeDataType(vctxt,
26083
inode, inode->typeDef, inode->decl->value);
26084
} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26085
ret = xmlSchemaVCheckINodeDataType(vctxt,
26086
inode, inode->typeDef->contentTypeDef,
26087
inode->decl->value);
26091
VERROR_INT("xmlSchemaValidatorPopElem",
26092
"calling xmlSchemaVCheckCVCSimpleType()");
26093
goto internal_error;
26100
* PSVI: Create a text node on the instance element.
26102
if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
26103
(inode->node != NULL)) {
26104
xmlNodePtr textChild;
26105
xmlChar *normValue;
26107
* VAL TODO: Normalize the value.
26109
normValue = xmlSchemaNormalizeValue(inode->typeDef,
26110
inode->decl->value);
26111
if (normValue != NULL) {
26112
textChild = xmlNewText(BAD_CAST normValue);
26113
xmlFree(normValue);
26115
textChild = xmlNewText(inode->decl->value);
26116
if (textChild == NULL) {
26117
VERROR_INT("xmlSchemaValidatorPopElem",
26118
"calling xmlNewText()");
26119
goto internal_error;
26121
xmlAddChild(inode->node, textChild);
26124
} else if (! INODE_NILLED(inode)) {
26126
* 5.2.1 The element information item must be ļæ½validļæ½ with respect
26127
* to the ļæ½actual type definitionļæ½ as defined by Element Locally
26128
* Valid (Type) (ļæ½3.3.4).
26130
if (WXS_IS_SIMPLE(inode->typeDef)) {
26132
* SPEC (cvc-type) (3.1)
26133
* "If the type definition is a simple type definition, ..."
26134
* (3.1.3) "If clause 3.2 of Element Locally Valid
26135
* (Element) (ļæ½3.3.4) did not apply, then the ļæ½normalized valueļæ½
26136
* must be ļæ½validļæ½ with respect to the type definition as defined
26137
* by String Valid (ļæ½3.14.4).
26139
ret = xmlSchemaVCheckINodeDataType(vctxt,
26140
inode, inode->typeDef, inode->value);
26141
} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26143
* SPEC (cvc-type) (3.2) "If the type definition is a complex type
26144
* definition, then the element information item must be
26145
* ļæ½validļæ½ with respect to the type definition as per
26146
* Element Locally Valid (Complex Type) (ļæ½3.4.4);"
26148
* SPEC (cvc-complex-type) (2.2)
26149
* "If the {content type} is a simple type definition, ...
26150
* the ļæ½normalized valueļæ½ of the element information item is
26151
* ļæ½validļæ½ with respect to that simple type definition as
26152
* defined by String Valid (ļæ½3.14.4)."
26154
ret = xmlSchemaVCheckINodeDataType(vctxt,
26155
inode, inode->typeDef->contentTypeDef, inode->value);
26159
VERROR_INT("xmlSchemaValidatorPopElem",
26160
"calling xmlSchemaVCheckCVCSimpleType()");
26161
goto internal_error;
26166
* 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26167
* not applied, all of the following must be true:
26169
if ((inode->decl->value != NULL) &&
26170
(inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
26173
* TODO: We will need a computed value, when comparison is
26174
* done on computed values.
26177
* 5.2.2.1 The element information item must have no element
26178
* information item [children].
26181
XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
26182
ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
26184
"The content must not containt element nodes since "
26185
"there is a fixed value constraint");
26189
* 5.2.2.2 The appropriate case among the following must
26192
if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
26194
* 5.2.2.2.1 If the {content type} of the ļæ½actual type
26195
* definitionļæ½ is mixed, then the *initial value* of the
26196
* item must match the canonical lexical representation
26197
* of the {value constraint} value.
26199
* ... the *initial value* of an element information
26200
* item is the string composed of, in order, the
26201
* [character code] of each character information item in
26202
* the [children] of that element information item.
26204
if (! xmlStrEqual(inode->value, inode->decl->value)){
26206
* VAL TODO: Report invalid & expected values as well.
26207
* VAL TODO: Implement the canonical stuff.
26209
ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
26210
xmlSchemaCustomErr(ACTXT_CAST vctxt,
26212
"The initial value '%s' does not match the fixed "
26213
"value constraint '%s'",
26214
inode->value, inode->decl->value);
26217
} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26219
* 5.2.2.2.2 If the {content type} of the ļæ½actual type
26220
* definitionļæ½ is a simple type definition, then the
26221
* *actual value* of the item must match the canonical
26222
* lexical representation of the {value constraint} value.
26225
* VAL TODO: *actual value* is the normalized value, impl.
26227
* VAL TODO: Report invalid & expected values as well.
26228
* VAL TODO: Implement a comparison with the computed values.
26230
if (! xmlStrEqual(inode->value,
26231
inode->decl->value)) {
26232
ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
26233
xmlSchemaCustomErr(ACTXT_CAST vctxt,
26235
"The actual value '%s' does not match the fixed "
26236
"value constraint '%s'",
26238
inode->decl->value);
26247
if (vctxt->depth < 0) {
26248
/* TODO: raise error? */
26251
if (vctxt->depth == vctxt->skipDepth)
26252
vctxt->skipDepth = -1;
26254
* Evaluate the history of XPath state objects.
26256
if (inode->appliedXPath &&
26257
(xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
26258
goto internal_error;
26261
* SPEC (6) "The element information item must be ļæ½validļæ½ with
26262
* respect to each of the {identity-constraint definitions} as per
26263
* Identity-constraint Satisfied (ļæ½3.11.4)."
26266
* PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26267
* need to be built in any case.
26268
* We will currently build IDC node-tables and bubble them only if
26269
* keyrefs do exist.
26273
* Add the current IDC target-nodes to the IDC node-tables.
26275
if ((inode->idcMatchers != NULL) &&
26276
(vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26278
if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
26279
goto internal_error;
26282
* Validate IDC keyrefs.
26284
if (vctxt->inode->hasKeyrefs)
26285
if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
26286
goto internal_error;
26288
* Merge/free the IDC table.
26290
if (inode->idcTable != NULL) {
26291
#ifdef DEBUG_IDC_NODE_TABLE
26292
xmlSchemaDebugDumpIDCTable(stdout,
26297
if ((vctxt->depth > 0) &&
26298
(vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26301
* Merge the IDC node table with the table of the parent node.
26303
if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
26304
goto internal_error;
26308
* Clear the current ielem.
26309
* VAL TODO: Don't free the PSVI IDC tables if they are
26310
* requested for the PSVI.
26312
xmlSchemaClearElemInfo(vctxt, inode);
26314
* Skip further processing if we are on the validation root.
26316
if (vctxt->depth == 0) {
26318
vctxt->inode = NULL;
26322
* Reset the keyrefDepth if needed.
26324
if (vctxt->aidcs != NULL) {
26325
xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26327
if (aidc->keyrefDepth == vctxt->depth) {
26329
* A 'keyrefDepth' of a key/unique IDC matches the current
26330
* depth, this means that we are leaving the scope of the
26331
* top-most keyref IDC which refers to this IDC.
26333
aidc->keyrefDepth = -1;
26336
} while (aidc != NULL);
26339
vctxt->inode = vctxt->elemInfos[vctxt->depth];
26341
* VAL TODO: 7 If the element information item is the ļæ½validation rootļæ½, it must be
26342
* ļæ½validļæ½ per Validation Root Valid (ID/IDREF) (ļæ½3.3.4).
26352
* 3.4.4 Complex Type Definition Validation Rules
26353
* Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26356
xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26358
xmlSchemaNodeInfoPtr pielem;
26359
xmlSchemaTypePtr ptype;
26362
if (vctxt->depth <= 0) {
26363
VERROR_INT("xmlSchemaValidateChildElem",
26364
"not intended for the validation root");
26367
pielem = vctxt->elemInfos[vctxt->depth -1];
26368
if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26369
pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26371
* Handle 'nilled' elements.
26373
if (INODE_NILLED(pielem)) {
26375
* SPEC (cvc-elt) (3.3.4) : (3.2.1)
26377
ACTIVATE_PARENT_ELEM;
26378
ret = XML_SCHEMAV_CVC_ELT_3_2_1;
26380
"Neither character nor element content is allowed, "
26381
"because the element was 'nilled'");
26383
goto unexpected_elem;
26386
ptype = pielem->typeDef;
26388
if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26390
* Workaround for "anyType": we have currently no content model
26391
* assigned for "anyType", so handle it explicitely.
26392
* "anyType" has an unbounded, lax "any" wildcard.
26394
vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26395
vctxt->inode->localName,
26396
vctxt->inode->nsName);
26398
if (vctxt->inode->decl == NULL) {
26399
xmlSchemaAttrInfoPtr iattr;
26401
* Process "xsi:type".
26402
* SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26404
iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26405
XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26406
if (iattr != NULL) {
26407
ret = xmlSchemaProcessXSIType(vctxt, iattr,
26408
&(vctxt->inode->typeDef), NULL);
26411
VERROR_INT("xmlSchemaValidateChildElem",
26412
"calling xmlSchemaProcessXSIType() to "
26413
"process the attribute 'xsi:nil'");
26420
* Fallback to "anyType".
26422
* SPEC (cvc-assess-elt)
26423
* "If the item cannot be ļæ½strictly assessedļæ½, [...]
26424
* an element information item's schema validity may be laxly
26425
* assessed if its ļæ½context-determined declarationļæ½ is not
26426
* skip by ļæ½validatingļæ½ with respect to the ļæ½ur-type
26427
* definitionļæ½ as per Element Locally Valid (Type) (ļæ½3.3.4)."
26429
vctxt->inode->typeDef =
26430
xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26436
switch (ptype->contentType) {
26437
case XML_SCHEMA_CONTENT_EMPTY:
26439
* SPEC (2.1) "If the {content type} is empty, then the
26440
* element information item has no character or element
26441
* information item [children]."
26443
ACTIVATE_PARENT_ELEM
26444
ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
26446
"Element content is not allowed, "
26447
"because the content type is empty");
26449
goto unexpected_elem;
26452
case XML_SCHEMA_CONTENT_MIXED:
26453
case XML_SCHEMA_CONTENT_ELEMENTS: {
26454
xmlRegExecCtxtPtr regexCtxt;
26455
xmlChar *values[10];
26456
int terminal, nbval = 10, nbneg;
26458
/* VAL TODO: Optimized "anyType" validation.*/
26460
if (ptype->contModel == NULL) {
26461
VERROR_INT("xmlSchemaValidateChildElem",
26462
"type has elem content but no content model");
26466
* Safety belf for evaluation if the cont. model was already
26467
* examined to be invalid.
26469
if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
26470
VERROR_INT("xmlSchemaValidateChildElem",
26471
"validating elem, but elem content is already invalid");
26475
regexCtxt = pielem->regexCtxt;
26476
if (regexCtxt == NULL) {
26478
* Create the regex context.
26480
regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26481
(xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
26483
if (regexCtxt == NULL) {
26484
VERROR_INT("xmlSchemaValidateChildElem",
26485
"failed to create a regex context");
26488
pielem->regexCtxt = regexCtxt;
26489
#ifdef DEBUG_AUTOMATA
26490
xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
26491
pielem->localName);
26496
* SPEC (2.4) "If the {content type} is element-only or mixed,
26497
* then the sequence of the element information item's
26498
* element information item [children], if any, taken in
26499
* order, is ļæ½validļæ½ with respect to the {content type}'s
26500
* particle, as defined in Element Sequence Locally Valid
26501
* (Particle) (ļæ½3.9.4)."
26503
ret = xmlRegExecPushString2(regexCtxt,
26504
vctxt->inode->localName,
26505
vctxt->inode->nsName,
26507
#ifdef DEBUG_AUTOMATA
26509
xmlGenericError(xmlGenericErrorContext,
26510
"AUTOMATON push ERROR for '%s' on '%s'\n",
26511
vctxt->inode->localName, pielem->localName);
26513
xmlGenericError(xmlGenericErrorContext,
26514
"AUTOMATON push OK for '%s' on '%s'\n",
26515
vctxt->inode->localName, pielem->localName);
26517
if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26518
VERROR_INT("xmlSchemaValidateChildElem",
26519
"calling xmlRegExecPushString2()");
26523
xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
26524
&values[0], &terminal);
26525
xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26526
XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
26527
"This element is not expected",
26528
nbval, nbneg, values);
26530
goto unexpected_elem;
26535
case XML_SCHEMA_CONTENT_SIMPLE:
26536
case XML_SCHEMA_CONTENT_BASIC:
26537
ACTIVATE_PARENT_ELEM
26538
if (WXS_IS_COMPLEX(ptype)) {
26540
* SPEC (cvc-complex-type) (2.2)
26541
* "If the {content type} is a simple type definition, then
26542
* the element information item has no element information
26543
* item [children], ..."
26545
ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
26546
VERROR(ret, NULL, "Element content is not allowed, "
26547
"because the content type is a simple type definition");
26550
* SPEC (cvc-type) (3.1.2) "The element information item must
26551
* have no element information item [children]."
26553
ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
26554
VERROR(ret, NULL, "Element content is not allowed, "
26555
"because the type definition is simple");
26559
goto unexpected_elem;
26568
* Pop this element and set the skipDepth to skip
26569
* all further content of the parent element.
26571
vctxt->skipDepth = vctxt->depth;
26572
vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
26573
pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26577
#define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26578
#define XML_SCHEMA_PUSH_TEXT_CREATED 2
26579
#define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26582
xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26583
int nodeType, const xmlChar *value, int len,
26584
int mode, int *consumed)
26587
* Unfortunately we have to duplicate the text sometimes.
26588
* OPTIMIZE: Maybe we could skip it, if:
26589
* 1. content type is simple
26590
* 2. whitespace is "collapse"
26591
* 3. it consists of whitespace only
26593
* Process character content.
26595
if (consumed != NULL)
26597
if (INODE_NILLED(vctxt->inode)) {
26599
* SPEC cvc-elt (3.3.4 - 3.2.1)
26600
* "The element information item must have no character or
26601
* element information item [children]."
26603
VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
26604
"Neither character nor element content is allowed "
26605
"because the element is 'nilled'");
26606
return (vctxt->err);
26609
* SPEC (2.1) "If the {content type} is empty, then the
26610
* element information item has no character or element
26611
* information item [children]."
26613
if (vctxt->inode->typeDef->contentType ==
26614
XML_SCHEMA_CONTENT_EMPTY) {
26615
VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
26616
"Character content is not allowed, "
26617
"because the content type is empty");
26618
return (vctxt->err);
26621
if (vctxt->inode->typeDef->contentType ==
26622
XML_SCHEMA_CONTENT_ELEMENTS) {
26623
if ((nodeType != XML_TEXT_NODE) ||
26624
(! xmlSchemaIsBlank((xmlChar *) value, len))) {
26626
* SPEC cvc-complex-type (2.3)
26627
* "If the {content type} is element-only, then the
26628
* element information item has no character information
26629
* item [children] other than those whose [character
26630
* code] is defined as a white space in [XML 1.0 (Second
26633
VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
26634
"Character content other than whitespace is not allowed "
26635
"because the content type is 'element-only'");
26636
return (vctxt->err);
26641
if ((value == NULL) || (value[0] == 0))
26645
* NOTE that even if the content type is *mixed*, we need the
26646
* *initial value* for default/fixed value constraints.
26648
if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
26649
((vctxt->inode->decl == NULL) ||
26650
(vctxt->inode->decl->value == NULL)))
26653
if (vctxt->inode->value == NULL) {
26658
case XML_SCHEMA_PUSH_TEXT_PERSIST:
26660
* When working on a tree.
26662
vctxt->inode->value = value;
26664
case XML_SCHEMA_PUSH_TEXT_CREATED:
26666
* When working with the reader.
26667
* The value will be freed by the element info.
26669
vctxt->inode->value = value;
26670
if (consumed != NULL)
26672
vctxt->inode->flags |=
26673
XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26675
case XML_SCHEMA_PUSH_TEXT_VOLATILE:
26677
* When working with SAX.
26678
* The value will be freed by the element info.
26681
vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
26683
vctxt->inode->value = BAD_CAST xmlStrdup(value);
26684
vctxt->inode->flags |=
26685
XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26692
len = xmlStrlen(value);
26694
* Concat the value.
26696
if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
26697
vctxt->inode->value = BAD_CAST xmlStrncat(
26698
(xmlChar *) vctxt->inode->value, value, len);
26700
vctxt->inode->value =
26701
BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
26702
vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26710
xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
26714
if ((vctxt->skipDepth != -1) &&
26715
(vctxt->depth >= vctxt->skipDepth)) {
26716
VERROR_INT("xmlSchemaValidateElem",
26718
goto internal_error;
26720
if (vctxt->xsiAssemble) {
26722
* We will stop validation if there was an error during
26723
* dynamic schema construction.
26724
* Note that we simply set @skipDepth to 0, this could
26725
* mean that a streaming document via SAX would be
26726
* still read to the end but it won't be validated any more.
26727
* TODO: If we are sure how to stop the validation at once
26728
* for all input scenarios, then this should be changed to
26729
* instantly stop the validation.
26731
ret = xmlSchemaAssembleByXSI(vctxt);
26734
goto internal_error;
26735
vctxt->skipDepth = 0;
26739
if (vctxt->depth > 0) {
26741
* Validate this element against the content model
26744
ret = xmlSchemaValidateChildElem(vctxt);
26747
VERROR_INT("xmlSchemaValidateElem",
26748
"calling xmlSchemaStreamValidateChildElement()");
26749
goto internal_error;
26753
if (vctxt->depth == vctxt->skipDepth)
26755
if ((vctxt->inode->decl == NULL) &&
26756
(vctxt->inode->typeDef == NULL)) {
26757
VERROR_INT("xmlSchemaValidateElem",
26758
"the child element was valid but neither the "
26759
"declaration nor the type was set");
26760
goto internal_error;
26764
* Get the declaration of the validation root.
26766
vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26767
vctxt->inode->localName,
26768
vctxt->inode->nsName);
26769
if (vctxt->inode->decl == NULL) {
26770
ret = XML_SCHEMAV_CVC_ELT_1;
26772
"No matching global declaration available "
26773
"for the validation root");
26778
if (vctxt->inode->decl == NULL)
26779
goto type_validation;
26781
if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
26786
ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
26789
VERROR_INT("xmlSchemaValidateElem",
26790
"calling xmlSchemaValidateElemWildcard()");
26791
goto internal_error;
26796
vctxt->skipDepth = vctxt->depth;
26800
* The declaration might be set by the wildcard validation,
26801
* when the processContents is "lax" or "strict".
26803
if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
26805
* Clear the "decl" field to not confuse further processing.
26807
vctxt->inode->decl = NULL;
26808
goto type_validation;
26812
* Validate against the declaration.
26814
ret = xmlSchemaValidateElemDecl(vctxt);
26817
VERROR_INT("xmlSchemaValidateElem",
26818
"calling xmlSchemaValidateElemDecl()");
26819
goto internal_error;
26824
* Validate against the type definition.
26828
if (vctxt->inode->typeDef == NULL) {
26829
vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26830
ret = XML_SCHEMAV_CVC_TYPE_1;
26832
"The type definition is absent");
26835
if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
26836
vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26837
ret = XML_SCHEMAV_CVC_TYPE_2;
26839
"The type definition is abstract");
26843
* Evaluate IDCs. Do it here, since new IDC matchers are registered
26844
* during validation against the declaration. This must be done
26845
* _before_ attribute validation.
26847
if (vctxt->xpathStates != NULL) {
26848
ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
26849
vctxt->inode->appliedXPath = 1;
26851
VERROR_INT("xmlSchemaValidateElem",
26852
"calling xmlSchemaXPathEvaluate()");
26853
goto internal_error;
26857
* Validate attributes.
26859
if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
26860
if ((vctxt->nbAttrInfos != 0) ||
26861
(vctxt->inode->typeDef->attrUses != NULL)) {
26863
ret = xmlSchemaVAttributesComplex(vctxt);
26865
} else if (vctxt->nbAttrInfos != 0) {
26867
ret = xmlSchemaVAttributesSimple(vctxt);
26870
* Clear registered attributes.
26872
if (vctxt->nbAttrInfos != 0)
26873
xmlSchemaClearAttrInfos(vctxt);
26875
VERROR_INT("xmlSchemaValidateElem",
26876
"calling attributes validation");
26877
goto internal_error;
26880
* Don't return an error if attributes are invalid on purpose.
26886
vctxt->skipDepth = vctxt->depth;
26892
#ifdef XML_SCHEMA_READER_ENABLED
26894
xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
26896
const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
26897
int depth, nodeType, ret = 0, consumed;
26898
xmlSchemaNodeInfoPtr ielem;
26901
ret = xmlTextReaderRead(vctxt->reader);
26903
* Move to the document element.
26906
nodeType = xmlTextReaderNodeType(vctxt->reader);
26907
if (nodeType == XML_ELEMENT_NODE)
26909
ret = xmlTextReaderRead(vctxt->reader);
26916
depth = xmlTextReaderDepth(vctxt->reader);
26917
nodeType = xmlTextReaderNodeType(vctxt->reader);
26919
if (nodeType == XML_ELEMENT_NODE) {
26922
if (xmlSchemaValidatorPushElem(vctxt) == -1) {
26923
VERROR_INT("xmlSchemaVReaderWalk",
26924
"calling xmlSchemaValidatorPushElem()");
26925
goto internal_error;
26927
ielem = vctxt->inode;
26928
ielem->localName = xmlTextReaderLocalName(vctxt->reader);
26929
ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
26930
ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
26932
* Is the element empty?
26934
ret = xmlTextReaderIsEmptyElement(vctxt->reader);
26936
VERROR_INT("xmlSchemaVReaderWalk",
26937
"calling xmlTextReaderIsEmptyElement()");
26938
goto internal_error;
26941
ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
26944
* Register attributes.
26946
vctxt->nbAttrInfos = 0;
26947
ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
26949
VERROR_INT("xmlSchemaVReaderWalk",
26950
"calling xmlTextReaderMoveToFirstAttribute()");
26951
goto internal_error;
26956
* VAL TODO: How do we know that the reader works on a
26957
* node tree, to be able to pass a node here?
26959
if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
26960
(const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
26961
xmlTextReaderNamespaceUri(vctxt->reader), 1,
26962
xmlTextReaderValue(vctxt->reader), 1) == -1) {
26964
VERROR_INT("xmlSchemaVReaderWalk",
26965
"calling xmlSchemaValidatorPushAttribute()");
26966
goto internal_error;
26968
ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
26970
VERROR_INT("xmlSchemaVReaderWalk",
26971
"calling xmlTextReaderMoveToFirstAttribute()");
26972
goto internal_error;
26974
} while (ret == 1);
26976
* Back to element position.
26978
ret = xmlTextReaderMoveToElement(vctxt->reader);
26980
VERROR_INT("xmlSchemaVReaderWalk",
26981
"calling xmlTextReaderMoveToElement()");
26982
goto internal_error;
26986
* Validate the element.
26988
ret= xmlSchemaValidateElem(vctxt);
26991
VERROR_INT("xmlSchemaVReaderWalk",
26992
"calling xmlSchemaValidateElem()");
26993
goto internal_error;
26997
if (vctxt->depth == vctxt->skipDepth) {
27000
* Skip all content.
27002
if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
27003
ret = xmlTextReaderRead(vctxt->reader);
27004
curDepth = xmlTextReaderDepth(vctxt->reader);
27005
while ((ret == 1) && (curDepth != depth)) {
27006
ret = xmlTextReaderRead(vctxt->reader);
27007
curDepth = xmlTextReaderDepth(vctxt->reader);
27011
* VAL TODO: A reader error occured; what to do here?
27020
* READER VAL TODO: Is an END_ELEM really never called
27021
* if the elem is empty?
27023
if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27025
} else if (nodeType == END_ELEM) {
27027
* Process END of element.
27030
ret = xmlSchemaValidatorPopElem(vctxt);
27033
VERROR_INT("xmlSchemaVReaderWalk",
27034
"calling xmlSchemaValidatorPopElem()");
27035
goto internal_error;
27039
if (vctxt->depth >= 0)
27040
ielem = vctxt->inode;
27043
} else if ((nodeType == XML_TEXT_NODE) ||
27044
(nodeType == XML_CDATA_SECTION_NODE) ||
27045
(nodeType == WHTSP) ||
27046
(nodeType == SIGN_WHTSP)) {
27048
* Process character content.
27052
if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
27053
nodeType = XML_TEXT_NODE;
27055
value = xmlTextReaderValue(vctxt->reader);
27056
ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
27057
-1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
27061
VERROR_INT("xmlSchemaVReaderWalk",
27062
"calling xmlSchemaVPushText()");
27063
goto internal_error;
27065
} else if ((nodeType == XML_ENTITY_NODE) ||
27066
(nodeType == XML_ENTITY_REF_NODE)) {
27068
* VAL TODO: What to do with entities?
27075
ret = xmlTextReaderRead(vctxt->reader);
27076
} while (ret == 1);
27085
/************************************************************************
27087
* SAX validation handlers *
27089
************************************************************************/
27092
* Process text content.
27095
xmlSchemaSAXHandleText(void *ctx,
27096
const xmlChar * ch,
27099
xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27101
if (vctxt->depth < 0)
27103
if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27105
if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27106
vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27107
if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
27108
XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27109
VERROR_INT("xmlSchemaSAXHandleCDataSection",
27110
"calling xmlSchemaVPushText()");
27112
xmlStopParser(vctxt->parserCtxt);
27117
* Process CDATA content.
27120
xmlSchemaSAXHandleCDataSection(void *ctx,
27121
const xmlChar * ch,
27124
xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27126
if (vctxt->depth < 0)
27128
if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27130
if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27131
vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27132
if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
27133
XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27134
VERROR_INT("xmlSchemaSAXHandleCDataSection",
27135
"calling xmlSchemaVPushText()");
27137
xmlStopParser(vctxt->parserCtxt);
27142
xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
27143
const xmlChar * name ATTRIBUTE_UNUSED)
27145
xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27147
if (vctxt->depth < 0)
27149
if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27151
/* SAX VAL TODO: What to do here? */
27156
xmlSchemaSAXHandleStartElementNs(void *ctx,
27157
const xmlChar * localname,
27158
const xmlChar * prefix ATTRIBUTE_UNUSED,
27159
const xmlChar * URI,
27161
const xmlChar ** namespaces,
27163
int nb_defaulted ATTRIBUTE_UNUSED,
27164
const xmlChar ** attributes)
27166
xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27168
xmlSchemaNodeInfoPtr ielem;
27172
* SAX VAL TODO: What to do with nb_defaulted?
27175
* Skip elements if inside a "skip" wildcard or invalid.
27178
if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27181
* Push the element.
27183
if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27184
VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27185
"calling xmlSchemaValidatorPushElem()");
27186
goto internal_error;
27188
ielem = vctxt->inode;
27190
* TODO: Is this OK?
27192
ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
27193
ielem->localName = localname;
27194
ielem->nsName = URI;
27195
ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27197
* Register namespaces on the elem info.
27199
if (nb_namespaces != 0) {
27201
* Although the parser builds its own namespace list,
27202
* we have no access to it, so we'll use an own one.
27204
for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
27206
* Store prefix and namespace name.
27208
if (ielem->nsBindings == NULL) {
27209
ielem->nsBindings =
27210
(const xmlChar **) xmlMalloc(10 *
27211
sizeof(const xmlChar *));
27212
if (ielem->nsBindings == NULL) {
27213
xmlSchemaVErrMemory(vctxt,
27214
"allocating namespace bindings for SAX validation",
27216
goto internal_error;
27218
ielem->nbNsBindings = 0;
27219
ielem->sizeNsBindings = 5;
27220
} else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
27221
ielem->sizeNsBindings *= 2;
27222
ielem->nsBindings =
27223
(const xmlChar **) xmlRealloc(
27224
(void *) ielem->nsBindings,
27225
ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
27226
if (ielem->nsBindings == NULL) {
27227
xmlSchemaVErrMemory(vctxt,
27228
"re-allocating namespace bindings for SAX validation",
27230
goto internal_error;
27234
ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
27235
if (namespaces[j+1][0] == 0) {
27239
ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
27241
ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
27243
ielem->nbNsBindings++;
27247
* Register attributes.
27248
* SAX VAL TODO: We are not adding namespace declaration
27251
if (nb_attributes != 0) {
27254
for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
27256
* Duplicate the value.
27258
value = xmlStrndup(attributes[j+3],
27259
attributes[j+4] - attributes[j+3]);
27261
* TODO: Set the node line.
27263
ret = xmlSchemaValidatorPushAttribute(vctxt,
27264
NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
27267
VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27268
"calling xmlSchemaValidatorPushAttribute()");
27269
goto internal_error;
27274
* Validate the element.
27276
ret = xmlSchemaValidateElem(vctxt);
27279
VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27280
"calling xmlSchemaValidateElem()");
27281
goto internal_error;
27290
xmlStopParser(vctxt->parserCtxt);
27295
xmlSchemaSAXHandleEndElementNs(void *ctx,
27296
const xmlChar * localname ATTRIBUTE_UNUSED,
27297
const xmlChar * prefix ATTRIBUTE_UNUSED,
27298
const xmlChar * URI ATTRIBUTE_UNUSED)
27300
xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27304
* Skip elements if inside a "skip" wildcard or if invalid.
27306
if (vctxt->skipDepth != -1) {
27307
if (vctxt->depth > vctxt->skipDepth) {
27311
vctxt->skipDepth = -1;
27314
* SAX VAL TODO: Just a temporary check.
27316
if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27317
(!xmlStrEqual(vctxt->inode->nsName, URI))) {
27318
VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27319
"elem pop mismatch");
27321
res = xmlSchemaValidatorPopElem(vctxt);
27324
VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27325
"calling xmlSchemaValidatorPopElem()");
27326
goto internal_error;
27334
xmlStopParser(vctxt->parserCtxt);
27338
/************************************************************************
27340
* Validation interfaces *
27342
************************************************************************/
27345
* xmlSchemaNewValidCtxt:
27346
* @schema: a precompiled XML Schemas
27348
* Create an XML Schemas validation context based on the given schema.
27350
* Returns the validation context or NULL in case of error
27352
xmlSchemaValidCtxtPtr
27353
xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
27355
xmlSchemaValidCtxtPtr ret;
27357
ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27359
xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
27362
memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27363
ret->type = XML_SCHEMA_CTXT_VALIDATOR;
27364
ret->dict = xmlDictCreate();
27365
ret->nodeQNames = xmlSchemaItemListCreate();
27366
ret->schema = schema;
27371
* xmlSchemaClearValidCtxt:
27372
* @ctxt: the schema validation context
27374
* Free the resources associated to the schema validation context;
27375
* leaves some fields alive intended for reuse of the context.
27378
xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27384
* TODO: Should we clear the flags?
27385
* Might be problematic if one reuses the context
27386
* and assumes that the options remain the same.
27389
vctxt->validationRoot = NULL;
27391
#ifdef LIBXML_READER_ENABLED
27392
vctxt->reader = NULL;
27394
vctxt->hasKeyrefs = 0;
27396
if (vctxt->value != NULL) {
27397
xmlSchemaFreeValue(vctxt->value);
27398
vctxt->value = NULL;
27401
* Augmented IDC information.
27403
if (vctxt->aidcs != NULL) {
27404
xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27409
} while (cur != NULL);
27410
vctxt->aidcs = NULL;
27412
if (vctxt->idcMatcherCache != NULL) {
27413
xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27417
matcher = matcher->nextCached;
27418
xmlSchemaIDCFreeMatcherList(tmp);
27420
vctxt->idcMatcherCache = NULL;
27424
if (vctxt->idcNodes != NULL) {
27426
xmlSchemaPSVIIDCNodePtr item;
27428
for (i = 0; i < vctxt->nbIdcNodes; i++) {
27429
item = vctxt->idcNodes[i];
27430
xmlFree(item->keys);
27433
xmlFree(vctxt->idcNodes);
27434
vctxt->idcNodes = NULL;
27435
vctxt->nbIdcNodes = 0;
27436
vctxt->sizeIdcNodes = 0;
27439
* Note that we won't delete the XPath state pool here.
27441
if (vctxt->xpathStates != NULL) {
27442
xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27443
vctxt->xpathStates = NULL;
27448
if (vctxt->nbAttrInfos != 0) {
27449
xmlSchemaClearAttrInfos(vctxt);
27454
if (vctxt->elemInfos != NULL) {
27456
xmlSchemaNodeInfoPtr ei;
27458
for (i = 0; i < vctxt->sizeElemInfos; i++) {
27459
ei = vctxt->elemInfos[i];
27462
xmlSchemaClearElemInfo(vctxt, ei);
27465
xmlSchemaItemListClear(vctxt->nodeQNames);
27466
/* Recreate the dict. */
27467
xmlDictFree(vctxt->dict);
27469
* TODO: Is is save to recreate it? Do we have a scenario
27470
* where the user provides the dict?
27472
vctxt->dict = xmlDictCreate();
27476
* xmlSchemaFreeValidCtxt:
27477
* @ctxt: the schema validation context
27479
* Free the resources associated to the schema validation context
27482
xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
27486
if (ctxt->value != NULL)
27487
xmlSchemaFreeValue(ctxt->value);
27488
if (ctxt->pctxt != NULL)
27489
xmlSchemaFreeParserCtxt(ctxt->pctxt);
27490
if (ctxt->idcNodes != NULL) {
27492
xmlSchemaPSVIIDCNodePtr item;
27494
for (i = 0; i < ctxt->nbIdcNodes; i++) {
27495
item = ctxt->idcNodes[i];
27496
xmlFree(item->keys);
27499
xmlFree(ctxt->idcNodes);
27501
if (ctxt->idcKeys != NULL) {
27503
for (i = 0; i < ctxt->nbIdcKeys; i++)
27504
xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27505
xmlFree(ctxt->idcKeys);
27508
if (ctxt->xpathStates != NULL) {
27509
xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27510
ctxt->xpathStates = NULL;
27512
if (ctxt->xpathStatePool != NULL) {
27513
xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27514
ctxt->xpathStatePool = NULL;
27518
* Augmented IDC information.
27520
if (ctxt->aidcs != NULL) {
27521
xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27526
} while (cur != NULL);
27528
if (ctxt->attrInfos != NULL) {
27530
xmlSchemaAttrInfoPtr attr;
27532
/* Just a paranoid call to the cleanup. */
27533
if (ctxt->nbAttrInfos != 0)
27534
xmlSchemaClearAttrInfos(ctxt);
27535
for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27536
attr = ctxt->attrInfos[i];
27539
xmlFree(ctxt->attrInfos);
27541
if (ctxt->elemInfos != NULL) {
27543
xmlSchemaNodeInfoPtr ei;
27545
for (i = 0; i < ctxt->sizeElemInfos; i++) {
27546
ei = ctxt->elemInfos[i];
27549
xmlSchemaClearElemInfo(ctxt, ei);
27552
xmlFree(ctxt->elemInfos);
27554
if (ctxt->nodeQNames != NULL)
27555
xmlSchemaItemListFree(ctxt->nodeQNames);
27556
if (ctxt->dict != NULL)
27557
xmlDictFree(ctxt->dict);
27562
* xmlSchemaIsValid:
27563
* @ctxt: the schema validation context
27565
* Check if any error was detected during validation.
27567
* Returns 1 if valid so far, 0 if errors were detected, and -1 in case
27568
* of internal error.
27571
xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
27575
return(ctxt->err == 0);
27579
* xmlSchemaSetValidErrors:
27580
* @ctxt: a schema validation context
27581
* @err: the error function
27582
* @warn: the warning function
27583
* @ctx: the functions context
27585
* Set the error and warning callback informations
27588
xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27589
xmlSchemaValidityErrorFunc err,
27590
xmlSchemaValidityWarningFunc warn, void *ctx)
27595
ctxt->warning = warn;
27596
ctxt->errCtxt = ctx;
27597
if (ctxt->pctxt != NULL)
27598
xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
27602
* xmlSchemaSetValidStructuredErrors:
27603
* @ctxt: a schema validation context
27604
* @serror: the structured error function
27605
* @ctx: the functions context
27607
* Set the structured error callback
27610
xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
27611
xmlStructuredErrorFunc serror, void *ctx)
27615
ctxt->serror = serror;
27616
ctxt->error = NULL;
27617
ctxt->warning = NULL;
27618
ctxt->errCtxt = ctx;
27619
if (ctxt->pctxt != NULL)
27620
xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
27624
* xmlSchemaGetValidErrors:
27625
* @ctxt: a XML-Schema validation context
27626
* @err: the error function result
27627
* @warn: the warning function result
27628
* @ctx: the functions context result
27630
* Get the error and warning callback informations
27632
* Returns -1 in case of error and 0 otherwise
27635
xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27636
xmlSchemaValidityErrorFunc * err,
27637
xmlSchemaValidityWarningFunc * warn, void **ctx)
27642
*err = ctxt->error;
27644
*warn = ctxt->warning;
27646
*ctx = ctxt->errCtxt;
27652
* xmlSchemaSetValidOptions:
27653
* @ctxt: a schema validation context
27654
* @options: a combination of xmlSchemaValidOption
27656
* Sets the options to be used during the validation.
27658
* Returns 0 in case of success, -1 in case of an
27662
xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
27671
* WARNING: Change the start value if adding to the
27672
* xmlSchemaValidOption.
27673
* TODO: Is there an other, more easy to maintain,
27676
for (i = 1; i < (int) sizeof(int) * 8; i++) {
27677
if (options & 1<<i)
27680
ctxt->options = options;
27685
* xmlSchemaValidCtxtGetOptions:
27686
* @ctxt: a schema validation context
27688
* Get the validation context options.
27690
* Returns the option combination or -1 on error.
27693
xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
27699
return (ctxt->options);
27703
xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
27707
xmlSchemaNodeInfoPtr ielem = NULL;
27708
xmlNodePtr node, valRoot;
27709
const xmlChar *nsName;
27711
/* DOC VAL TODO: Move this to the start function. */
27712
valRoot = xmlDocGetRootElement(vctxt->doc);
27713
if (valRoot == NULL) {
27714
/* VAL TODO: Error code? */
27715
VERROR(1, NULL, "The document has no document element");
27719
vctxt->validationRoot = valRoot;
27721
while (node != NULL) {
27722
if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27724
if (node->type == XML_ELEMENT_NODE) {
27727
* Init the node-info.
27730
if (xmlSchemaValidatorPushElem(vctxt) == -1)
27731
goto internal_error;
27732
ielem = vctxt->inode;
27733
ielem->node = node;
27734
ielem->nodeLine = node->line;
27735
ielem->localName = node->name;
27736
if (node->ns != NULL)
27737
ielem->nsName = node->ns->href;
27738
ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27740
* Register attributes.
27741
* DOC VAL TODO: We do not register namespace declaration
27744
vctxt->nbAttrInfos = 0;
27745
if (node->properties != NULL) {
27746
attr = node->properties;
27748
if (attr->ns != NULL)
27749
nsName = attr->ns->href;
27752
ret = xmlSchemaValidatorPushAttribute(vctxt,
27755
* Note that we give it the line number of the
27759
attr->name, nsName, 0,
27760
xmlNodeListGetString(attr->doc, attr->children, 1), 1);
27762
VERROR_INT("xmlSchemaDocWalk",
27763
"calling xmlSchemaValidatorPushAttribute()");
27764
goto internal_error;
27770
* Validate the element.
27772
ret = xmlSchemaValidateElem(vctxt);
27775
VERROR_INT("xmlSchemaDocWalk",
27776
"calling xmlSchemaValidateElem()");
27777
goto internal_error;
27780
* Don't stop validation; just skip the content
27785
if ((vctxt->skipDepth != -1) &&
27786
(vctxt->depth >= vctxt->skipDepth))
27788
} else if ((node->type == XML_TEXT_NODE) ||
27789
(node->type == XML_CDATA_SECTION_NODE)) {
27791
* Process character content.
27793
if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
27794
ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27795
ret = xmlSchemaVPushText(vctxt, node->type, node->content,
27796
-1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
27798
VERROR_INT("xmlSchemaVDocWalk",
27799
"calling xmlSchemaVPushText()");
27800
goto internal_error;
27803
* DOC VAL TODO: Should we skip further validation of the
27804
* element content here?
27806
} else if ((node->type == XML_ENTITY_NODE) ||
27807
(node->type == XML_ENTITY_REF_NODE)) {
27809
* DOC VAL TODO: What to do with entities?
27811
VERROR_INT("xmlSchemaVDocWalk",
27812
"there is at least one entity reference in the node-tree "
27813
"currently being validated. Processing of entities with "
27814
"this XML Schema processor is not supported (yet). Please "
27815
"substitute entities before validation.");
27816
goto internal_error;
27820
* DOC VAL TODO: XInclude nodes, etc.
27826
if (node->children != NULL) {
27827
node = node->children;
27831
if (node->type == XML_ELEMENT_NODE) {
27833
* Leaving the scope of an element.
27835
if (node != vctxt->inode->node) {
27836
VERROR_INT("xmlSchemaVDocWalk",
27837
"element position mismatch");
27838
goto internal_error;
27840
ret = xmlSchemaValidatorPopElem(vctxt);
27843
VERROR_INT("xmlSchemaVDocWalk",
27844
"calling xmlSchemaValidatorPopElem()");
27845
goto internal_error;
27848
if (node == valRoot)
27852
if (node->next != NULL)
27855
node = node->parent;
27867
xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
27869
* Some initialization.
27872
vctxt->nberrors = 0;
27874
vctxt->skipDepth = -1;
27875
vctxt->xsiAssemble = 0;
27876
vctxt->hasKeyrefs = 0;
27877
#ifdef ENABLE_IDC_NODE_TABLES_TEST
27878
vctxt->createIDCNodeTables = 1;
27880
vctxt->createIDCNodeTables = 0;
27883
* Create a schema + parser if necessary.
27885
if (vctxt->schema == NULL) {
27886
xmlSchemaParserCtxtPtr pctxt;
27888
vctxt->xsiAssemble = 1;
27890
* If not schema was given then we will create a schema
27891
* dynamically using XSI schema locations.
27893
* Create the schema parser context.
27895
if ((vctxt->pctxt == NULL) &&
27896
(xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
27898
pctxt = vctxt->pctxt;
27899
pctxt->xsiAssemble = 1;
27901
* Create the schema.
27903
vctxt->schema = xmlSchemaNewSchema(pctxt);
27904
if (vctxt->schema == NULL)
27907
* Create the schema construction context.
27909
pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
27910
if (pctxt->constructor == NULL)
27912
pctxt->constructor->mainSchema = vctxt->schema;
27914
* Take ownership of the constructor to be able to free it.
27916
pctxt->ownsConstructor = 1;
27919
* Augment the IDC definitions for the main schema and all imported ones
27920
* NOTE: main schema if the first in the imported list
27922
xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
27928
xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
27929
if (vctxt->xsiAssemble) {
27930
if (vctxt->schema != NULL) {
27931
xmlSchemaFree(vctxt->schema);
27932
vctxt->schema = NULL;
27935
xmlSchemaClearValidCtxt(vctxt);
27939
xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
27943
if (xmlSchemaPreRun(vctxt) < 0)
27946
if (vctxt->doc != NULL) {
27950
ret = xmlSchemaVDocWalk(vctxt);
27951
#ifdef LIBXML_READER_ENABLED
27952
} else if (vctxt->reader != NULL) {
27954
* XML Reader validation.
27956
#ifdef XML_SCHEMA_READER_ENABLED
27957
ret = xmlSchemaVReaderWalk(vctxt);
27960
} else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
27964
ret = xmlParseDocument(vctxt->parserCtxt);
27966
VERROR_INT("xmlSchemaVStart",
27967
"no instance to validate");
27971
xmlSchemaPostRun(vctxt);
27978
* xmlSchemaValidateOneElement:
27979
* @ctxt: a schema validation context
27980
* @elem: an element node
27982
* Validate a branch of a tree, starting with the given @elem.
27984
* Returns 0 if the element and its subtree is valid, a positive error
27985
* code number otherwise and -1 in case of an internal or API error.
27988
xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
27990
if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
27993
if (ctxt->schema == NULL)
27996
ctxt->doc = elem->doc;
27998
ctxt->validationRoot = elem;
27999
return(xmlSchemaVStart(ctxt));
28003
* xmlSchemaValidateDoc:
28004
* @ctxt: a schema validation context
28005
* @doc: a parsed document tree
28007
* Validate a document tree in memory.
28009
* Returns 0 if the document is schemas valid, a positive error code
28010
* number otherwise and -1 in case of internal or API error.
28013
xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
28015
if ((ctxt == NULL) || (doc == NULL))
28019
ctxt->node = xmlDocGetRootElement(doc);
28020
if (ctxt->node == NULL) {
28021
xmlSchemaCustomErr(ACTXT_CAST ctxt,
28022
XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
28023
(xmlNodePtr) doc, NULL,
28024
"The document has no document element", NULL, NULL);
28025
return (ctxt->err);
28027
ctxt->validationRoot = ctxt->node;
28028
return (xmlSchemaVStart(ctxt));
28032
/************************************************************************
28034
* Function and data for SAX streaming API *
28036
************************************************************************/
28037
typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
28038
typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
28040
struct _xmlSchemaSplitSAXData {
28041
xmlSAXHandlerPtr user_sax;
28043
xmlSchemaValidCtxtPtr ctxt;
28044
xmlSAXHandlerPtr schemas_sax;
28047
#define XML_SAX_PLUG_MAGIC 0xdc43ba21
28049
struct _xmlSchemaSAXPlug {
28050
unsigned int magic;
28052
/* the original callbacks informations */
28053
xmlSAXHandlerPtr *user_sax_ptr;
28054
xmlSAXHandlerPtr user_sax;
28055
void **user_data_ptr;
28058
/* the block plugged back and validation informations */
28059
xmlSAXHandler schemas_sax;
28060
xmlSchemaValidCtxtPtr ctxt;
28063
/* All those functions just bounces to the user provided SAX handlers */
28065
internalSubsetSplit(void *ctx, const xmlChar *name,
28066
const xmlChar *ExternalID, const xmlChar *SystemID)
28068
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28069
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28070
(ctxt->user_sax->internalSubset != NULL))
28071
ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
28076
isStandaloneSplit(void *ctx)
28078
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28079
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28080
(ctxt->user_sax->isStandalone != NULL))
28081
return(ctxt->user_sax->isStandalone(ctxt->user_data));
28086
hasInternalSubsetSplit(void *ctx)
28088
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28089
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28090
(ctxt->user_sax->hasInternalSubset != NULL))
28091
return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
28096
hasExternalSubsetSplit(void *ctx)
28098
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28099
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28100
(ctxt->user_sax->hasExternalSubset != NULL))
28101
return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
28106
externalSubsetSplit(void *ctx, const xmlChar *name,
28107
const xmlChar *ExternalID, const xmlChar *SystemID)
28109
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28110
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28111
(ctxt->user_sax->externalSubset != NULL))
28112
ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
28116
static xmlParserInputPtr
28117
resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
28119
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28120
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28121
(ctxt->user_sax->resolveEntity != NULL))
28122
return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
28127
static xmlEntityPtr
28128
getEntitySplit(void *ctx, const xmlChar *name)
28130
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28131
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28132
(ctxt->user_sax->getEntity != NULL))
28133
return(ctxt->user_sax->getEntity(ctxt->user_data, name));
28137
static xmlEntityPtr
28138
getParameterEntitySplit(void *ctx, const xmlChar *name)
28140
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28141
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28142
(ctxt->user_sax->getParameterEntity != NULL))
28143
return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
28149
entityDeclSplit(void *ctx, const xmlChar *name, int type,
28150
const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
28152
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28153
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28154
(ctxt->user_sax->entityDecl != NULL))
28155
ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
28156
systemId, content);
28160
attributeDeclSplit(void *ctx, const xmlChar * elem,
28161
const xmlChar * name, int type, int def,
28162
const xmlChar * defaultValue, xmlEnumerationPtr tree)
28164
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28165
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28166
(ctxt->user_sax->attributeDecl != NULL)) {
28167
ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
28168
def, defaultValue, tree);
28170
xmlFreeEnumeration(tree);
28175
elementDeclSplit(void *ctx, const xmlChar *name, int type,
28176
xmlElementContentPtr content)
28178
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28179
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28180
(ctxt->user_sax->elementDecl != NULL))
28181
ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
28185
notationDeclSplit(void *ctx, const xmlChar *name,
28186
const xmlChar *publicId, const xmlChar *systemId)
28188
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28189
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28190
(ctxt->user_sax->notationDecl != NULL))
28191
ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
28196
unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
28197
const xmlChar *publicId, const xmlChar *systemId,
28198
const xmlChar *notationName)
28200
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28201
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28202
(ctxt->user_sax->unparsedEntityDecl != NULL))
28203
ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
28204
systemId, notationName);
28208
setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
28210
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28211
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28212
(ctxt->user_sax->setDocumentLocator != NULL))
28213
ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
28217
startDocumentSplit(void *ctx)
28219
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28220
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28221
(ctxt->user_sax->startDocument != NULL))
28222
ctxt->user_sax->startDocument(ctxt->user_data);
28226
endDocumentSplit(void *ctx)
28228
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28229
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28230
(ctxt->user_sax->endDocument != NULL))
28231
ctxt->user_sax->endDocument(ctxt->user_data);
28235
processingInstructionSplit(void *ctx, const xmlChar *target,
28236
const xmlChar *data)
28238
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28239
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28240
(ctxt->user_sax->processingInstruction != NULL))
28241
ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
28245
commentSplit(void *ctx, const xmlChar *value)
28247
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28248
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28249
(ctxt->user_sax->comment != NULL))
28250
ctxt->user_sax->comment(ctxt->user_data, value);
28254
* Varargs error callbacks to the user application, harder ...
28257
static void XMLCDECL
28258
warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28259
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28260
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28261
(ctxt->user_sax->warning != NULL)) {
28265
static void XMLCDECL
28266
errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28267
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28268
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28269
(ctxt->user_sax->error != NULL)) {
28273
static void XMLCDECL
28274
fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28275
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28276
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28277
(ctxt->user_sax->fatalError != NULL)) {
28283
* Those are function where both the user handler and the schemas handler
28284
* need to be called.
28287
charactersSplit(void *ctx, const xmlChar *ch, int len)
28289
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28292
if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
28293
ctxt->user_sax->characters(ctxt->user_data, ch, len);
28294
if (ctxt->ctxt != NULL)
28295
xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28299
ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28301
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28304
if ((ctxt->user_sax != NULL) &&
28305
(ctxt->user_sax->ignorableWhitespace != NULL))
28306
ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28307
if (ctxt->ctxt != NULL)
28308
xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28312
cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28314
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28317
if ((ctxt->user_sax != NULL) &&
28318
(ctxt->user_sax->cdataBlock != NULL))
28319
ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28320
if (ctxt->ctxt != NULL)
28321
xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28325
referenceSplit(void *ctx, const xmlChar *name)
28327
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28330
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28331
(ctxt->user_sax->reference != NULL))
28332
ctxt->user_sax->reference(ctxt->user_data, name);
28333
if (ctxt->ctxt != NULL)
28334
xmlSchemaSAXHandleReference(ctxt->user_data, name);
28338
startElementNsSplit(void *ctx, const xmlChar * localname,
28339
const xmlChar * prefix, const xmlChar * URI,
28340
int nb_namespaces, const xmlChar ** namespaces,
28341
int nb_attributes, int nb_defaulted,
28342
const xmlChar ** attributes) {
28343
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28346
if ((ctxt->user_sax != NULL) &&
28347
(ctxt->user_sax->startElementNs != NULL))
28348
ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28349
URI, nb_namespaces, namespaces,
28350
nb_attributes, nb_defaulted,
28352
if (ctxt->ctxt != NULL)
28353
xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28354
URI, nb_namespaces, namespaces,
28355
nb_attributes, nb_defaulted,
28360
endElementNsSplit(void *ctx, const xmlChar * localname,
28361
const xmlChar * prefix, const xmlChar * URI) {
28362
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28365
if ((ctxt->user_sax != NULL) &&
28366
(ctxt->user_sax->endElementNs != NULL))
28367
ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28368
if (ctxt->ctxt != NULL)
28369
xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28373
* xmlSchemaSAXPlug:
28374
* @ctxt: a schema validation context
28375
* @sax: a pointer to the original xmlSAXHandlerPtr
28376
* @user_data: a pointer to the original SAX user data pointer
28378
* Plug a SAX based validation layer in a SAX parsing event flow.
28379
* The original @saxptr and @dataptr data are replaced by new pointers
28380
* but the calls to the original will be maintained.
28382
* Returns a pointer to a data structure needed to unplug the validation layer
28383
* or NULL in case of errors.
28385
xmlSchemaSAXPlugPtr
28386
xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
28387
xmlSAXHandlerPtr *sax, void **user_data)
28389
xmlSchemaSAXPlugPtr ret;
28390
xmlSAXHandlerPtr old_sax;
28392
if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
28396
* We only allow to plug into SAX2 event streams
28399
if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
28401
if ((old_sax != NULL) &&
28402
(old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
28403
((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
28407
* everything seems right allocate the local data needed for that layer
28409
ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28413
memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28414
ret->magic = XML_SAX_PLUG_MAGIC;
28415
ret->schemas_sax.initialized = XML_SAX2_MAGIC;
28417
ret->user_sax_ptr = sax;
28418
ret->user_sax = old_sax;
28419
if (old_sax == NULL) {
28421
* go direct, no need for the split block and functions.
28423
ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28424
ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28426
* Note that we use the same text-function for both, to prevent
28427
* the parser from testing for ignorable whitespace.
28429
ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28430
ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28432
ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28433
ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28435
ret->user_data = ctxt;
28439
* for each callback unused by Schemas initialize it to the Split
28440
* routine only if non NULL in the user block, this can speed up
28441
* things at the SAX level.
28443
if (old_sax->internalSubset != NULL)
28444
ret->schemas_sax.internalSubset = internalSubsetSplit;
28445
if (old_sax->isStandalone != NULL)
28446
ret->schemas_sax.isStandalone = isStandaloneSplit;
28447
if (old_sax->hasInternalSubset != NULL)
28448
ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28449
if (old_sax->hasExternalSubset != NULL)
28450
ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28451
if (old_sax->resolveEntity != NULL)
28452
ret->schemas_sax.resolveEntity = resolveEntitySplit;
28453
if (old_sax->getEntity != NULL)
28454
ret->schemas_sax.getEntity = getEntitySplit;
28455
if (old_sax->entityDecl != NULL)
28456
ret->schemas_sax.entityDecl = entityDeclSplit;
28457
if (old_sax->notationDecl != NULL)
28458
ret->schemas_sax.notationDecl = notationDeclSplit;
28459
if (old_sax->attributeDecl != NULL)
28460
ret->schemas_sax.attributeDecl = attributeDeclSplit;
28461
if (old_sax->elementDecl != NULL)
28462
ret->schemas_sax.elementDecl = elementDeclSplit;
28463
if (old_sax->unparsedEntityDecl != NULL)
28464
ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28465
if (old_sax->setDocumentLocator != NULL)
28466
ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28467
if (old_sax->startDocument != NULL)
28468
ret->schemas_sax.startDocument = startDocumentSplit;
28469
if (old_sax->endDocument != NULL)
28470
ret->schemas_sax.endDocument = endDocumentSplit;
28471
if (old_sax->processingInstruction != NULL)
28472
ret->schemas_sax.processingInstruction = processingInstructionSplit;
28473
if (old_sax->comment != NULL)
28474
ret->schemas_sax.comment = commentSplit;
28475
if (old_sax->warning != NULL)
28476
ret->schemas_sax.warning = warningSplit;
28477
if (old_sax->error != NULL)
28478
ret->schemas_sax.error = errorSplit;
28479
if (old_sax->fatalError != NULL)
28480
ret->schemas_sax.fatalError = fatalErrorSplit;
28481
if (old_sax->getParameterEntity != NULL)
28482
ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28483
if (old_sax->externalSubset != NULL)
28484
ret->schemas_sax.externalSubset = externalSubsetSplit;
28487
* the 6 schemas callback have to go to the splitter functions
28488
* Note that we use the same text-function for ignorableWhitespace
28489
* if possible, to prevent the parser from testing for ignorable
28492
ret->schemas_sax.characters = charactersSplit;
28493
if ((old_sax->ignorableWhitespace != NULL) &&
28494
(old_sax->ignorableWhitespace != old_sax->characters))
28495
ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28497
ret->schemas_sax.ignorableWhitespace = charactersSplit;
28498
ret->schemas_sax.cdataBlock = cdataBlockSplit;
28499
ret->schemas_sax.reference = referenceSplit;
28500
ret->schemas_sax.startElementNs = startElementNsSplit;
28501
ret->schemas_sax.endElementNs = endElementNsSplit;
28503
ret->user_data_ptr = user_data;
28504
ret->user_data = *user_data;
28509
* plug the pointers back.
28511
*sax = &(ret->schemas_sax);
28513
ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28514
xmlSchemaPreRun(ctxt);
28519
* xmlSchemaSAXUnplug:
28520
* @plug: a data structure returned by xmlSchemaSAXPlug
28522
* Unplug a SAX based validation layer in a SAX parsing event flow.
28523
* The original pointers used in the call are restored.
28525
* Returns 0 in case of success and -1 in case of failure.
28528
xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
28530
xmlSAXHandlerPtr *sax;
28533
if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
28537
xmlSchemaPostRun(plug->ctxt);
28538
/* restore the data */
28539
sax = plug->user_sax_ptr;
28540
*sax = plug->user_sax;
28541
if (plug->user_sax != NULL) {
28542
user_data = plug->user_data_ptr;
28543
*user_data = plug->user_data;
28546
/* free and return */
28552
* xmlSchemaValidateStream:
28553
* @ctxt: a schema validation context
28554
* @input: the input to use for reading the data
28555
* @enc: an optional encoding information
28556
* @sax: a SAX handler for the resulting events
28557
* @user_data: the context to provide to the SAX handler.
28559
* Validate an input based on a flow of SAX event from the parser
28560
* and forward the events to the @sax handler with the provided @user_data
28561
* the user provided @sax handler must be a SAX2 one.
28563
* Returns 0 if the document is schemas valid, a positive error code
28564
* number otherwise and -1 in case of internal or API error.
28567
xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
28568
xmlParserInputBufferPtr input, xmlCharEncoding enc,
28569
xmlSAXHandlerPtr sax, void *user_data)
28571
xmlSchemaSAXPlugPtr plug = NULL;
28572
xmlSAXHandlerPtr old_sax = NULL;
28573
xmlParserCtxtPtr pctxt = NULL;
28574
xmlParserInputPtr inputStream = NULL;
28577
if ((ctxt == NULL) || (input == NULL))
28581
* prepare the parser
28583
pctxt = xmlNewParserCtxt();
28586
old_sax = pctxt->sax;
28588
pctxt->userData = user_data;
28591
xmlCtxtUseOptions(pctxt, options);
28593
pctxt->linenumbers = 1;
28595
inputStream = xmlNewIOInputStream(pctxt, input, enc);;
28596
if (inputStream == NULL) {
28600
inputPush(pctxt, inputStream);
28601
ctxt->parserCtxt = pctxt;
28602
ctxt->input = input;
28605
* Plug the validation and launch the parsing
28607
plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
28608
if (plug == NULL) {
28612
ctxt->input = input;
28614
ctxt->sax = pctxt->sax;
28615
ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28616
ret = xmlSchemaVStart(ctxt);
28618
if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
28619
ret = ctxt->parserCtxt->errNo;
28625
ctxt->parserCtxt = NULL;
28627
ctxt->input = NULL;
28628
if (plug != NULL) {
28629
xmlSchemaSAXUnplug(plug);
28632
if (pctxt != NULL) {
28633
pctxt->sax = old_sax;
28634
xmlFreeParserCtxt(pctxt);
28640
* xmlSchemaValidateFile:
28641
* @ctxt: a schema validation context
28642
* @filename: the URI of the instance
28643
* @options: a future set of options, currently unused
28645
* Do a schemas validation of the given resource, it will use the
28646
* SAX streamable validation internally.
28648
* Returns 0 if the document is valid, a positive error code
28649
* number otherwise and -1 in case of an internal or API error.
28652
xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
28653
const char * filename,
28654
int options ATTRIBUTE_UNUSED)
28657
xmlParserInputBufferPtr input;
28659
if ((ctxt == NULL) || (filename == NULL))
28662
input = xmlParserInputBufferCreateFilename(filename,
28663
XML_CHAR_ENCODING_NONE);
28666
ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
28671
#define bottom_xmlschemas
28672
#include "elfgcchack.h"
28673
#endif /* LIBXML_SCHEMAS_ENABLED */