XML C parser available under the MIT license. http://xmlsoft.org/

Dependents:   libiio

Committer:
pcercuei
Date:
Thu Aug 25 10:07:34 2016 +0000
Revision:
1:26f20484cbdc
Parent:
0:03b5121a232e
Add config.h and dummy.c containing empty functions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pcercuei 0:03b5121a232e 1 /*
pcercuei 0:03b5121a232e 2 * schemas.c : implementation of the XML Schema handling and
pcercuei 0:03b5121a232e 3 * schema validity checking
pcercuei 0:03b5121a232e 4 *
pcercuei 0:03b5121a232e 5 * See Copyright for the status of this software.
pcercuei 0:03b5121a232e 6 *
pcercuei 0:03b5121a232e 7 * Daniel Veillard <veillard@redhat.com>
pcercuei 0:03b5121a232e 8 */
pcercuei 0:03b5121a232e 9
pcercuei 0:03b5121a232e 10 /*
pcercuei 0:03b5121a232e 11 * TODO:
pcercuei 0:03b5121a232e 12 * - when types are redefined in includes, check that all
pcercuei 0:03b5121a232e 13 * types in the redef list are equal
pcercuei 0:03b5121a232e 14 * -> need a type equality operation.
pcercuei 0:03b5121a232e 15 * - if we don't intend to use the schema for schemas, we
pcercuei 0:03b5121a232e 16 * need to validate all schema attributes (ref, type, name)
pcercuei 0:03b5121a232e 17 * against their types.
pcercuei 0:03b5121a232e 18 * - Eliminate item creation for: ??
pcercuei 0:03b5121a232e 19 *
pcercuei 0:03b5121a232e 20 * URGENT TODO:
pcercuei 0:03b5121a232e 21 * - For xsi-driven schema acquisition, augment the IDCs after every
pcercuei 0:03b5121a232e 22 * acquisition episode (xmlSchemaAugmentIDC).
pcercuei 0:03b5121a232e 23 *
pcercuei 0:03b5121a232e 24 * NOTES:
pcercuei 0:03b5121a232e 25 * - Elimated item creation for: <restriction>, <extension>,
pcercuei 0:03b5121a232e 26 * <simpleContent>, <complexContent>, <list>, <union>
pcercuei 0:03b5121a232e 27 *
pcercuei 0:03b5121a232e 28 * PROBLEMS:
pcercuei 0:03b5121a232e 29 * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
pcercuei 0:03b5121a232e 30 * IDC XPath expression and chameleon includes: the targetNamespace is changed, so
pcercuei 0:03b5121a232e 31 * XPath will have trouble to resolve to this namespace, since not known.
pcercuei 0:03b5121a232e 32 *
pcercuei 0:03b5121a232e 33 *
pcercuei 0:03b5121a232e 34 * CONSTRAINTS:
pcercuei 0:03b5121a232e 35 *
pcercuei 0:03b5121a232e 36 * Schema Component Constraint:
pcercuei 0:03b5121a232e 37 * All Group Limited (cos-all-limited)
pcercuei 0:03b5121a232e 38 * Status: complete
pcercuei 0:03b5121a232e 39 * (1.2)
pcercuei 0:03b5121a232e 40 * In xmlSchemaGroupDefReferenceTermFixup() and
pcercuei 0:03b5121a232e 41 * (2)
pcercuei 0:03b5121a232e 42 * In xmlSchemaParseModelGroup()
pcercuei 0:03b5121a232e 43 * TODO: Actually this should go to component-level checks,
pcercuei 0:03b5121a232e 44 * but is done here due to performance. Move it to an other layer
pcercuei 0:03b5121a232e 45 * is schema construction via an API is implemented.
pcercuei 0:03b5121a232e 46 */
pcercuei 0:03b5121a232e 47 #define IN_LIBXML
pcercuei 0:03b5121a232e 48 #include "libxml.h"
pcercuei 0:03b5121a232e 49
pcercuei 0:03b5121a232e 50 #ifdef LIBXML_SCHEMAS_ENABLED
pcercuei 0:03b5121a232e 51
pcercuei 0:03b5121a232e 52 #include <string.h>
pcercuei 0:03b5121a232e 53 #include <libxml/xmlmemory.h>
pcercuei 0:03b5121a232e 54 #include <libxml/parser.h>
pcercuei 0:03b5121a232e 55 #include <libxml/parserInternals.h>
pcercuei 0:03b5121a232e 56 #include <libxml/hash.h>
pcercuei 0:03b5121a232e 57 #include <libxml/uri.h>
pcercuei 0:03b5121a232e 58 #include <libxml/xmlschemas.h>
pcercuei 0:03b5121a232e 59 #include <libxml/schemasInternals.h>
pcercuei 0:03b5121a232e 60 #include <libxml/xmlschemastypes.h>
pcercuei 0:03b5121a232e 61 #include <libxml/xmlautomata.h>
pcercuei 0:03b5121a232e 62 #include <libxml/xmlregexp.h>
pcercuei 0:03b5121a232e 63 #include <libxml/dict.h>
pcercuei 0:03b5121a232e 64 #include <libxml/encoding.h>
pcercuei 0:03b5121a232e 65 #include <libxml/xmlIO.h>
pcercuei 0:03b5121a232e 66 #ifdef LIBXML_PATTERN_ENABLED
pcercuei 0:03b5121a232e 67 #include <libxml/pattern.h>
pcercuei 0:03b5121a232e 68 #endif
pcercuei 0:03b5121a232e 69 #ifdef LIBXML_READER_ENABLED
pcercuei 0:03b5121a232e 70 #include <libxml/xmlreader.h>
pcercuei 0:03b5121a232e 71 #endif
pcercuei 0:03b5121a232e 72
pcercuei 0:03b5121a232e 73 /* #define DEBUG 1 */
pcercuei 0:03b5121a232e 74
pcercuei 0:03b5121a232e 75 /* #define DEBUG_CONTENT 1 */
pcercuei 0:03b5121a232e 76
pcercuei 0:03b5121a232e 77 /* #define DEBUG_TYPE 1 */
pcercuei 0:03b5121a232e 78
pcercuei 0:03b5121a232e 79 /* #define DEBUG_CONTENT_REGEXP 1 */
pcercuei 0:03b5121a232e 80
pcercuei 0:03b5121a232e 81 /* #define DEBUG_AUTOMATA 1 */
pcercuei 0:03b5121a232e 82
pcercuei 0:03b5121a232e 83 /* #define DEBUG_IDC */
pcercuei 0:03b5121a232e 84
pcercuei 0:03b5121a232e 85 /* #define DEBUG_IDC_NODE_TABLE */
pcercuei 0:03b5121a232e 86
pcercuei 0:03b5121a232e 87 /* #define WXS_ELEM_DECL_CONS_ENABLED */
pcercuei 0:03b5121a232e 88
pcercuei 0:03b5121a232e 89 #ifdef DEBUG_IDC
pcercuei 0:03b5121a232e 90 #ifndef DEBUG_IDC_NODE_TABLE
pcercuei 0:03b5121a232e 91 #define DEBUG_IDC_NODE_TABLE
pcercuei 0:03b5121a232e 92 #endif
pcercuei 0:03b5121a232e 93 #endif
pcercuei 0:03b5121a232e 94
pcercuei 0:03b5121a232e 95 /* #define ENABLE_PARTICLE_RESTRICTION 1 */
pcercuei 0:03b5121a232e 96
pcercuei 0:03b5121a232e 97 #define ENABLE_REDEFINE
pcercuei 0:03b5121a232e 98
pcercuei 0:03b5121a232e 99 /* #define ENABLE_NAMED_LOCALS */
pcercuei 0:03b5121a232e 100
pcercuei 0:03b5121a232e 101 /* #define ENABLE_IDC_NODE_TABLES_TEST */
pcercuei 0:03b5121a232e 102
pcercuei 0:03b5121a232e 103 #define DUMP_CONTENT_MODEL
pcercuei 0:03b5121a232e 104
pcercuei 0:03b5121a232e 105 #ifdef LIBXML_READER_ENABLED
pcercuei 0:03b5121a232e 106 /* #define XML_SCHEMA_READER_ENABLED */
pcercuei 0:03b5121a232e 107 #endif
pcercuei 0:03b5121a232e 108
pcercuei 0:03b5121a232e 109 #define UNBOUNDED (1 << 30)
pcercuei 0:03b5121a232e 110 #define TODO \
pcercuei 0:03b5121a232e 111 xmlGenericError(xmlGenericErrorContext, \
pcercuei 0:03b5121a232e 112 "Unimplemented block at %s:%d\n", \
pcercuei 0:03b5121a232e 113 __FILE__, __LINE__);
pcercuei 0:03b5121a232e 114
pcercuei 0:03b5121a232e 115 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
pcercuei 0:03b5121a232e 116
pcercuei 0:03b5121a232e 117 /*
pcercuei 0:03b5121a232e 118 * The XML Schemas namespaces
pcercuei 0:03b5121a232e 119 */
pcercuei 0:03b5121a232e 120 static const xmlChar *xmlSchemaNs = (const xmlChar *)
pcercuei 0:03b5121a232e 121 "http://www.w3.org/2001/XMLSchema";
pcercuei 0:03b5121a232e 122
pcercuei 0:03b5121a232e 123 static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
pcercuei 0:03b5121a232e 124 "http://www.w3.org/2001/XMLSchema-instance";
pcercuei 0:03b5121a232e 125
pcercuei 0:03b5121a232e 126 static const xmlChar *xmlNamespaceNs = (const xmlChar *)
pcercuei 0:03b5121a232e 127 "http://www.w3.org/2000/xmlns/";
pcercuei 0:03b5121a232e 128
pcercuei 0:03b5121a232e 129 /*
pcercuei 0:03b5121a232e 130 * Come casting macros.
pcercuei 0:03b5121a232e 131 */
pcercuei 0:03b5121a232e 132 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
pcercuei 0:03b5121a232e 133 #define PCTXT_CAST (xmlSchemaParserCtxtPtr)
pcercuei 0:03b5121a232e 134 #define VCTXT_CAST (xmlSchemaValidCtxtPtr)
pcercuei 0:03b5121a232e 135 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
pcercuei 0:03b5121a232e 136 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
pcercuei 0:03b5121a232e 137 #define WXS_PTC_CAST (xmlSchemaParticlePtr)
pcercuei 0:03b5121a232e 138 #define WXS_TYPE_CAST (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 139 #define WXS_ELEM_CAST (xmlSchemaElementPtr)
pcercuei 0:03b5121a232e 140 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
pcercuei 0:03b5121a232e 141 #define WXS_ATTR_CAST (xmlSchemaAttributePtr)
pcercuei 0:03b5121a232e 142 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
pcercuei 0:03b5121a232e 143 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
pcercuei 0:03b5121a232e 144 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
pcercuei 0:03b5121a232e 145 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
pcercuei 0:03b5121a232e 146 #define WXS_IDC_CAST (xmlSchemaIDCPtr)
pcercuei 0:03b5121a232e 147 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
pcercuei 0:03b5121a232e 148 #define WXS_LIST_CAST (xmlSchemaItemListPtr)
pcercuei 0:03b5121a232e 149
pcercuei 0:03b5121a232e 150 /*
pcercuei 0:03b5121a232e 151 * Macros to query common properties of components.
pcercuei 0:03b5121a232e 152 */
pcercuei 0:03b5121a232e 153 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
pcercuei 0:03b5121a232e 154
pcercuei 0:03b5121a232e 155 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
pcercuei 0:03b5121a232e 156 /*
pcercuei 0:03b5121a232e 157 * Macros for element declarations.
pcercuei 0:03b5121a232e 158 */
pcercuei 0:03b5121a232e 159 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
pcercuei 0:03b5121a232e 160
pcercuei 0:03b5121a232e 161 #define WXS_SUBST_HEAD(item) (item)->refDecl
pcercuei 0:03b5121a232e 162 /*
pcercuei 0:03b5121a232e 163 * Macros for attribute declarations.
pcercuei 0:03b5121a232e 164 */
pcercuei 0:03b5121a232e 165 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
pcercuei 0:03b5121a232e 166 /*
pcercuei 0:03b5121a232e 167 * Macros for attribute uses.
pcercuei 0:03b5121a232e 168 */
pcercuei 0:03b5121a232e 169 #define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl
pcercuei 0:03b5121a232e 170
pcercuei 0:03b5121a232e 171 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
pcercuei 0:03b5121a232e 172
pcercuei 0:03b5121a232e 173 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
pcercuei 0:03b5121a232e 174
pcercuei 0:03b5121a232e 175 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
pcercuei 0:03b5121a232e 176 /*
pcercuei 0:03b5121a232e 177 * Macros for attribute groups.
pcercuei 0:03b5121a232e 178 */
pcercuei 0:03b5121a232e 179 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
pcercuei 0:03b5121a232e 180 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
pcercuei 0:03b5121a232e 181 /*
pcercuei 0:03b5121a232e 182 * Macros for particles.
pcercuei 0:03b5121a232e 183 */
pcercuei 0:03b5121a232e 184 #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
pcercuei 0:03b5121a232e 185
pcercuei 0:03b5121a232e 186 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
pcercuei 0:03b5121a232e 187
pcercuei 0:03b5121a232e 188 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
pcercuei 0:03b5121a232e 189
pcercuei 0:03b5121a232e 190 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
pcercuei 0:03b5121a232e 191 /*
pcercuei 0:03b5121a232e 192 * Macros for model groups definitions.
pcercuei 0:03b5121a232e 193 */
pcercuei 0:03b5121a232e 194 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
pcercuei 0:03b5121a232e 195 /*
pcercuei 0:03b5121a232e 196 * Macros for model groups.
pcercuei 0:03b5121a232e 197 */
pcercuei 0:03b5121a232e 198 #define WXS_IS_MODEL_GROUP(i) \
pcercuei 0:03b5121a232e 199 (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
pcercuei 0:03b5121a232e 200 ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
pcercuei 0:03b5121a232e 201 ((i)->type == XML_SCHEMA_TYPE_ALL))
pcercuei 0:03b5121a232e 202
pcercuei 0:03b5121a232e 203 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
pcercuei 0:03b5121a232e 204 /*
pcercuei 0:03b5121a232e 205 * Macros for schema buckets.
pcercuei 0:03b5121a232e 206 */
pcercuei 0:03b5121a232e 207 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
pcercuei 0:03b5121a232e 208 ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
pcercuei 0:03b5121a232e 209
pcercuei 0:03b5121a232e 210 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
pcercuei 0:03b5121a232e 211 ((t) == XML_SCHEMA_SCHEMA_IMPORT))
pcercuei 0:03b5121a232e 212
pcercuei 0:03b5121a232e 213 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
pcercuei 0:03b5121a232e 214
pcercuei 0:03b5121a232e 215 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
pcercuei 0:03b5121a232e 216 /*
pcercuei 0:03b5121a232e 217 * Macros for complex/simple types.
pcercuei 0:03b5121a232e 218 */
pcercuei 0:03b5121a232e 219 #define WXS_IS_ANYTYPE(i) \
pcercuei 0:03b5121a232e 220 (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
pcercuei 0:03b5121a232e 221 ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
pcercuei 0:03b5121a232e 222
pcercuei 0:03b5121a232e 223 #define WXS_IS_COMPLEX(i) \
pcercuei 0:03b5121a232e 224 (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
pcercuei 0:03b5121a232e 225 ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
pcercuei 0:03b5121a232e 226
pcercuei 0:03b5121a232e 227 #define WXS_IS_SIMPLE(item) \
pcercuei 0:03b5121a232e 228 ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
pcercuei 0:03b5121a232e 229 ((item->type == XML_SCHEMA_TYPE_BASIC) && \
pcercuei 0:03b5121a232e 230 (item->builtInType != XML_SCHEMAS_ANYTYPE)))
pcercuei 0:03b5121a232e 231
pcercuei 0:03b5121a232e 232 #define WXS_IS_ANY_SIMPLE_TYPE(i) \
pcercuei 0:03b5121a232e 233 (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
pcercuei 0:03b5121a232e 234 ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
pcercuei 0:03b5121a232e 235
pcercuei 0:03b5121a232e 236 #define WXS_IS_RESTRICTION(t) \
pcercuei 0:03b5121a232e 237 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
pcercuei 0:03b5121a232e 238
pcercuei 0:03b5121a232e 239 #define WXS_IS_EXTENSION(t) \
pcercuei 0:03b5121a232e 240 ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
pcercuei 0:03b5121a232e 241
pcercuei 0:03b5121a232e 242 #define WXS_IS_TYPE_NOT_FIXED(i) \
pcercuei 0:03b5121a232e 243 (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
pcercuei 0:03b5121a232e 244 (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
pcercuei 0:03b5121a232e 245
pcercuei 0:03b5121a232e 246 #define WXS_IS_TYPE_NOT_FIXED_1(item) \
pcercuei 0:03b5121a232e 247 (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
pcercuei 0:03b5121a232e 248 (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
pcercuei 0:03b5121a232e 249
pcercuei 0:03b5121a232e 250 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
pcercuei 0:03b5121a232e 251
pcercuei 0:03b5121a232e 252 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
pcercuei 0:03b5121a232e 253 /*
pcercuei 0:03b5121a232e 254 * Macros for exclusively for complex types.
pcercuei 0:03b5121a232e 255 */
pcercuei 0:03b5121a232e 256 #define WXS_HAS_COMPLEX_CONTENT(item) \
pcercuei 0:03b5121a232e 257 ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
pcercuei 0:03b5121a232e 258 (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
pcercuei 0:03b5121a232e 259 (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
pcercuei 0:03b5121a232e 260
pcercuei 0:03b5121a232e 261 #define WXS_HAS_SIMPLE_CONTENT(item) \
pcercuei 0:03b5121a232e 262 ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
pcercuei 0:03b5121a232e 263 (item->contentType == XML_SCHEMA_CONTENT_BASIC))
pcercuei 0:03b5121a232e 264
pcercuei 0:03b5121a232e 265 #define WXS_HAS_MIXED_CONTENT(item) \
pcercuei 0:03b5121a232e 266 (item->contentType == XML_SCHEMA_CONTENT_MIXED)
pcercuei 0:03b5121a232e 267
pcercuei 0:03b5121a232e 268 #define WXS_EMPTIABLE(t) \
pcercuei 0:03b5121a232e 269 (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
pcercuei 0:03b5121a232e 270
pcercuei 0:03b5121a232e 271 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
pcercuei 0:03b5121a232e 272
pcercuei 0:03b5121a232e 273 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
pcercuei 0:03b5121a232e 274
pcercuei 0:03b5121a232e 275 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
pcercuei 0:03b5121a232e 276 /*
pcercuei 0:03b5121a232e 277 * Macros for exclusively for simple types.
pcercuei 0:03b5121a232e 278 */
pcercuei 0:03b5121a232e 279 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
pcercuei 0:03b5121a232e 280
pcercuei 0:03b5121a232e 281 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
pcercuei 0:03b5121a232e 282
pcercuei 0:03b5121a232e 283 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
pcercuei 0:03b5121a232e 284
pcercuei 0:03b5121a232e 285 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
pcercuei 0:03b5121a232e 286 /*
pcercuei 0:03b5121a232e 287 * Misc parser context macros.
pcercuei 0:03b5121a232e 288 */
pcercuei 0:03b5121a232e 289 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
pcercuei 0:03b5121a232e 290
pcercuei 0:03b5121a232e 291 #define WXS_HAS_BUCKETS(ctx) \
pcercuei 0:03b5121a232e 292 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
pcercuei 0:03b5121a232e 293 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
pcercuei 0:03b5121a232e 294
pcercuei 0:03b5121a232e 295 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
pcercuei 0:03b5121a232e 296
pcercuei 0:03b5121a232e 297 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
pcercuei 0:03b5121a232e 298
pcercuei 0:03b5121a232e 299 #define WXS_SCHEMA(ctx) (ctx)->schema
pcercuei 0:03b5121a232e 300
pcercuei 0:03b5121a232e 301 #define WXS_ADD_LOCAL(ctx, item) \
pcercuei 0:03b5121a232e 302 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
pcercuei 0:03b5121a232e 303
pcercuei 0:03b5121a232e 304 #define WXS_ADD_GLOBAL(ctx, item) \
pcercuei 0:03b5121a232e 305 xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
pcercuei 0:03b5121a232e 306
pcercuei 0:03b5121a232e 307 #define WXS_ADD_PENDING(ctx, item) \
pcercuei 0:03b5121a232e 308 xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
pcercuei 0:03b5121a232e 309 /*
pcercuei 0:03b5121a232e 310 * xmlSchemaItemList macros.
pcercuei 0:03b5121a232e 311 */
pcercuei 0:03b5121a232e 312 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
pcercuei 0:03b5121a232e 313 /*
pcercuei 0:03b5121a232e 314 * Misc macros.
pcercuei 0:03b5121a232e 315 */
pcercuei 0:03b5121a232e 316 #define IS_SCHEMA(node, type) \
pcercuei 0:03b5121a232e 317 ((node != NULL) && (node->ns != NULL) && \
pcercuei 0:03b5121a232e 318 (xmlStrEqual(node->name, (const xmlChar *) type)) && \
pcercuei 0:03b5121a232e 319 (xmlStrEqual(node->ns->href, xmlSchemaNs)))
pcercuei 0:03b5121a232e 320
pcercuei 0:03b5121a232e 321 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
pcercuei 0:03b5121a232e 322
pcercuei 0:03b5121a232e 323 /*
pcercuei 0:03b5121a232e 324 * Since we put the default/fixed values into the dict, we can
pcercuei 0:03b5121a232e 325 * use pointer comparison for those values.
pcercuei 0:03b5121a232e 326 * REMOVED: (xmlStrEqual((v1), (v2)))
pcercuei 0:03b5121a232e 327 */
pcercuei 0:03b5121a232e 328 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
pcercuei 0:03b5121a232e 329
pcercuei 0:03b5121a232e 330 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
pcercuei 0:03b5121a232e 331
pcercuei 0:03b5121a232e 332 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
pcercuei 0:03b5121a232e 333
pcercuei 0:03b5121a232e 334 #define HFAILURE if (res == -1) goto exit_failure;
pcercuei 0:03b5121a232e 335
pcercuei 0:03b5121a232e 336 #define HERROR if (res != 0) goto exit_error;
pcercuei 0:03b5121a232e 337
pcercuei 0:03b5121a232e 338 #define HSTOP(ctx) if ((ctx)->stop) goto exit;
pcercuei 0:03b5121a232e 339 /*
pcercuei 0:03b5121a232e 340 * Some flags used for various schema constraints.
pcercuei 0:03b5121a232e 341 */
pcercuei 0:03b5121a232e 342 #define SUBSET_RESTRICTION 1<<0
pcercuei 0:03b5121a232e 343 #define SUBSET_EXTENSION 1<<1
pcercuei 0:03b5121a232e 344 #define SUBSET_SUBSTITUTION 1<<2
pcercuei 0:03b5121a232e 345 #define SUBSET_LIST 1<<3
pcercuei 0:03b5121a232e 346 #define SUBSET_UNION 1<<4
pcercuei 0:03b5121a232e 347
pcercuei 0:03b5121a232e 348 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
pcercuei 0:03b5121a232e 349 typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
pcercuei 0:03b5121a232e 350
pcercuei 0:03b5121a232e 351 typedef struct _xmlSchemaItemList xmlSchemaItemList;
pcercuei 0:03b5121a232e 352 typedef xmlSchemaItemList *xmlSchemaItemListPtr;
pcercuei 0:03b5121a232e 353 struct _xmlSchemaItemList {
pcercuei 0:03b5121a232e 354 void **items; /* used for dynamic addition of schemata */
pcercuei 0:03b5121a232e 355 int nbItems; /* used for dynamic addition of schemata */
pcercuei 0:03b5121a232e 356 int sizeItems; /* used for dynamic addition of schemata */
pcercuei 0:03b5121a232e 357 };
pcercuei 0:03b5121a232e 358
pcercuei 0:03b5121a232e 359 #define XML_SCHEMA_CTXT_PARSER 1
pcercuei 0:03b5121a232e 360 #define XML_SCHEMA_CTXT_VALIDATOR 2
pcercuei 0:03b5121a232e 361
pcercuei 0:03b5121a232e 362 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
pcercuei 0:03b5121a232e 363 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
pcercuei 0:03b5121a232e 364 struct _xmlSchemaAbstractCtxt {
pcercuei 0:03b5121a232e 365 int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
pcercuei 0:03b5121a232e 366 };
pcercuei 0:03b5121a232e 367
pcercuei 0:03b5121a232e 368 typedef struct _xmlSchemaBucket xmlSchemaBucket;
pcercuei 0:03b5121a232e 369 typedef xmlSchemaBucket *xmlSchemaBucketPtr;
pcercuei 0:03b5121a232e 370
pcercuei 0:03b5121a232e 371 #define XML_SCHEMA_SCHEMA_MAIN 0
pcercuei 0:03b5121a232e 372 #define XML_SCHEMA_SCHEMA_IMPORT 1
pcercuei 0:03b5121a232e 373 #define XML_SCHEMA_SCHEMA_INCLUDE 2
pcercuei 0:03b5121a232e 374 #define XML_SCHEMA_SCHEMA_REDEFINE 3
pcercuei 0:03b5121a232e 375
pcercuei 0:03b5121a232e 376 /**
pcercuei 0:03b5121a232e 377 * xmlSchemaSchemaRelation:
pcercuei 0:03b5121a232e 378 *
pcercuei 0:03b5121a232e 379 * Used to create a graph of schema relationships.
pcercuei 0:03b5121a232e 380 */
pcercuei 0:03b5121a232e 381 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
pcercuei 0:03b5121a232e 382 typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
pcercuei 0:03b5121a232e 383 struct _xmlSchemaSchemaRelation {
pcercuei 0:03b5121a232e 384 xmlSchemaSchemaRelationPtr next;
pcercuei 0:03b5121a232e 385 int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
pcercuei 0:03b5121a232e 386 const xmlChar *importNamespace;
pcercuei 0:03b5121a232e 387 xmlSchemaBucketPtr bucket;
pcercuei 0:03b5121a232e 388 };
pcercuei 0:03b5121a232e 389
pcercuei 0:03b5121a232e 390 #define XML_SCHEMA_BUCKET_MARKED 1<<0
pcercuei 0:03b5121a232e 391 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
pcercuei 0:03b5121a232e 392
pcercuei 0:03b5121a232e 393 struct _xmlSchemaBucket {
pcercuei 0:03b5121a232e 394 int type;
pcercuei 0:03b5121a232e 395 int flags;
pcercuei 0:03b5121a232e 396 const xmlChar *schemaLocation;
pcercuei 0:03b5121a232e 397 const xmlChar *origTargetNamespace;
pcercuei 0:03b5121a232e 398 const xmlChar *targetNamespace;
pcercuei 0:03b5121a232e 399 xmlDocPtr doc;
pcercuei 0:03b5121a232e 400 xmlSchemaSchemaRelationPtr relations;
pcercuei 0:03b5121a232e 401 int located;
pcercuei 0:03b5121a232e 402 int parsed;
pcercuei 0:03b5121a232e 403 int imported;
pcercuei 0:03b5121a232e 404 int preserveDoc;
pcercuei 0:03b5121a232e 405 xmlSchemaItemListPtr globals; /* Global components. */
pcercuei 0:03b5121a232e 406 xmlSchemaItemListPtr locals; /* Local components. */
pcercuei 0:03b5121a232e 407 };
pcercuei 0:03b5121a232e 408
pcercuei 0:03b5121a232e 409 /**
pcercuei 0:03b5121a232e 410 * xmlSchemaImport:
pcercuei 0:03b5121a232e 411 * (extends xmlSchemaBucket)
pcercuei 0:03b5121a232e 412 *
pcercuei 0:03b5121a232e 413 * Reflects a schema. Holds some information
pcercuei 0:03b5121a232e 414 * about the schema and its toplevel components. Duplicate
pcercuei 0:03b5121a232e 415 * toplevel components are not checked at this level.
pcercuei 0:03b5121a232e 416 */
pcercuei 0:03b5121a232e 417 typedef struct _xmlSchemaImport xmlSchemaImport;
pcercuei 0:03b5121a232e 418 typedef xmlSchemaImport *xmlSchemaImportPtr;
pcercuei 0:03b5121a232e 419 struct _xmlSchemaImport {
pcercuei 0:03b5121a232e 420 int type; /* Main OR import OR include. */
pcercuei 0:03b5121a232e 421 int flags;
pcercuei 0:03b5121a232e 422 const xmlChar *schemaLocation; /* The URI of the schema document. */
pcercuei 0:03b5121a232e 423 /* For chameleon includes, @origTargetNamespace will be NULL */
pcercuei 0:03b5121a232e 424 const xmlChar *origTargetNamespace;
pcercuei 0:03b5121a232e 425 /*
pcercuei 0:03b5121a232e 426 * For chameleon includes, @targetNamespace will be the
pcercuei 0:03b5121a232e 427 * targetNamespace of the including schema.
pcercuei 0:03b5121a232e 428 */
pcercuei 0:03b5121a232e 429 const xmlChar *targetNamespace;
pcercuei 0:03b5121a232e 430 xmlDocPtr doc; /* The schema node-tree. */
pcercuei 0:03b5121a232e 431 /* @relations will hold any included/imported/redefined schemas. */
pcercuei 0:03b5121a232e 432 xmlSchemaSchemaRelationPtr relations;
pcercuei 0:03b5121a232e 433 int located;
pcercuei 0:03b5121a232e 434 int parsed;
pcercuei 0:03b5121a232e 435 int imported;
pcercuei 0:03b5121a232e 436 int preserveDoc;
pcercuei 0:03b5121a232e 437 xmlSchemaItemListPtr globals;
pcercuei 0:03b5121a232e 438 xmlSchemaItemListPtr locals;
pcercuei 0:03b5121a232e 439 /* The imported schema. */
pcercuei 0:03b5121a232e 440 xmlSchemaPtr schema;
pcercuei 0:03b5121a232e 441 };
pcercuei 0:03b5121a232e 442
pcercuei 0:03b5121a232e 443 /*
pcercuei 0:03b5121a232e 444 * (extends xmlSchemaBucket)
pcercuei 0:03b5121a232e 445 */
pcercuei 0:03b5121a232e 446 typedef struct _xmlSchemaInclude xmlSchemaInclude;
pcercuei 0:03b5121a232e 447 typedef xmlSchemaInclude *xmlSchemaIncludePtr;
pcercuei 0:03b5121a232e 448 struct _xmlSchemaInclude {
pcercuei 0:03b5121a232e 449 int type;
pcercuei 0:03b5121a232e 450 int flags;
pcercuei 0:03b5121a232e 451 const xmlChar *schemaLocation;
pcercuei 0:03b5121a232e 452 const xmlChar *origTargetNamespace;
pcercuei 0:03b5121a232e 453 const xmlChar *targetNamespace;
pcercuei 0:03b5121a232e 454 xmlDocPtr doc;
pcercuei 0:03b5121a232e 455 xmlSchemaSchemaRelationPtr relations;
pcercuei 0:03b5121a232e 456 int located;
pcercuei 0:03b5121a232e 457 int parsed;
pcercuei 0:03b5121a232e 458 int imported;
pcercuei 0:03b5121a232e 459 int preserveDoc;
pcercuei 0:03b5121a232e 460 xmlSchemaItemListPtr globals; /* Global components. */
pcercuei 0:03b5121a232e 461 xmlSchemaItemListPtr locals; /* Local components. */
pcercuei 0:03b5121a232e 462
pcercuei 0:03b5121a232e 463 /* The owning main or import schema bucket. */
pcercuei 0:03b5121a232e 464 xmlSchemaImportPtr ownerImport;
pcercuei 0:03b5121a232e 465 };
pcercuei 0:03b5121a232e 466
pcercuei 0:03b5121a232e 467 /**
pcercuei 0:03b5121a232e 468 * xmlSchemaBasicItem:
pcercuei 0:03b5121a232e 469 *
pcercuei 0:03b5121a232e 470 * The abstract base type for schema components.
pcercuei 0:03b5121a232e 471 */
pcercuei 0:03b5121a232e 472 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
pcercuei 0:03b5121a232e 473 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
pcercuei 0:03b5121a232e 474 struct _xmlSchemaBasicItem {
pcercuei 0:03b5121a232e 475 xmlSchemaTypeType type;
pcercuei 0:03b5121a232e 476 };
pcercuei 0:03b5121a232e 477
pcercuei 0:03b5121a232e 478 /**
pcercuei 0:03b5121a232e 479 * xmlSchemaAnnotItem:
pcercuei 0:03b5121a232e 480 *
pcercuei 0:03b5121a232e 481 * The abstract base type for annotated schema components.
pcercuei 0:03b5121a232e 482 * (Extends xmlSchemaBasicItem)
pcercuei 0:03b5121a232e 483 */
pcercuei 0:03b5121a232e 484 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
pcercuei 0:03b5121a232e 485 typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
pcercuei 0:03b5121a232e 486 struct _xmlSchemaAnnotItem {
pcercuei 0:03b5121a232e 487 xmlSchemaTypeType type;
pcercuei 0:03b5121a232e 488 xmlSchemaAnnotPtr annot;
pcercuei 0:03b5121a232e 489 };
pcercuei 0:03b5121a232e 490
pcercuei 0:03b5121a232e 491 /**
pcercuei 0:03b5121a232e 492 * xmlSchemaTreeItem:
pcercuei 0:03b5121a232e 493 *
pcercuei 0:03b5121a232e 494 * The abstract base type for tree-like structured schema components.
pcercuei 0:03b5121a232e 495 * (Extends xmlSchemaAnnotItem)
pcercuei 0:03b5121a232e 496 */
pcercuei 0:03b5121a232e 497 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
pcercuei 0:03b5121a232e 498 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
pcercuei 0:03b5121a232e 499 struct _xmlSchemaTreeItem {
pcercuei 0:03b5121a232e 500 xmlSchemaTypeType type;
pcercuei 0:03b5121a232e 501 xmlSchemaAnnotPtr annot;
pcercuei 0:03b5121a232e 502 xmlSchemaTreeItemPtr next;
pcercuei 0:03b5121a232e 503 xmlSchemaTreeItemPtr children;
pcercuei 0:03b5121a232e 504 };
pcercuei 0:03b5121a232e 505
pcercuei 0:03b5121a232e 506
pcercuei 0:03b5121a232e 507 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
pcercuei 0:03b5121a232e 508 /**
pcercuei 0:03b5121a232e 509 * xmlSchemaAttributeUsePtr:
pcercuei 0:03b5121a232e 510 *
pcercuei 0:03b5121a232e 511 * The abstract base type for tree-like structured schema components.
pcercuei 0:03b5121a232e 512 * (Extends xmlSchemaTreeItem)
pcercuei 0:03b5121a232e 513 */
pcercuei 0:03b5121a232e 514 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
pcercuei 0:03b5121a232e 515 typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
pcercuei 0:03b5121a232e 516 struct _xmlSchemaAttributeUse {
pcercuei 0:03b5121a232e 517 xmlSchemaTypeType type;
pcercuei 0:03b5121a232e 518 xmlSchemaAnnotPtr annot;
pcercuei 0:03b5121a232e 519 xmlSchemaAttributeUsePtr next; /* The next attr. use. */
pcercuei 0:03b5121a232e 520 /*
pcercuei 0:03b5121a232e 521 * The attr. decl. OR a QName-ref. to an attr. decl. OR
pcercuei 0:03b5121a232e 522 * a QName-ref. to an attribute group definition.
pcercuei 0:03b5121a232e 523 */
pcercuei 0:03b5121a232e 524 xmlSchemaAttributePtr attrDecl;
pcercuei 0:03b5121a232e 525
pcercuei 0:03b5121a232e 526 int flags;
pcercuei 0:03b5121a232e 527 xmlNodePtr node;
pcercuei 0:03b5121a232e 528 int occurs; /* required, optional */
pcercuei 0:03b5121a232e 529 const xmlChar * defValue;
pcercuei 0:03b5121a232e 530 xmlSchemaValPtr defVal;
pcercuei 0:03b5121a232e 531 };
pcercuei 0:03b5121a232e 532
pcercuei 0:03b5121a232e 533 /**
pcercuei 0:03b5121a232e 534 * xmlSchemaAttributeUseProhibPtr:
pcercuei 0:03b5121a232e 535 *
pcercuei 0:03b5121a232e 536 * A helper component to reflect attribute prohibitions.
pcercuei 0:03b5121a232e 537 * (Extends xmlSchemaBasicItem)
pcercuei 0:03b5121a232e 538 */
pcercuei 0:03b5121a232e 539 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
pcercuei 0:03b5121a232e 540 typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
pcercuei 0:03b5121a232e 541 struct _xmlSchemaAttributeUseProhib {
pcercuei 0:03b5121a232e 542 xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
pcercuei 0:03b5121a232e 543 xmlNodePtr node;
pcercuei 0:03b5121a232e 544 const xmlChar *name;
pcercuei 0:03b5121a232e 545 const xmlChar *targetNamespace;
pcercuei 0:03b5121a232e 546 int isRef;
pcercuei 0:03b5121a232e 547 };
pcercuei 0:03b5121a232e 548
pcercuei 0:03b5121a232e 549 /**
pcercuei 0:03b5121a232e 550 * xmlSchemaRedef:
pcercuei 0:03b5121a232e 551 */
pcercuei 0:03b5121a232e 552 typedef struct _xmlSchemaRedef xmlSchemaRedef;
pcercuei 0:03b5121a232e 553 typedef xmlSchemaRedef *xmlSchemaRedefPtr;
pcercuei 0:03b5121a232e 554 struct _xmlSchemaRedef {
pcercuei 0:03b5121a232e 555 xmlSchemaRedefPtr next;
pcercuei 0:03b5121a232e 556 xmlSchemaBasicItemPtr item; /* The redefining component. */
pcercuei 0:03b5121a232e 557 xmlSchemaBasicItemPtr reference; /* The referencing component. */
pcercuei 0:03b5121a232e 558 xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
pcercuei 0:03b5121a232e 559 const xmlChar *refName; /* The name of the to-be-redefined component. */
pcercuei 0:03b5121a232e 560 const xmlChar *refTargetNs; /* The target namespace of the
pcercuei 0:03b5121a232e 561 to-be-redefined comp. */
pcercuei 0:03b5121a232e 562 xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
pcercuei 0:03b5121a232e 563 };
pcercuei 0:03b5121a232e 564
pcercuei 0:03b5121a232e 565 /**
pcercuei 0:03b5121a232e 566 * xmlSchemaConstructionCtxt:
pcercuei 0:03b5121a232e 567 */
pcercuei 0:03b5121a232e 568 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
pcercuei 0:03b5121a232e 569 typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
pcercuei 0:03b5121a232e 570 struct _xmlSchemaConstructionCtxt {
pcercuei 0:03b5121a232e 571 xmlSchemaPtr mainSchema; /* The main schema. */
pcercuei 0:03b5121a232e 572 xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
pcercuei 0:03b5121a232e 573 xmlDictPtr dict;
pcercuei 0:03b5121a232e 574 xmlSchemaItemListPtr buckets; /* List of schema buckets. */
pcercuei 0:03b5121a232e 575 /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
pcercuei 0:03b5121a232e 576 xmlSchemaBucketPtr bucket; /* The current schema bucket */
pcercuei 0:03b5121a232e 577 xmlSchemaItemListPtr pending; /* All Components of all schemas that
pcercuei 0:03b5121a232e 578 need to be fixed. */
pcercuei 0:03b5121a232e 579 xmlHashTablePtr substGroups;
pcercuei 0:03b5121a232e 580 xmlSchemaRedefPtr redefs;
pcercuei 0:03b5121a232e 581 xmlSchemaRedefPtr lastRedef;
pcercuei 0:03b5121a232e 582 };
pcercuei 0:03b5121a232e 583
pcercuei 0:03b5121a232e 584 #define XML_SCHEMAS_PARSE_ERROR 1
pcercuei 0:03b5121a232e 585 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
pcercuei 0:03b5121a232e 586
pcercuei 0:03b5121a232e 587 struct _xmlSchemaParserCtxt {
pcercuei 0:03b5121a232e 588 int type;
pcercuei 0:03b5121a232e 589 void *errCtxt; /* user specific error context */
pcercuei 0:03b5121a232e 590 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
pcercuei 0:03b5121a232e 591 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
pcercuei 0:03b5121a232e 592 int err;
pcercuei 0:03b5121a232e 593 int nberrors;
pcercuei 0:03b5121a232e 594 xmlStructuredErrorFunc serror;
pcercuei 0:03b5121a232e 595
pcercuei 0:03b5121a232e 596 xmlSchemaConstructionCtxtPtr constructor;
pcercuei 0:03b5121a232e 597 int ownsConstructor; /* TODO: Move this to parser *flags*. */
pcercuei 0:03b5121a232e 598
pcercuei 0:03b5121a232e 599 /* xmlSchemaPtr topschema; */
pcercuei 0:03b5121a232e 600 /* xmlHashTablePtr namespaces; */
pcercuei 0:03b5121a232e 601
pcercuei 0:03b5121a232e 602 xmlSchemaPtr schema; /* The main schema in use */
pcercuei 0:03b5121a232e 603 int counter;
pcercuei 0:03b5121a232e 604
pcercuei 0:03b5121a232e 605 const xmlChar *URL;
pcercuei 0:03b5121a232e 606 xmlDocPtr doc;
pcercuei 0:03b5121a232e 607 int preserve; /* Whether the doc should be freed */
pcercuei 0:03b5121a232e 608
pcercuei 0:03b5121a232e 609 const char *buffer;
pcercuei 0:03b5121a232e 610 int size;
pcercuei 0:03b5121a232e 611
pcercuei 0:03b5121a232e 612 /*
pcercuei 0:03b5121a232e 613 * Used to build complex element content models
pcercuei 0:03b5121a232e 614 */
pcercuei 0:03b5121a232e 615 xmlAutomataPtr am;
pcercuei 0:03b5121a232e 616 xmlAutomataStatePtr start;
pcercuei 0:03b5121a232e 617 xmlAutomataStatePtr end;
pcercuei 0:03b5121a232e 618 xmlAutomataStatePtr state;
pcercuei 0:03b5121a232e 619
pcercuei 0:03b5121a232e 620 xmlDictPtr dict; /* dictionnary for interned string names */
pcercuei 0:03b5121a232e 621 xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
pcercuei 0:03b5121a232e 622 int options;
pcercuei 0:03b5121a232e 623 xmlSchemaValidCtxtPtr vctxt;
pcercuei 0:03b5121a232e 624 int isS4S;
pcercuei 0:03b5121a232e 625 int isRedefine;
pcercuei 0:03b5121a232e 626 int xsiAssemble;
pcercuei 0:03b5121a232e 627 int stop; /* If the parser should stop; i.e. a critical error. */
pcercuei 0:03b5121a232e 628 const xmlChar *targetNamespace;
pcercuei 0:03b5121a232e 629 xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
pcercuei 0:03b5121a232e 630
pcercuei 0:03b5121a232e 631 xmlSchemaRedefPtr redef; /* Used for redefinitions. */
pcercuei 0:03b5121a232e 632 int redefCounter; /* Used for redefinitions. */
pcercuei 0:03b5121a232e 633 xmlSchemaItemListPtr attrProhibs;
pcercuei 0:03b5121a232e 634 };
pcercuei 0:03b5121a232e 635
pcercuei 0:03b5121a232e 636 /**
pcercuei 0:03b5121a232e 637 * xmlSchemaQNameRef:
pcercuei 0:03b5121a232e 638 *
pcercuei 0:03b5121a232e 639 * A component reference item (not a schema component)
pcercuei 0:03b5121a232e 640 * (Extends xmlSchemaBasicItem)
pcercuei 0:03b5121a232e 641 */
pcercuei 0:03b5121a232e 642 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
pcercuei 0:03b5121a232e 643 typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
pcercuei 0:03b5121a232e 644 struct _xmlSchemaQNameRef {
pcercuei 0:03b5121a232e 645 xmlSchemaTypeType type;
pcercuei 0:03b5121a232e 646 xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
pcercuei 0:03b5121a232e 647 xmlSchemaTypeType itemType;
pcercuei 0:03b5121a232e 648 const xmlChar *name;
pcercuei 0:03b5121a232e 649 const xmlChar *targetNamespace;
pcercuei 0:03b5121a232e 650 xmlNodePtr node;
pcercuei 0:03b5121a232e 651 };
pcercuei 0:03b5121a232e 652
pcercuei 0:03b5121a232e 653 /**
pcercuei 0:03b5121a232e 654 * xmlSchemaParticle:
pcercuei 0:03b5121a232e 655 *
pcercuei 0:03b5121a232e 656 * A particle component.
pcercuei 0:03b5121a232e 657 * (Extends xmlSchemaTreeItem)
pcercuei 0:03b5121a232e 658 */
pcercuei 0:03b5121a232e 659 typedef struct _xmlSchemaParticle xmlSchemaParticle;
pcercuei 0:03b5121a232e 660 typedef xmlSchemaParticle *xmlSchemaParticlePtr;
pcercuei 0:03b5121a232e 661 struct _xmlSchemaParticle {
pcercuei 0:03b5121a232e 662 xmlSchemaTypeType type;
pcercuei 0:03b5121a232e 663 xmlSchemaAnnotPtr annot;
pcercuei 0:03b5121a232e 664 xmlSchemaTreeItemPtr next; /* next particle */
pcercuei 0:03b5121a232e 665 xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
pcercuei 0:03b5121a232e 666 a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
pcercuei 0:03b5121a232e 667 etc.) */
pcercuei 0:03b5121a232e 668 int minOccurs;
pcercuei 0:03b5121a232e 669 int maxOccurs;
pcercuei 0:03b5121a232e 670 xmlNodePtr node;
pcercuei 0:03b5121a232e 671 };
pcercuei 0:03b5121a232e 672
pcercuei 0:03b5121a232e 673 /**
pcercuei 0:03b5121a232e 674 * xmlSchemaModelGroup:
pcercuei 0:03b5121a232e 675 *
pcercuei 0:03b5121a232e 676 * A model group component.
pcercuei 0:03b5121a232e 677 * (Extends xmlSchemaTreeItem)
pcercuei 0:03b5121a232e 678 */
pcercuei 0:03b5121a232e 679 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
pcercuei 0:03b5121a232e 680 typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
pcercuei 0:03b5121a232e 681 struct _xmlSchemaModelGroup {
pcercuei 0:03b5121a232e 682 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
pcercuei 0:03b5121a232e 683 xmlSchemaAnnotPtr annot;
pcercuei 0:03b5121a232e 684 xmlSchemaTreeItemPtr next; /* not used */
pcercuei 0:03b5121a232e 685 xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
pcercuei 0:03b5121a232e 686 xmlNodePtr node;
pcercuei 0:03b5121a232e 687 };
pcercuei 0:03b5121a232e 688
pcercuei 0:03b5121a232e 689 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
pcercuei 0:03b5121a232e 690 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
pcercuei 0:03b5121a232e 691 /**
pcercuei 0:03b5121a232e 692 * xmlSchemaModelGroupDef:
pcercuei 0:03b5121a232e 693 *
pcercuei 0:03b5121a232e 694 * A model group definition component.
pcercuei 0:03b5121a232e 695 * (Extends xmlSchemaTreeItem)
pcercuei 0:03b5121a232e 696 */
pcercuei 0:03b5121a232e 697 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
pcercuei 0:03b5121a232e 698 typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
pcercuei 0:03b5121a232e 699 struct _xmlSchemaModelGroupDef {
pcercuei 0:03b5121a232e 700 xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
pcercuei 0:03b5121a232e 701 xmlSchemaAnnotPtr annot;
pcercuei 0:03b5121a232e 702 xmlSchemaTreeItemPtr next; /* not used */
pcercuei 0:03b5121a232e 703 xmlSchemaTreeItemPtr children; /* the "model group" */
pcercuei 0:03b5121a232e 704 const xmlChar *name;
pcercuei 0:03b5121a232e 705 const xmlChar *targetNamespace;
pcercuei 0:03b5121a232e 706 xmlNodePtr node;
pcercuei 0:03b5121a232e 707 int flags;
pcercuei 0:03b5121a232e 708 };
pcercuei 0:03b5121a232e 709
pcercuei 0:03b5121a232e 710 typedef struct _xmlSchemaIDC xmlSchemaIDC;
pcercuei 0:03b5121a232e 711 typedef xmlSchemaIDC *xmlSchemaIDCPtr;
pcercuei 0:03b5121a232e 712
pcercuei 0:03b5121a232e 713 /**
pcercuei 0:03b5121a232e 714 * xmlSchemaIDCSelect:
pcercuei 0:03b5121a232e 715 *
pcercuei 0:03b5121a232e 716 * The identity-constraint "field" and "selector" item, holding the
pcercuei 0:03b5121a232e 717 * XPath expression.
pcercuei 0:03b5121a232e 718 */
pcercuei 0:03b5121a232e 719 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
pcercuei 0:03b5121a232e 720 typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
pcercuei 0:03b5121a232e 721 struct _xmlSchemaIDCSelect {
pcercuei 0:03b5121a232e 722 xmlSchemaIDCSelectPtr next;
pcercuei 0:03b5121a232e 723 xmlSchemaIDCPtr idc;
pcercuei 0:03b5121a232e 724 int index; /* an index position if significant for IDC key-sequences */
pcercuei 0:03b5121a232e 725 const xmlChar *xpath; /* the XPath expression */
pcercuei 0:03b5121a232e 726 void *xpathComp; /* the compiled XPath expression */
pcercuei 0:03b5121a232e 727 };
pcercuei 0:03b5121a232e 728
pcercuei 0:03b5121a232e 729 /**
pcercuei 0:03b5121a232e 730 * xmlSchemaIDC:
pcercuei 0:03b5121a232e 731 *
pcercuei 0:03b5121a232e 732 * The identity-constraint definition component.
pcercuei 0:03b5121a232e 733 * (Extends xmlSchemaAnnotItem)
pcercuei 0:03b5121a232e 734 */
pcercuei 0:03b5121a232e 735
pcercuei 0:03b5121a232e 736 struct _xmlSchemaIDC {
pcercuei 0:03b5121a232e 737 xmlSchemaTypeType type;
pcercuei 0:03b5121a232e 738 xmlSchemaAnnotPtr annot;
pcercuei 0:03b5121a232e 739 xmlSchemaIDCPtr next;
pcercuei 0:03b5121a232e 740 xmlNodePtr node;
pcercuei 0:03b5121a232e 741 const xmlChar *name;
pcercuei 0:03b5121a232e 742 const xmlChar *targetNamespace;
pcercuei 0:03b5121a232e 743 xmlSchemaIDCSelectPtr selector;
pcercuei 0:03b5121a232e 744 xmlSchemaIDCSelectPtr fields;
pcercuei 0:03b5121a232e 745 int nbFields;
pcercuei 0:03b5121a232e 746 xmlSchemaQNameRefPtr ref;
pcercuei 0:03b5121a232e 747 };
pcercuei 0:03b5121a232e 748
pcercuei 0:03b5121a232e 749 /**
pcercuei 0:03b5121a232e 750 * xmlSchemaIDCAug:
pcercuei 0:03b5121a232e 751 *
pcercuei 0:03b5121a232e 752 * The augmented IDC information used for validation.
pcercuei 0:03b5121a232e 753 */
pcercuei 0:03b5121a232e 754 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
pcercuei 0:03b5121a232e 755 typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
pcercuei 0:03b5121a232e 756 struct _xmlSchemaIDCAug {
pcercuei 0:03b5121a232e 757 xmlSchemaIDCAugPtr next; /* next in a list */
pcercuei 0:03b5121a232e 758 xmlSchemaIDCPtr def; /* the IDC definition */
pcercuei 0:03b5121a232e 759 int keyrefDepth; /* the lowest tree level to which IDC
pcercuei 0:03b5121a232e 760 tables need to be bubbled upwards */
pcercuei 0:03b5121a232e 761 };
pcercuei 0:03b5121a232e 762
pcercuei 0:03b5121a232e 763 /**
pcercuei 0:03b5121a232e 764 * xmlSchemaPSVIIDCKeySequence:
pcercuei 0:03b5121a232e 765 *
pcercuei 0:03b5121a232e 766 * The key sequence of a node table item.
pcercuei 0:03b5121a232e 767 */
pcercuei 0:03b5121a232e 768 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
pcercuei 0:03b5121a232e 769 typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
pcercuei 0:03b5121a232e 770 struct _xmlSchemaPSVIIDCKey {
pcercuei 0:03b5121a232e 771 xmlSchemaTypePtr type;
pcercuei 0:03b5121a232e 772 xmlSchemaValPtr val;
pcercuei 0:03b5121a232e 773 };
pcercuei 0:03b5121a232e 774
pcercuei 0:03b5121a232e 775 /**
pcercuei 0:03b5121a232e 776 * xmlSchemaPSVIIDCNode:
pcercuei 0:03b5121a232e 777 *
pcercuei 0:03b5121a232e 778 * The node table item of a node table.
pcercuei 0:03b5121a232e 779 */
pcercuei 0:03b5121a232e 780 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
pcercuei 0:03b5121a232e 781 typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
pcercuei 0:03b5121a232e 782 struct _xmlSchemaPSVIIDCNode {
pcercuei 0:03b5121a232e 783 xmlNodePtr node;
pcercuei 0:03b5121a232e 784 xmlSchemaPSVIIDCKeyPtr *keys;
pcercuei 0:03b5121a232e 785 int nodeLine;
pcercuei 0:03b5121a232e 786 int nodeQNameID;
pcercuei 0:03b5121a232e 787
pcercuei 0:03b5121a232e 788 };
pcercuei 0:03b5121a232e 789
pcercuei 0:03b5121a232e 790 /**
pcercuei 0:03b5121a232e 791 * xmlSchemaPSVIIDCBinding:
pcercuei 0:03b5121a232e 792 *
pcercuei 0:03b5121a232e 793 * The identity-constraint binding item of the [identity-constraint table].
pcercuei 0:03b5121a232e 794 */
pcercuei 0:03b5121a232e 795 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
pcercuei 0:03b5121a232e 796 typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
pcercuei 0:03b5121a232e 797 struct _xmlSchemaPSVIIDCBinding {
pcercuei 0:03b5121a232e 798 xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
pcercuei 0:03b5121a232e 799 xmlSchemaIDCPtr definition; /* the IDC definition */
pcercuei 0:03b5121a232e 800 xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
pcercuei 0:03b5121a232e 801 int nbNodes; /* number of entries in the node table */
pcercuei 0:03b5121a232e 802 int sizeNodes; /* size of the node table */
pcercuei 0:03b5121a232e 803 xmlSchemaItemListPtr dupls;
pcercuei 0:03b5121a232e 804 };
pcercuei 0:03b5121a232e 805
pcercuei 0:03b5121a232e 806
pcercuei 0:03b5121a232e 807 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
pcercuei 0:03b5121a232e 808 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
pcercuei 0:03b5121a232e 809
pcercuei 0:03b5121a232e 810 #define XPATH_STATE_OBJ_MATCHES -2
pcercuei 0:03b5121a232e 811 #define XPATH_STATE_OBJ_BLOCKED -3
pcercuei 0:03b5121a232e 812
pcercuei 0:03b5121a232e 813 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
pcercuei 0:03b5121a232e 814 typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
pcercuei 0:03b5121a232e 815
pcercuei 0:03b5121a232e 816 /**
pcercuei 0:03b5121a232e 817 * xmlSchemaIDCStateObj:
pcercuei 0:03b5121a232e 818 *
pcercuei 0:03b5121a232e 819 * The state object used to evaluate XPath expressions.
pcercuei 0:03b5121a232e 820 */
pcercuei 0:03b5121a232e 821 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
pcercuei 0:03b5121a232e 822 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
pcercuei 0:03b5121a232e 823 struct _xmlSchemaIDCStateObj {
pcercuei 0:03b5121a232e 824 int type;
pcercuei 0:03b5121a232e 825 xmlSchemaIDCStateObjPtr next; /* next if in a list */
pcercuei 0:03b5121a232e 826 int depth; /* depth of creation */
pcercuei 0:03b5121a232e 827 int *history; /* list of (depth, state-id) tuples */
pcercuei 0:03b5121a232e 828 int nbHistory;
pcercuei 0:03b5121a232e 829 int sizeHistory;
pcercuei 0:03b5121a232e 830 xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
pcercuei 0:03b5121a232e 831 matcher */
pcercuei 0:03b5121a232e 832 xmlSchemaIDCSelectPtr sel;
pcercuei 0:03b5121a232e 833 void *xpathCtxt;
pcercuei 0:03b5121a232e 834 };
pcercuei 0:03b5121a232e 835
pcercuei 0:03b5121a232e 836 #define IDC_MATCHER 0
pcercuei 0:03b5121a232e 837
pcercuei 0:03b5121a232e 838 /**
pcercuei 0:03b5121a232e 839 * xmlSchemaIDCMatcher:
pcercuei 0:03b5121a232e 840 *
pcercuei 0:03b5121a232e 841 * Used to evaluate IDC selectors (and fields).
pcercuei 0:03b5121a232e 842 */
pcercuei 0:03b5121a232e 843 struct _xmlSchemaIDCMatcher {
pcercuei 0:03b5121a232e 844 int type;
pcercuei 0:03b5121a232e 845 int depth; /* the tree depth at creation time */
pcercuei 0:03b5121a232e 846 xmlSchemaIDCMatcherPtr next; /* next in the list */
pcercuei 0:03b5121a232e 847 xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
pcercuei 0:03b5121a232e 848 xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
pcercuei 0:03b5121a232e 849 int idcType;
pcercuei 0:03b5121a232e 850 xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
pcercuei 0:03b5121a232e 851 elements */
pcercuei 0:03b5121a232e 852 int sizeKeySeqs;
pcercuei 0:03b5121a232e 853 xmlSchemaItemListPtr targets; /* list of target-node
pcercuei 0:03b5121a232e 854 (xmlSchemaPSVIIDCNodePtr) entries */
pcercuei 0:03b5121a232e 855 };
pcercuei 0:03b5121a232e 856
pcercuei 0:03b5121a232e 857 /*
pcercuei 0:03b5121a232e 858 * Element info flags.
pcercuei 0:03b5121a232e 859 */
pcercuei 0:03b5121a232e 860 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0
pcercuei 0:03b5121a232e 861 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
pcercuei 0:03b5121a232e 862 #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2
pcercuei 0:03b5121a232e 863 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3
pcercuei 0:03b5121a232e 864
pcercuei 0:03b5121a232e 865 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4
pcercuei 0:03b5121a232e 866 #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5
pcercuei 0:03b5121a232e 867 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6
pcercuei 0:03b5121a232e 868
pcercuei 0:03b5121a232e 869 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7
pcercuei 0:03b5121a232e 870 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8
pcercuei 0:03b5121a232e 871 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9
pcercuei 0:03b5121a232e 872 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10
pcercuei 0:03b5121a232e 873
pcercuei 0:03b5121a232e 874 /**
pcercuei 0:03b5121a232e 875 * xmlSchemaNodeInfo:
pcercuei 0:03b5121a232e 876 *
pcercuei 0:03b5121a232e 877 * Holds information of an element node.
pcercuei 0:03b5121a232e 878 */
pcercuei 0:03b5121a232e 879 struct _xmlSchemaNodeInfo {
pcercuei 0:03b5121a232e 880 int nodeType;
pcercuei 0:03b5121a232e 881 xmlNodePtr node;
pcercuei 0:03b5121a232e 882 int nodeLine;
pcercuei 0:03b5121a232e 883 const xmlChar *localName;
pcercuei 0:03b5121a232e 884 const xmlChar *nsName;
pcercuei 0:03b5121a232e 885 const xmlChar *value;
pcercuei 0:03b5121a232e 886 xmlSchemaValPtr val; /* the pre-computed value if any */
pcercuei 0:03b5121a232e 887 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
pcercuei 0:03b5121a232e 888
pcercuei 0:03b5121a232e 889 int flags; /* combination of node info flags */
pcercuei 0:03b5121a232e 890
pcercuei 0:03b5121a232e 891 int valNeeded;
pcercuei 0:03b5121a232e 892 int normVal;
pcercuei 0:03b5121a232e 893
pcercuei 0:03b5121a232e 894 xmlSchemaElementPtr decl; /* the element/attribute declaration */
pcercuei 0:03b5121a232e 895 int depth;
pcercuei 0:03b5121a232e 896 xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
pcercuei 0:03b5121a232e 897 for the scope element*/
pcercuei 0:03b5121a232e 898 xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
pcercuei 0:03b5121a232e 899 element */
pcercuei 0:03b5121a232e 900 xmlRegExecCtxtPtr regexCtxt;
pcercuei 0:03b5121a232e 901
pcercuei 0:03b5121a232e 902 const xmlChar **nsBindings; /* Namespace bindings on this element */
pcercuei 0:03b5121a232e 903 int nbNsBindings;
pcercuei 0:03b5121a232e 904 int sizeNsBindings;
pcercuei 0:03b5121a232e 905
pcercuei 0:03b5121a232e 906 int hasKeyrefs;
pcercuei 0:03b5121a232e 907 int appliedXPath; /* Indicates that an XPath has been applied. */
pcercuei 0:03b5121a232e 908 };
pcercuei 0:03b5121a232e 909
pcercuei 0:03b5121a232e 910 #define XML_SCHEMAS_ATTR_UNKNOWN 1
pcercuei 0:03b5121a232e 911 #define XML_SCHEMAS_ATTR_ASSESSED 2
pcercuei 0:03b5121a232e 912 #define XML_SCHEMAS_ATTR_PROHIBITED 3
pcercuei 0:03b5121a232e 913 #define XML_SCHEMAS_ATTR_ERR_MISSING 4
pcercuei 0:03b5121a232e 914 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5
pcercuei 0:03b5121a232e 915 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
pcercuei 0:03b5121a232e 916 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
pcercuei 0:03b5121a232e 917 #define XML_SCHEMAS_ATTR_DEFAULT 8
pcercuei 0:03b5121a232e 918 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
pcercuei 0:03b5121a232e 919 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
pcercuei 0:03b5121a232e 920 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
pcercuei 0:03b5121a232e 921 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
pcercuei 0:03b5121a232e 922 #define XML_SCHEMAS_ATTR_WILD_SKIP 13
pcercuei 0:03b5121a232e 923 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
pcercuei 0:03b5121a232e 924 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
pcercuei 0:03b5121a232e 925 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
pcercuei 0:03b5121a232e 926 #define XML_SCHEMAS_ATTR_META 17
pcercuei 0:03b5121a232e 927 /*
pcercuei 0:03b5121a232e 928 * @metaType values of xmlSchemaAttrInfo.
pcercuei 0:03b5121a232e 929 */
pcercuei 0:03b5121a232e 930 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
pcercuei 0:03b5121a232e 931 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
pcercuei 0:03b5121a232e 932 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
pcercuei 0:03b5121a232e 933 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
pcercuei 0:03b5121a232e 934 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
pcercuei 0:03b5121a232e 935
pcercuei 0:03b5121a232e 936 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
pcercuei 0:03b5121a232e 937 typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
pcercuei 0:03b5121a232e 938 struct _xmlSchemaAttrInfo {
pcercuei 0:03b5121a232e 939 int nodeType;
pcercuei 0:03b5121a232e 940 xmlNodePtr node;
pcercuei 0:03b5121a232e 941 int nodeLine;
pcercuei 0:03b5121a232e 942 const xmlChar *localName;
pcercuei 0:03b5121a232e 943 const xmlChar *nsName;
pcercuei 0:03b5121a232e 944 const xmlChar *value;
pcercuei 0:03b5121a232e 945 xmlSchemaValPtr val; /* the pre-computed value if any */
pcercuei 0:03b5121a232e 946 xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
pcercuei 0:03b5121a232e 947 int flags; /* combination of node info flags */
pcercuei 0:03b5121a232e 948
pcercuei 0:03b5121a232e 949 xmlSchemaAttributePtr decl; /* the attribute declaration */
pcercuei 0:03b5121a232e 950 xmlSchemaAttributeUsePtr use; /* the attribute use */
pcercuei 0:03b5121a232e 951 int state;
pcercuei 0:03b5121a232e 952 int metaType;
pcercuei 0:03b5121a232e 953 const xmlChar *vcValue; /* the value constraint value */
pcercuei 0:03b5121a232e 954 xmlSchemaNodeInfoPtr parent;
pcercuei 0:03b5121a232e 955 };
pcercuei 0:03b5121a232e 956
pcercuei 0:03b5121a232e 957
pcercuei 0:03b5121a232e 958 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
pcercuei 0:03b5121a232e 959 /**
pcercuei 0:03b5121a232e 960 * xmlSchemaValidCtxt:
pcercuei 0:03b5121a232e 961 *
pcercuei 0:03b5121a232e 962 * A Schemas validation context
pcercuei 0:03b5121a232e 963 */
pcercuei 0:03b5121a232e 964 struct _xmlSchemaValidCtxt {
pcercuei 0:03b5121a232e 965 int type;
pcercuei 0:03b5121a232e 966 void *errCtxt; /* user specific data block */
pcercuei 0:03b5121a232e 967 xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
pcercuei 0:03b5121a232e 968 xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
pcercuei 0:03b5121a232e 969 xmlStructuredErrorFunc serror;
pcercuei 0:03b5121a232e 970
pcercuei 0:03b5121a232e 971 xmlSchemaPtr schema; /* The schema in use */
pcercuei 0:03b5121a232e 972 xmlDocPtr doc;
pcercuei 0:03b5121a232e 973 xmlParserInputBufferPtr input;
pcercuei 0:03b5121a232e 974 xmlCharEncoding enc;
pcercuei 0:03b5121a232e 975 xmlSAXHandlerPtr sax;
pcercuei 0:03b5121a232e 976 xmlParserCtxtPtr parserCtxt;
pcercuei 0:03b5121a232e 977 void *user_data; /* TODO: What is this for? */
pcercuei 0:03b5121a232e 978 char *filename;
pcercuei 0:03b5121a232e 979
pcercuei 0:03b5121a232e 980 int err;
pcercuei 0:03b5121a232e 981 int nberrors;
pcercuei 0:03b5121a232e 982
pcercuei 0:03b5121a232e 983 xmlNodePtr node;
pcercuei 0:03b5121a232e 984 xmlNodePtr cur;
pcercuei 0:03b5121a232e 985 /* xmlSchemaTypePtr type; */
pcercuei 0:03b5121a232e 986
pcercuei 0:03b5121a232e 987 xmlRegExecCtxtPtr regexp;
pcercuei 0:03b5121a232e 988 xmlSchemaValPtr value;
pcercuei 0:03b5121a232e 989
pcercuei 0:03b5121a232e 990 int valueWS;
pcercuei 0:03b5121a232e 991 int options;
pcercuei 0:03b5121a232e 992 xmlNodePtr validationRoot;
pcercuei 0:03b5121a232e 993 xmlSchemaParserCtxtPtr pctxt;
pcercuei 0:03b5121a232e 994 int xsiAssemble;
pcercuei 0:03b5121a232e 995
pcercuei 0:03b5121a232e 996 int depth;
pcercuei 0:03b5121a232e 997 xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
pcercuei 0:03b5121a232e 998 int sizeElemInfos;
pcercuei 0:03b5121a232e 999 xmlSchemaNodeInfoPtr inode; /* the current element information */
pcercuei 0:03b5121a232e 1000
pcercuei 0:03b5121a232e 1001 xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
pcercuei 0:03b5121a232e 1002
pcercuei 0:03b5121a232e 1003 xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
pcercuei 0:03b5121a232e 1004 xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
pcercuei 0:03b5121a232e 1005 xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
pcercuei 0:03b5121a232e 1006
pcercuei 0:03b5121a232e 1007 xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
pcercuei 0:03b5121a232e 1008 int nbIdcNodes;
pcercuei 0:03b5121a232e 1009 int sizeIdcNodes;
pcercuei 0:03b5121a232e 1010
pcercuei 0:03b5121a232e 1011 xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
pcercuei 0:03b5121a232e 1012 int nbIdcKeys;
pcercuei 0:03b5121a232e 1013 int sizeIdcKeys;
pcercuei 0:03b5121a232e 1014
pcercuei 0:03b5121a232e 1015 int flags;
pcercuei 0:03b5121a232e 1016
pcercuei 0:03b5121a232e 1017 xmlDictPtr dict;
pcercuei 0:03b5121a232e 1018
pcercuei 0:03b5121a232e 1019 #ifdef LIBXML_READER_ENABLED
pcercuei 0:03b5121a232e 1020 xmlTextReaderPtr reader;
pcercuei 0:03b5121a232e 1021 #endif
pcercuei 0:03b5121a232e 1022
pcercuei 0:03b5121a232e 1023 xmlSchemaAttrInfoPtr *attrInfos;
pcercuei 0:03b5121a232e 1024 int nbAttrInfos;
pcercuei 0:03b5121a232e 1025 int sizeAttrInfos;
pcercuei 0:03b5121a232e 1026
pcercuei 0:03b5121a232e 1027 int skipDepth;
pcercuei 0:03b5121a232e 1028 xmlSchemaItemListPtr nodeQNames;
pcercuei 0:03b5121a232e 1029 int hasKeyrefs;
pcercuei 0:03b5121a232e 1030 int createIDCNodeTables;
pcercuei 0:03b5121a232e 1031 int psviExposeIDCNodeTables;
pcercuei 0:03b5121a232e 1032
pcercuei 0:03b5121a232e 1033 /* Locator for error reporting in streaming mode */
pcercuei 0:03b5121a232e 1034 xmlSchemaValidityLocatorFunc locFunc;
pcercuei 0:03b5121a232e 1035 void *locCtxt;
pcercuei 0:03b5121a232e 1036 };
pcercuei 0:03b5121a232e 1037
pcercuei 0:03b5121a232e 1038 /**
pcercuei 0:03b5121a232e 1039 * xmlSchemaSubstGroup:
pcercuei 0:03b5121a232e 1040 *
pcercuei 0:03b5121a232e 1041 *
pcercuei 0:03b5121a232e 1042 */
pcercuei 0:03b5121a232e 1043 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
pcercuei 0:03b5121a232e 1044 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
pcercuei 0:03b5121a232e 1045 struct _xmlSchemaSubstGroup {
pcercuei 0:03b5121a232e 1046 xmlSchemaElementPtr head;
pcercuei 0:03b5121a232e 1047 xmlSchemaItemListPtr members;
pcercuei 0:03b5121a232e 1048 };
pcercuei 0:03b5121a232e 1049
pcercuei 0:03b5121a232e 1050 /************************************************************************
pcercuei 0:03b5121a232e 1051 * *
pcercuei 0:03b5121a232e 1052 * Some predeclarations *
pcercuei 0:03b5121a232e 1053 * *
pcercuei 0:03b5121a232e 1054 ************************************************************************/
pcercuei 0:03b5121a232e 1055
pcercuei 0:03b5121a232e 1056 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 1057 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 1058 xmlNodePtr node);
pcercuei 0:03b5121a232e 1059 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 1060 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 1061 xmlNodePtr node);
pcercuei 0:03b5121a232e 1062 static int
pcercuei 0:03b5121a232e 1063 xmlSchemaTypeFixup(xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 1064 xmlSchemaAbstractCtxtPtr ctxt);
pcercuei 0:03b5121a232e 1065 static const xmlChar *
pcercuei 0:03b5121a232e 1066 xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
pcercuei 0:03b5121a232e 1067 static int
pcercuei 0:03b5121a232e 1068 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 1069 xmlNodePtr node);
pcercuei 0:03b5121a232e 1070 static int
pcercuei 0:03b5121a232e 1071 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
pcercuei 0:03b5121a232e 1072 xmlSchemaParserCtxtPtr ctxt);
pcercuei 0:03b5121a232e 1073 static void
pcercuei 0:03b5121a232e 1074 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
pcercuei 0:03b5121a232e 1075 static xmlSchemaWhitespaceValueType
pcercuei 0:03b5121a232e 1076 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
pcercuei 0:03b5121a232e 1077 static xmlSchemaTreeItemPtr
pcercuei 0:03b5121a232e 1078 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 1079 xmlNodePtr node, xmlSchemaTypeType type,
pcercuei 0:03b5121a232e 1080 int withParticle);
pcercuei 0:03b5121a232e 1081 static const xmlChar *
pcercuei 0:03b5121a232e 1082 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
pcercuei 0:03b5121a232e 1083 static xmlSchemaTypeLinkPtr
pcercuei 0:03b5121a232e 1084 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
pcercuei 0:03b5121a232e 1085 static void
pcercuei 0:03b5121a232e 1086 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 1087 const char *funcName,
pcercuei 0:03b5121a232e 1088 const char *message);
pcercuei 0:03b5121a232e 1089 static int
pcercuei 0:03b5121a232e 1090 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
pcercuei 0:03b5121a232e 1091 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 1092 xmlSchemaTypePtr baseType,
pcercuei 0:03b5121a232e 1093 int subset);
pcercuei 0:03b5121a232e 1094 static void
pcercuei 0:03b5121a232e 1095 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
pcercuei 0:03b5121a232e 1096 xmlSchemaParserCtxtPtr ctxt);
pcercuei 0:03b5121a232e 1097 static void
pcercuei 0:03b5121a232e 1098 xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
pcercuei 0:03b5121a232e 1099 static xmlSchemaQNameRefPtr
pcercuei 0:03b5121a232e 1100 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 1101 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 1102 xmlNodePtr node);
pcercuei 0:03b5121a232e 1103
pcercuei 0:03b5121a232e 1104 /************************************************************************
pcercuei 0:03b5121a232e 1105 * *
pcercuei 0:03b5121a232e 1106 * Helper functions *
pcercuei 0:03b5121a232e 1107 * *
pcercuei 0:03b5121a232e 1108 ************************************************************************/
pcercuei 0:03b5121a232e 1109
pcercuei 0:03b5121a232e 1110 /**
pcercuei 0:03b5121a232e 1111 * xmlSchemaItemTypeToStr:
pcercuei 0:03b5121a232e 1112 * @type: the type of the schema item
pcercuei 0:03b5121a232e 1113 *
pcercuei 0:03b5121a232e 1114 * Returns the component name of a schema item.
pcercuei 0:03b5121a232e 1115 */
pcercuei 0:03b5121a232e 1116 static const xmlChar *
pcercuei 0:03b5121a232e 1117 xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
pcercuei 0:03b5121a232e 1118 {
pcercuei 0:03b5121a232e 1119 switch (type) {
pcercuei 0:03b5121a232e 1120 case XML_SCHEMA_TYPE_BASIC:
pcercuei 0:03b5121a232e 1121 return(BAD_CAST "simple type definition");
pcercuei 0:03b5121a232e 1122 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 1123 return(BAD_CAST "simple type definition");
pcercuei 0:03b5121a232e 1124 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 1125 return(BAD_CAST "complex type definition");
pcercuei 0:03b5121a232e 1126 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 1127 return(BAD_CAST "element declaration");
pcercuei 0:03b5121a232e 1128 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
pcercuei 0:03b5121a232e 1129 return(BAD_CAST "attribute use");
pcercuei 0:03b5121a232e 1130 case XML_SCHEMA_TYPE_ATTRIBUTE:
pcercuei 0:03b5121a232e 1131 return(BAD_CAST "attribute declaration");
pcercuei 0:03b5121a232e 1132 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 1133 return(BAD_CAST "model group definition");
pcercuei 0:03b5121a232e 1134 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 1135 return(BAD_CAST "attribute group definition");
pcercuei 0:03b5121a232e 1136 case XML_SCHEMA_TYPE_NOTATION:
pcercuei 0:03b5121a232e 1137 return(BAD_CAST "notation declaration");
pcercuei 0:03b5121a232e 1138 case XML_SCHEMA_TYPE_SEQUENCE:
pcercuei 0:03b5121a232e 1139 return(BAD_CAST "model group (sequence)");
pcercuei 0:03b5121a232e 1140 case XML_SCHEMA_TYPE_CHOICE:
pcercuei 0:03b5121a232e 1141 return(BAD_CAST "model group (choice)");
pcercuei 0:03b5121a232e 1142 case XML_SCHEMA_TYPE_ALL:
pcercuei 0:03b5121a232e 1143 return(BAD_CAST "model group (all)");
pcercuei 0:03b5121a232e 1144 case XML_SCHEMA_TYPE_PARTICLE:
pcercuei 0:03b5121a232e 1145 return(BAD_CAST "particle");
pcercuei 0:03b5121a232e 1146 case XML_SCHEMA_TYPE_IDC_UNIQUE:
pcercuei 0:03b5121a232e 1147 return(BAD_CAST "unique identity-constraint");
pcercuei 0:03b5121a232e 1148 /* return(BAD_CAST "IDC (unique)"); */
pcercuei 0:03b5121a232e 1149 case XML_SCHEMA_TYPE_IDC_KEY:
pcercuei 0:03b5121a232e 1150 return(BAD_CAST "key identity-constraint");
pcercuei 0:03b5121a232e 1151 /* return(BAD_CAST "IDC (key)"); */
pcercuei 0:03b5121a232e 1152 case XML_SCHEMA_TYPE_IDC_KEYREF:
pcercuei 0:03b5121a232e 1153 return(BAD_CAST "keyref identity-constraint");
pcercuei 0:03b5121a232e 1154 /* return(BAD_CAST "IDC (keyref)"); */
pcercuei 0:03b5121a232e 1155 case XML_SCHEMA_TYPE_ANY:
pcercuei 0:03b5121a232e 1156 return(BAD_CAST "wildcard (any)");
pcercuei 0:03b5121a232e 1157 case XML_SCHEMA_EXTRA_QNAMEREF:
pcercuei 0:03b5121a232e 1158 return(BAD_CAST "[helper component] QName reference");
pcercuei 0:03b5121a232e 1159 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
pcercuei 0:03b5121a232e 1160 return(BAD_CAST "[helper component] attribute use prohibition");
pcercuei 0:03b5121a232e 1161 default:
pcercuei 0:03b5121a232e 1162 return(BAD_CAST "Not a schema component");
pcercuei 0:03b5121a232e 1163 }
pcercuei 0:03b5121a232e 1164 }
pcercuei 0:03b5121a232e 1165
pcercuei 0:03b5121a232e 1166 /**
pcercuei 0:03b5121a232e 1167 * xmlSchemaGetComponentTypeStr:
pcercuei 0:03b5121a232e 1168 * @type: the type of the schema item
pcercuei 0:03b5121a232e 1169 *
pcercuei 0:03b5121a232e 1170 * Returns the component name of a schema item.
pcercuei 0:03b5121a232e 1171 */
pcercuei 0:03b5121a232e 1172 static const xmlChar *
pcercuei 0:03b5121a232e 1173 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
pcercuei 0:03b5121a232e 1174 {
pcercuei 0:03b5121a232e 1175 switch (item->type) {
pcercuei 0:03b5121a232e 1176 case XML_SCHEMA_TYPE_BASIC:
pcercuei 0:03b5121a232e 1177 if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
pcercuei 0:03b5121a232e 1178 return(BAD_CAST "complex type definition");
pcercuei 0:03b5121a232e 1179 else
pcercuei 0:03b5121a232e 1180 return(BAD_CAST "simple type definition");
pcercuei 0:03b5121a232e 1181 default:
pcercuei 0:03b5121a232e 1182 return(xmlSchemaItemTypeToStr(item->type));
pcercuei 0:03b5121a232e 1183 }
pcercuei 0:03b5121a232e 1184 }
pcercuei 0:03b5121a232e 1185
pcercuei 0:03b5121a232e 1186 /**
pcercuei 0:03b5121a232e 1187 * xmlSchemaGetComponentNode:
pcercuei 0:03b5121a232e 1188 * @item: a schema component
pcercuei 0:03b5121a232e 1189 *
pcercuei 0:03b5121a232e 1190 * Returns node associated with the schema component.
pcercuei 0:03b5121a232e 1191 * NOTE that such a node need not be available; plus, a component's
pcercuei 0:03b5121a232e 1192 * node need not to reflect the component directly, since there is no
pcercuei 0:03b5121a232e 1193 * one-to-one relationship between the XML Schema representation and
pcercuei 0:03b5121a232e 1194 * the component representation.
pcercuei 0:03b5121a232e 1195 */
pcercuei 0:03b5121a232e 1196 static xmlNodePtr
pcercuei 0:03b5121a232e 1197 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
pcercuei 0:03b5121a232e 1198 {
pcercuei 0:03b5121a232e 1199 switch (item->type) {
pcercuei 0:03b5121a232e 1200 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 1201 return (((xmlSchemaElementPtr) item)->node);
pcercuei 0:03b5121a232e 1202 case XML_SCHEMA_TYPE_ATTRIBUTE:
pcercuei 0:03b5121a232e 1203 return (((xmlSchemaAttributePtr) item)->node);
pcercuei 0:03b5121a232e 1204 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 1205 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 1206 return (((xmlSchemaTypePtr) item)->node);
pcercuei 0:03b5121a232e 1207 case XML_SCHEMA_TYPE_ANY:
pcercuei 0:03b5121a232e 1208 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
pcercuei 0:03b5121a232e 1209 return (((xmlSchemaWildcardPtr) item)->node);
pcercuei 0:03b5121a232e 1210 case XML_SCHEMA_TYPE_PARTICLE:
pcercuei 0:03b5121a232e 1211 return (((xmlSchemaParticlePtr) item)->node);
pcercuei 0:03b5121a232e 1212 case XML_SCHEMA_TYPE_SEQUENCE:
pcercuei 0:03b5121a232e 1213 case XML_SCHEMA_TYPE_CHOICE:
pcercuei 0:03b5121a232e 1214 case XML_SCHEMA_TYPE_ALL:
pcercuei 0:03b5121a232e 1215 return (((xmlSchemaModelGroupPtr) item)->node);
pcercuei 0:03b5121a232e 1216 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 1217 return (((xmlSchemaModelGroupDefPtr) item)->node);
pcercuei 0:03b5121a232e 1218 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 1219 return (((xmlSchemaAttributeGroupPtr) item)->node);
pcercuei 0:03b5121a232e 1220 case XML_SCHEMA_TYPE_IDC_UNIQUE:
pcercuei 0:03b5121a232e 1221 case XML_SCHEMA_TYPE_IDC_KEY:
pcercuei 0:03b5121a232e 1222 case XML_SCHEMA_TYPE_IDC_KEYREF:
pcercuei 0:03b5121a232e 1223 return (((xmlSchemaIDCPtr) item)->node);
pcercuei 0:03b5121a232e 1224 case XML_SCHEMA_EXTRA_QNAMEREF:
pcercuei 0:03b5121a232e 1225 return(((xmlSchemaQNameRefPtr) item)->node);
pcercuei 0:03b5121a232e 1226 /* TODO: What to do with NOTATIONs?
pcercuei 0:03b5121a232e 1227 case XML_SCHEMA_TYPE_NOTATION:
pcercuei 0:03b5121a232e 1228 return (((xmlSchemaNotationPtr) item)->node);
pcercuei 0:03b5121a232e 1229 */
pcercuei 0:03b5121a232e 1230 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
pcercuei 0:03b5121a232e 1231 return (((xmlSchemaAttributeUsePtr) item)->node);
pcercuei 0:03b5121a232e 1232 default:
pcercuei 0:03b5121a232e 1233 return (NULL);
pcercuei 0:03b5121a232e 1234 }
pcercuei 0:03b5121a232e 1235 }
pcercuei 0:03b5121a232e 1236
pcercuei 0:03b5121a232e 1237 #if 0
pcercuei 0:03b5121a232e 1238 /**
pcercuei 0:03b5121a232e 1239 * xmlSchemaGetNextComponent:
pcercuei 0:03b5121a232e 1240 * @item: a schema component
pcercuei 0:03b5121a232e 1241 *
pcercuei 0:03b5121a232e 1242 * Returns the next sibling of the schema component.
pcercuei 0:03b5121a232e 1243 */
pcercuei 0:03b5121a232e 1244 static xmlSchemaBasicItemPtr
pcercuei 0:03b5121a232e 1245 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
pcercuei 0:03b5121a232e 1246 {
pcercuei 0:03b5121a232e 1247 switch (item->type) {
pcercuei 0:03b5121a232e 1248 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 1249 return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
pcercuei 0:03b5121a232e 1250 case XML_SCHEMA_TYPE_ATTRIBUTE:
pcercuei 0:03b5121a232e 1251 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
pcercuei 0:03b5121a232e 1252 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 1253 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 1254 return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
pcercuei 0:03b5121a232e 1255 case XML_SCHEMA_TYPE_ANY:
pcercuei 0:03b5121a232e 1256 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
pcercuei 0:03b5121a232e 1257 return (NULL);
pcercuei 0:03b5121a232e 1258 case XML_SCHEMA_TYPE_PARTICLE:
pcercuei 0:03b5121a232e 1259 return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
pcercuei 0:03b5121a232e 1260 case XML_SCHEMA_TYPE_SEQUENCE:
pcercuei 0:03b5121a232e 1261 case XML_SCHEMA_TYPE_CHOICE:
pcercuei 0:03b5121a232e 1262 case XML_SCHEMA_TYPE_ALL:
pcercuei 0:03b5121a232e 1263 return (NULL);
pcercuei 0:03b5121a232e 1264 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 1265 return (NULL);
pcercuei 0:03b5121a232e 1266 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 1267 return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
pcercuei 0:03b5121a232e 1268 case XML_SCHEMA_TYPE_IDC_UNIQUE:
pcercuei 0:03b5121a232e 1269 case XML_SCHEMA_TYPE_IDC_KEY:
pcercuei 0:03b5121a232e 1270 case XML_SCHEMA_TYPE_IDC_KEYREF:
pcercuei 0:03b5121a232e 1271 return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
pcercuei 0:03b5121a232e 1272 default:
pcercuei 0:03b5121a232e 1273 return (NULL);
pcercuei 0:03b5121a232e 1274 }
pcercuei 0:03b5121a232e 1275 }
pcercuei 0:03b5121a232e 1276 #endif
pcercuei 0:03b5121a232e 1277
pcercuei 0:03b5121a232e 1278
pcercuei 0:03b5121a232e 1279 /**
pcercuei 0:03b5121a232e 1280 * xmlSchemaFormatQName:
pcercuei 0:03b5121a232e 1281 * @buf: the string buffer
pcercuei 0:03b5121a232e 1282 * @namespaceName: the namespace name
pcercuei 0:03b5121a232e 1283 * @localName: the local name
pcercuei 0:03b5121a232e 1284 *
pcercuei 0:03b5121a232e 1285 * Returns the given QName in the format "{namespaceName}localName" or
pcercuei 0:03b5121a232e 1286 * just "localName" if @namespaceName is NULL.
pcercuei 0:03b5121a232e 1287 *
pcercuei 0:03b5121a232e 1288 * Returns the localName if @namespaceName is NULL, a formatted
pcercuei 0:03b5121a232e 1289 * string otherwise.
pcercuei 0:03b5121a232e 1290 */
pcercuei 0:03b5121a232e 1291 static const xmlChar*
pcercuei 0:03b5121a232e 1292 xmlSchemaFormatQName(xmlChar **buf,
pcercuei 0:03b5121a232e 1293 const xmlChar *namespaceName,
pcercuei 0:03b5121a232e 1294 const xmlChar *localName)
pcercuei 0:03b5121a232e 1295 {
pcercuei 0:03b5121a232e 1296 FREE_AND_NULL(*buf)
pcercuei 0:03b5121a232e 1297 if (namespaceName != NULL) {
pcercuei 0:03b5121a232e 1298 *buf = xmlStrdup(BAD_CAST "{");
pcercuei 0:03b5121a232e 1299 *buf = xmlStrcat(*buf, namespaceName);
pcercuei 0:03b5121a232e 1300 *buf = xmlStrcat(*buf, BAD_CAST "}");
pcercuei 0:03b5121a232e 1301 }
pcercuei 0:03b5121a232e 1302 if (localName != NULL) {
pcercuei 0:03b5121a232e 1303 if (namespaceName == NULL)
pcercuei 0:03b5121a232e 1304 return(localName);
pcercuei 0:03b5121a232e 1305 *buf = xmlStrcat(*buf, localName);
pcercuei 0:03b5121a232e 1306 } else {
pcercuei 0:03b5121a232e 1307 *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
pcercuei 0:03b5121a232e 1308 }
pcercuei 0:03b5121a232e 1309 return ((const xmlChar *) *buf);
pcercuei 0:03b5121a232e 1310 }
pcercuei 0:03b5121a232e 1311
pcercuei 0:03b5121a232e 1312 static const xmlChar*
pcercuei 0:03b5121a232e 1313 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
pcercuei 0:03b5121a232e 1314 {
pcercuei 0:03b5121a232e 1315 if (ns != NULL)
pcercuei 0:03b5121a232e 1316 return (xmlSchemaFormatQName(buf, ns->href, localName));
pcercuei 0:03b5121a232e 1317 else
pcercuei 0:03b5121a232e 1318 return (xmlSchemaFormatQName(buf, NULL, localName));
pcercuei 0:03b5121a232e 1319 }
pcercuei 0:03b5121a232e 1320
pcercuei 0:03b5121a232e 1321 static const xmlChar *
pcercuei 0:03b5121a232e 1322 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
pcercuei 0:03b5121a232e 1323 {
pcercuei 0:03b5121a232e 1324 switch (item->type) {
pcercuei 0:03b5121a232e 1325 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 1326 return (((xmlSchemaElementPtr) item)->name);
pcercuei 0:03b5121a232e 1327 case XML_SCHEMA_TYPE_ATTRIBUTE:
pcercuei 0:03b5121a232e 1328 return (((xmlSchemaAttributePtr) item)->name);
pcercuei 0:03b5121a232e 1329 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 1330 return (((xmlSchemaAttributeGroupPtr) item)->name);
pcercuei 0:03b5121a232e 1331 case XML_SCHEMA_TYPE_BASIC:
pcercuei 0:03b5121a232e 1332 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 1333 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 1334 return (((xmlSchemaTypePtr) item)->name);
pcercuei 0:03b5121a232e 1335 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 1336 return (((xmlSchemaModelGroupDefPtr) item)->name);
pcercuei 0:03b5121a232e 1337 case XML_SCHEMA_TYPE_IDC_KEY:
pcercuei 0:03b5121a232e 1338 case XML_SCHEMA_TYPE_IDC_UNIQUE:
pcercuei 0:03b5121a232e 1339 case XML_SCHEMA_TYPE_IDC_KEYREF:
pcercuei 0:03b5121a232e 1340 return (((xmlSchemaIDCPtr) item)->name);
pcercuei 0:03b5121a232e 1341 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
pcercuei 0:03b5121a232e 1342 if (WXS_ATTRUSE_DECL(item) != NULL) {
pcercuei 0:03b5121a232e 1343 return(xmlSchemaGetComponentName(
pcercuei 0:03b5121a232e 1344 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
pcercuei 0:03b5121a232e 1345 } else
pcercuei 0:03b5121a232e 1346 return(NULL);
pcercuei 0:03b5121a232e 1347 case XML_SCHEMA_EXTRA_QNAMEREF:
pcercuei 0:03b5121a232e 1348 return (((xmlSchemaQNameRefPtr) item)->name);
pcercuei 0:03b5121a232e 1349 case XML_SCHEMA_TYPE_NOTATION:
pcercuei 0:03b5121a232e 1350 return (((xmlSchemaNotationPtr) item)->name);
pcercuei 0:03b5121a232e 1351 default:
pcercuei 0:03b5121a232e 1352 /*
pcercuei 0:03b5121a232e 1353 * Other components cannot have names.
pcercuei 0:03b5121a232e 1354 */
pcercuei 0:03b5121a232e 1355 break;
pcercuei 0:03b5121a232e 1356 }
pcercuei 0:03b5121a232e 1357 return (NULL);
pcercuei 0:03b5121a232e 1358 }
pcercuei 0:03b5121a232e 1359
pcercuei 0:03b5121a232e 1360 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
pcercuei 0:03b5121a232e 1361 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
pcercuei 0:03b5121a232e 1362 /*
pcercuei 0:03b5121a232e 1363 static const xmlChar *
pcercuei 0:03b5121a232e 1364 xmlSchemaGetQNameRefName(void *ref)
pcercuei 0:03b5121a232e 1365 {
pcercuei 0:03b5121a232e 1366 return(((xmlSchemaQNameRefPtr) ref)->name);
pcercuei 0:03b5121a232e 1367 }
pcercuei 0:03b5121a232e 1368
pcercuei 0:03b5121a232e 1369 static const xmlChar *
pcercuei 0:03b5121a232e 1370 xmlSchemaGetQNameRefTargetNs(void *ref)
pcercuei 0:03b5121a232e 1371 {
pcercuei 0:03b5121a232e 1372 return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
pcercuei 0:03b5121a232e 1373 }
pcercuei 0:03b5121a232e 1374 */
pcercuei 0:03b5121a232e 1375
pcercuei 0:03b5121a232e 1376 static const xmlChar *
pcercuei 0:03b5121a232e 1377 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
pcercuei 0:03b5121a232e 1378 {
pcercuei 0:03b5121a232e 1379 switch (item->type) {
pcercuei 0:03b5121a232e 1380 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 1381 return (((xmlSchemaElementPtr) item)->targetNamespace);
pcercuei 0:03b5121a232e 1382 case XML_SCHEMA_TYPE_ATTRIBUTE:
pcercuei 0:03b5121a232e 1383 return (((xmlSchemaAttributePtr) item)->targetNamespace);
pcercuei 0:03b5121a232e 1384 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 1385 return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
pcercuei 0:03b5121a232e 1386 case XML_SCHEMA_TYPE_BASIC:
pcercuei 0:03b5121a232e 1387 return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
pcercuei 0:03b5121a232e 1388 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 1389 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 1390 return (((xmlSchemaTypePtr) item)->targetNamespace);
pcercuei 0:03b5121a232e 1391 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 1392 return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
pcercuei 0:03b5121a232e 1393 case XML_SCHEMA_TYPE_IDC_KEY:
pcercuei 0:03b5121a232e 1394 case XML_SCHEMA_TYPE_IDC_UNIQUE:
pcercuei 0:03b5121a232e 1395 case XML_SCHEMA_TYPE_IDC_KEYREF:
pcercuei 0:03b5121a232e 1396 return (((xmlSchemaIDCPtr) item)->targetNamespace);
pcercuei 0:03b5121a232e 1397 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
pcercuei 0:03b5121a232e 1398 if (WXS_ATTRUSE_DECL(item) != NULL) {
pcercuei 0:03b5121a232e 1399 return(xmlSchemaGetComponentTargetNs(
pcercuei 0:03b5121a232e 1400 WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
pcercuei 0:03b5121a232e 1401 }
pcercuei 0:03b5121a232e 1402 /* TODO: Will returning NULL break something? */
pcercuei 0:03b5121a232e 1403 break;
pcercuei 0:03b5121a232e 1404 case XML_SCHEMA_EXTRA_QNAMEREF:
pcercuei 0:03b5121a232e 1405 return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
pcercuei 0:03b5121a232e 1406 case XML_SCHEMA_TYPE_NOTATION:
pcercuei 0:03b5121a232e 1407 return (((xmlSchemaNotationPtr) item)->targetNamespace);
pcercuei 0:03b5121a232e 1408 default:
pcercuei 0:03b5121a232e 1409 /*
pcercuei 0:03b5121a232e 1410 * Other components cannot have names.
pcercuei 0:03b5121a232e 1411 */
pcercuei 0:03b5121a232e 1412 break;
pcercuei 0:03b5121a232e 1413 }
pcercuei 0:03b5121a232e 1414 return (NULL);
pcercuei 0:03b5121a232e 1415 }
pcercuei 0:03b5121a232e 1416
pcercuei 0:03b5121a232e 1417 static const xmlChar*
pcercuei 0:03b5121a232e 1418 xmlSchemaGetComponentQName(xmlChar **buf,
pcercuei 0:03b5121a232e 1419 void *item)
pcercuei 0:03b5121a232e 1420 {
pcercuei 0:03b5121a232e 1421 return (xmlSchemaFormatQName(buf,
pcercuei 0:03b5121a232e 1422 xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
pcercuei 0:03b5121a232e 1423 xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
pcercuei 0:03b5121a232e 1424 }
pcercuei 0:03b5121a232e 1425
pcercuei 0:03b5121a232e 1426 static const xmlChar*
pcercuei 0:03b5121a232e 1427 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
pcercuei 0:03b5121a232e 1428 {
pcercuei 0:03b5121a232e 1429 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 1430
pcercuei 0:03b5121a232e 1431 *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
pcercuei 0:03b5121a232e 1432 *buf = xmlStrcat(*buf, BAD_CAST " '");
pcercuei 0:03b5121a232e 1433 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
pcercuei 0:03b5121a232e 1434 (xmlSchemaBasicItemPtr) item));
pcercuei 0:03b5121a232e 1435 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1436 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 1437 return(*buf);
pcercuei 0:03b5121a232e 1438 }
pcercuei 0:03b5121a232e 1439
pcercuei 0:03b5121a232e 1440 static const xmlChar*
pcercuei 0:03b5121a232e 1441 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
pcercuei 0:03b5121a232e 1442 {
pcercuei 0:03b5121a232e 1443 return(xmlSchemaGetComponentDesignation(buf, idc));
pcercuei 0:03b5121a232e 1444 }
pcercuei 0:03b5121a232e 1445
pcercuei 0:03b5121a232e 1446 /**
pcercuei 0:03b5121a232e 1447 * xmlSchemaWildcardPCToString:
pcercuei 0:03b5121a232e 1448 * @pc: the type of processContents
pcercuei 0:03b5121a232e 1449 *
pcercuei 0:03b5121a232e 1450 * Returns a string representation of the type of
pcercuei 0:03b5121a232e 1451 * processContents.
pcercuei 0:03b5121a232e 1452 */
pcercuei 0:03b5121a232e 1453 static const xmlChar *
pcercuei 0:03b5121a232e 1454 xmlSchemaWildcardPCToString(int pc)
pcercuei 0:03b5121a232e 1455 {
pcercuei 0:03b5121a232e 1456 switch (pc) {
pcercuei 0:03b5121a232e 1457 case XML_SCHEMAS_ANY_SKIP:
pcercuei 0:03b5121a232e 1458 return (BAD_CAST "skip");
pcercuei 0:03b5121a232e 1459 case XML_SCHEMAS_ANY_LAX:
pcercuei 0:03b5121a232e 1460 return (BAD_CAST "lax");
pcercuei 0:03b5121a232e 1461 case XML_SCHEMAS_ANY_STRICT:
pcercuei 0:03b5121a232e 1462 return (BAD_CAST "strict");
pcercuei 0:03b5121a232e 1463 default:
pcercuei 0:03b5121a232e 1464 return (BAD_CAST "invalid process contents");
pcercuei 0:03b5121a232e 1465 }
pcercuei 0:03b5121a232e 1466 }
pcercuei 0:03b5121a232e 1467
pcercuei 0:03b5121a232e 1468 /**
pcercuei 0:03b5121a232e 1469 * xmlSchemaGetCanonValueWhtspExt:
pcercuei 0:03b5121a232e 1470 * @val: the precomputed value
pcercuei 0:03b5121a232e 1471 * @retValue: the returned value
pcercuei 0:03b5121a232e 1472 * @ws: the whitespace type of the value
pcercuei 0:03b5121a232e 1473 *
pcercuei 0:03b5121a232e 1474 * Get a the canonical representation of the value.
pcercuei 0:03b5121a232e 1475 * The caller has to free the returned retValue.
pcercuei 0:03b5121a232e 1476 *
pcercuei 0:03b5121a232e 1477 * Returns 0 if the value could be built and -1 in case of
pcercuei 0:03b5121a232e 1478 * API errors or if the value type is not supported yet.
pcercuei 0:03b5121a232e 1479 */
pcercuei 0:03b5121a232e 1480 static int
pcercuei 0:03b5121a232e 1481 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
pcercuei 0:03b5121a232e 1482 xmlSchemaWhitespaceValueType ws,
pcercuei 0:03b5121a232e 1483 xmlChar **retValue)
pcercuei 0:03b5121a232e 1484 {
pcercuei 0:03b5121a232e 1485 int list;
pcercuei 0:03b5121a232e 1486 xmlSchemaValType valType;
pcercuei 0:03b5121a232e 1487 const xmlChar *value, *value2 = NULL;
pcercuei 0:03b5121a232e 1488
pcercuei 0:03b5121a232e 1489
pcercuei 0:03b5121a232e 1490 if ((retValue == NULL) || (val == NULL))
pcercuei 0:03b5121a232e 1491 return (-1);
pcercuei 0:03b5121a232e 1492 list = xmlSchemaValueGetNext(val) ? 1 : 0;
pcercuei 0:03b5121a232e 1493 *retValue = NULL;
pcercuei 0:03b5121a232e 1494 do {
pcercuei 0:03b5121a232e 1495 value = NULL;
pcercuei 0:03b5121a232e 1496 valType = xmlSchemaGetValType(val);
pcercuei 0:03b5121a232e 1497 switch (valType) {
pcercuei 0:03b5121a232e 1498 case XML_SCHEMAS_STRING:
pcercuei 0:03b5121a232e 1499 case XML_SCHEMAS_NORMSTRING:
pcercuei 0:03b5121a232e 1500 case XML_SCHEMAS_ANYSIMPLETYPE:
pcercuei 0:03b5121a232e 1501 value = xmlSchemaValueGetAsString(val);
pcercuei 0:03b5121a232e 1502 if (value != NULL) {
pcercuei 0:03b5121a232e 1503 if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
pcercuei 0:03b5121a232e 1504 value2 = xmlSchemaCollapseString(value);
pcercuei 0:03b5121a232e 1505 else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
pcercuei 0:03b5121a232e 1506 value2 = xmlSchemaWhiteSpaceReplace(value);
pcercuei 0:03b5121a232e 1507 if (value2 != NULL)
pcercuei 0:03b5121a232e 1508 value = value2;
pcercuei 0:03b5121a232e 1509 }
pcercuei 0:03b5121a232e 1510 break;
pcercuei 0:03b5121a232e 1511 default:
pcercuei 0:03b5121a232e 1512 if (xmlSchemaGetCanonValue(val, &value2) == -1) {
pcercuei 0:03b5121a232e 1513 if (value2 != NULL)
pcercuei 0:03b5121a232e 1514 xmlFree((xmlChar *) value2);
pcercuei 0:03b5121a232e 1515 goto internal_error;
pcercuei 0:03b5121a232e 1516 }
pcercuei 0:03b5121a232e 1517 value = value2;
pcercuei 0:03b5121a232e 1518 }
pcercuei 0:03b5121a232e 1519 if (*retValue == NULL)
pcercuei 0:03b5121a232e 1520 if (value == NULL) {
pcercuei 0:03b5121a232e 1521 if (! list)
pcercuei 0:03b5121a232e 1522 *retValue = xmlStrdup(BAD_CAST "");
pcercuei 0:03b5121a232e 1523 } else
pcercuei 0:03b5121a232e 1524 *retValue = xmlStrdup(value);
pcercuei 0:03b5121a232e 1525 else if (value != NULL) {
pcercuei 0:03b5121a232e 1526 /* List. */
pcercuei 0:03b5121a232e 1527 *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
pcercuei 0:03b5121a232e 1528 *retValue = xmlStrcat((xmlChar *) *retValue, value);
pcercuei 0:03b5121a232e 1529 }
pcercuei 0:03b5121a232e 1530 FREE_AND_NULL(value2)
pcercuei 0:03b5121a232e 1531 val = xmlSchemaValueGetNext(val);
pcercuei 0:03b5121a232e 1532 } while (val != NULL);
pcercuei 0:03b5121a232e 1533
pcercuei 0:03b5121a232e 1534 return (0);
pcercuei 0:03b5121a232e 1535 internal_error:
pcercuei 0:03b5121a232e 1536 if (*retValue != NULL)
pcercuei 0:03b5121a232e 1537 xmlFree((xmlChar *) (*retValue));
pcercuei 0:03b5121a232e 1538 if (value2 != NULL)
pcercuei 0:03b5121a232e 1539 xmlFree((xmlChar *) value2);
pcercuei 0:03b5121a232e 1540 return (-1);
pcercuei 0:03b5121a232e 1541 }
pcercuei 0:03b5121a232e 1542
pcercuei 0:03b5121a232e 1543 /**
pcercuei 0:03b5121a232e 1544 * xmlSchemaFormatItemForReport:
pcercuei 0:03b5121a232e 1545 * @buf: the string buffer
pcercuei 0:03b5121a232e 1546 * @itemDes: the designation of the item
pcercuei 0:03b5121a232e 1547 * @itemName: the name of the item
pcercuei 0:03b5121a232e 1548 * @item: the item as an object
pcercuei 0:03b5121a232e 1549 * @itemNode: the node of the item
pcercuei 0:03b5121a232e 1550 * @local: the local name
pcercuei 0:03b5121a232e 1551 * @parsing: if the function is used during the parse
pcercuei 0:03b5121a232e 1552 *
pcercuei 0:03b5121a232e 1553 * Returns a representation of the given item used
pcercuei 0:03b5121a232e 1554 * for error reports.
pcercuei 0:03b5121a232e 1555 *
pcercuei 0:03b5121a232e 1556 * The following order is used to build the resulting
pcercuei 0:03b5121a232e 1557 * designation if the arguments are not NULL:
pcercuei 0:03b5121a232e 1558 * 1a. If itemDes not NULL -> itemDes
pcercuei 0:03b5121a232e 1559 * 1b. If (itemDes not NULL) and (itemName not NULL)
pcercuei 0:03b5121a232e 1560 * -> itemDes + itemName
pcercuei 0:03b5121a232e 1561 * 2. If the preceding was NULL and (item not NULL) -> item
pcercuei 0:03b5121a232e 1562 * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
pcercuei 0:03b5121a232e 1563 *
pcercuei 0:03b5121a232e 1564 * If the itemNode is an attribute node, the name of the attribute
pcercuei 0:03b5121a232e 1565 * will be appended to the result.
pcercuei 0:03b5121a232e 1566 *
pcercuei 0:03b5121a232e 1567 * Returns the formatted string and sets @buf to the resulting value.
pcercuei 0:03b5121a232e 1568 */
pcercuei 0:03b5121a232e 1569 static xmlChar*
pcercuei 0:03b5121a232e 1570 xmlSchemaFormatItemForReport(xmlChar **buf,
pcercuei 0:03b5121a232e 1571 const xmlChar *itemDes,
pcercuei 0:03b5121a232e 1572 xmlSchemaBasicItemPtr item,
pcercuei 0:03b5121a232e 1573 xmlNodePtr itemNode)
pcercuei 0:03b5121a232e 1574 {
pcercuei 0:03b5121a232e 1575 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 1576 int named = 1;
pcercuei 0:03b5121a232e 1577
pcercuei 0:03b5121a232e 1578 if (*buf != NULL) {
pcercuei 0:03b5121a232e 1579 xmlFree(*buf);
pcercuei 0:03b5121a232e 1580 *buf = NULL;
pcercuei 0:03b5121a232e 1581 }
pcercuei 0:03b5121a232e 1582
pcercuei 0:03b5121a232e 1583 if (itemDes != NULL) {
pcercuei 0:03b5121a232e 1584 *buf = xmlStrdup(itemDes);
pcercuei 0:03b5121a232e 1585 } else if (item != NULL) {
pcercuei 0:03b5121a232e 1586 switch (item->type) {
pcercuei 0:03b5121a232e 1587 case XML_SCHEMA_TYPE_BASIC: {
pcercuei 0:03b5121a232e 1588 xmlSchemaTypePtr type = WXS_TYPE_CAST item;
pcercuei 0:03b5121a232e 1589
pcercuei 0:03b5121a232e 1590 if (WXS_IS_ATOMIC(type))
pcercuei 0:03b5121a232e 1591 *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
pcercuei 0:03b5121a232e 1592 else if (WXS_IS_LIST(type))
pcercuei 0:03b5121a232e 1593 *buf = xmlStrdup(BAD_CAST "list type 'xs:");
pcercuei 0:03b5121a232e 1594 else if (WXS_IS_UNION(type))
pcercuei 0:03b5121a232e 1595 *buf = xmlStrdup(BAD_CAST "union type 'xs:");
pcercuei 0:03b5121a232e 1596 else
pcercuei 0:03b5121a232e 1597 *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
pcercuei 0:03b5121a232e 1598 *buf = xmlStrcat(*buf, type->name);
pcercuei 0:03b5121a232e 1599 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1600 }
pcercuei 0:03b5121a232e 1601 break;
pcercuei 0:03b5121a232e 1602 case XML_SCHEMA_TYPE_SIMPLE: {
pcercuei 0:03b5121a232e 1603 xmlSchemaTypePtr type = WXS_TYPE_CAST item;
pcercuei 0:03b5121a232e 1604
pcercuei 0:03b5121a232e 1605 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
pcercuei 0:03b5121a232e 1606 *buf = xmlStrdup(BAD_CAST"");
pcercuei 0:03b5121a232e 1607 } else {
pcercuei 0:03b5121a232e 1608 *buf = xmlStrdup(BAD_CAST "local ");
pcercuei 0:03b5121a232e 1609 }
pcercuei 0:03b5121a232e 1610 if (WXS_IS_ATOMIC(type))
pcercuei 0:03b5121a232e 1611 *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
pcercuei 0:03b5121a232e 1612 else if (WXS_IS_LIST(type))
pcercuei 0:03b5121a232e 1613 *buf = xmlStrcat(*buf, BAD_CAST "list type");
pcercuei 0:03b5121a232e 1614 else if (WXS_IS_UNION(type))
pcercuei 0:03b5121a232e 1615 *buf = xmlStrcat(*buf, BAD_CAST "union type");
pcercuei 0:03b5121a232e 1616 else
pcercuei 0:03b5121a232e 1617 *buf = xmlStrcat(*buf, BAD_CAST "simple type");
pcercuei 0:03b5121a232e 1618 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
pcercuei 0:03b5121a232e 1619 *buf = xmlStrcat(*buf, BAD_CAST " '");
pcercuei 0:03b5121a232e 1620 *buf = xmlStrcat(*buf, type->name);
pcercuei 0:03b5121a232e 1621 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1622 }
pcercuei 0:03b5121a232e 1623 }
pcercuei 0:03b5121a232e 1624 break;
pcercuei 0:03b5121a232e 1625 case XML_SCHEMA_TYPE_COMPLEX: {
pcercuei 0:03b5121a232e 1626 xmlSchemaTypePtr type = WXS_TYPE_CAST item;
pcercuei 0:03b5121a232e 1627
pcercuei 0:03b5121a232e 1628 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
pcercuei 0:03b5121a232e 1629 *buf = xmlStrdup(BAD_CAST "");
pcercuei 0:03b5121a232e 1630 else
pcercuei 0:03b5121a232e 1631 *buf = xmlStrdup(BAD_CAST "local ");
pcercuei 0:03b5121a232e 1632 *buf = xmlStrcat(*buf, BAD_CAST "complex type");
pcercuei 0:03b5121a232e 1633 if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
pcercuei 0:03b5121a232e 1634 *buf = xmlStrcat(*buf, BAD_CAST " '");
pcercuei 0:03b5121a232e 1635 *buf = xmlStrcat(*buf, type->name);
pcercuei 0:03b5121a232e 1636 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1637 }
pcercuei 0:03b5121a232e 1638 }
pcercuei 0:03b5121a232e 1639 break;
pcercuei 0:03b5121a232e 1640 case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
pcercuei 0:03b5121a232e 1641 xmlSchemaAttributeUsePtr ause;
pcercuei 0:03b5121a232e 1642
pcercuei 0:03b5121a232e 1643 ause = WXS_ATTR_USE_CAST item;
pcercuei 0:03b5121a232e 1644 *buf = xmlStrdup(BAD_CAST "attribute use ");
pcercuei 0:03b5121a232e 1645 if (WXS_ATTRUSE_DECL(ause) != NULL) {
pcercuei 0:03b5121a232e 1646 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1647 *buf = xmlStrcat(*buf,
pcercuei 0:03b5121a232e 1648 xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
pcercuei 0:03b5121a232e 1649 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 1650 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1651 } else {
pcercuei 0:03b5121a232e 1652 *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
pcercuei 0:03b5121a232e 1653 }
pcercuei 0:03b5121a232e 1654 }
pcercuei 0:03b5121a232e 1655 break;
pcercuei 0:03b5121a232e 1656 case XML_SCHEMA_TYPE_ATTRIBUTE: {
pcercuei 0:03b5121a232e 1657 xmlSchemaAttributePtr attr;
pcercuei 0:03b5121a232e 1658
pcercuei 0:03b5121a232e 1659 attr = (xmlSchemaAttributePtr) item;
pcercuei 0:03b5121a232e 1660 *buf = xmlStrdup(BAD_CAST "attribute decl.");
pcercuei 0:03b5121a232e 1661 *buf = xmlStrcat(*buf, BAD_CAST " '");
pcercuei 0:03b5121a232e 1662 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 1663 attr->targetNamespace, attr->name));
pcercuei 0:03b5121a232e 1664 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 1665 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1666 }
pcercuei 0:03b5121a232e 1667 break;
pcercuei 0:03b5121a232e 1668 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 1669 xmlSchemaGetComponentDesignation(buf, item);
pcercuei 0:03b5121a232e 1670 break;
pcercuei 0:03b5121a232e 1671 case XML_SCHEMA_TYPE_ELEMENT: {
pcercuei 0:03b5121a232e 1672 xmlSchemaElementPtr elem;
pcercuei 0:03b5121a232e 1673
pcercuei 0:03b5121a232e 1674 elem = (xmlSchemaElementPtr) item;
pcercuei 0:03b5121a232e 1675 *buf = xmlStrdup(BAD_CAST "element decl.");
pcercuei 0:03b5121a232e 1676 *buf = xmlStrcat(*buf, BAD_CAST " '");
pcercuei 0:03b5121a232e 1677 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 1678 elem->targetNamespace, elem->name));
pcercuei 0:03b5121a232e 1679 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1680 }
pcercuei 0:03b5121a232e 1681 break;
pcercuei 0:03b5121a232e 1682 case XML_SCHEMA_TYPE_IDC_UNIQUE:
pcercuei 0:03b5121a232e 1683 case XML_SCHEMA_TYPE_IDC_KEY:
pcercuei 0:03b5121a232e 1684 case XML_SCHEMA_TYPE_IDC_KEYREF:
pcercuei 0:03b5121a232e 1685 if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
pcercuei 0:03b5121a232e 1686 *buf = xmlStrdup(BAD_CAST "unique '");
pcercuei 0:03b5121a232e 1687 else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
pcercuei 0:03b5121a232e 1688 *buf = xmlStrdup(BAD_CAST "key '");
pcercuei 0:03b5121a232e 1689 else
pcercuei 0:03b5121a232e 1690 *buf = xmlStrdup(BAD_CAST "keyRef '");
pcercuei 0:03b5121a232e 1691 *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
pcercuei 0:03b5121a232e 1692 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1693 break;
pcercuei 0:03b5121a232e 1694 case XML_SCHEMA_TYPE_ANY:
pcercuei 0:03b5121a232e 1695 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
pcercuei 0:03b5121a232e 1696 *buf = xmlStrdup(xmlSchemaWildcardPCToString(
pcercuei 0:03b5121a232e 1697 ((xmlSchemaWildcardPtr) item)->processContents));
pcercuei 0:03b5121a232e 1698 *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
pcercuei 0:03b5121a232e 1699 break;
pcercuei 0:03b5121a232e 1700 case XML_SCHEMA_FACET_MININCLUSIVE:
pcercuei 0:03b5121a232e 1701 case XML_SCHEMA_FACET_MINEXCLUSIVE:
pcercuei 0:03b5121a232e 1702 case XML_SCHEMA_FACET_MAXINCLUSIVE:
pcercuei 0:03b5121a232e 1703 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
pcercuei 0:03b5121a232e 1704 case XML_SCHEMA_FACET_TOTALDIGITS:
pcercuei 0:03b5121a232e 1705 case XML_SCHEMA_FACET_FRACTIONDIGITS:
pcercuei 0:03b5121a232e 1706 case XML_SCHEMA_FACET_PATTERN:
pcercuei 0:03b5121a232e 1707 case XML_SCHEMA_FACET_ENUMERATION:
pcercuei 0:03b5121a232e 1708 case XML_SCHEMA_FACET_WHITESPACE:
pcercuei 0:03b5121a232e 1709 case XML_SCHEMA_FACET_LENGTH:
pcercuei 0:03b5121a232e 1710 case XML_SCHEMA_FACET_MAXLENGTH:
pcercuei 0:03b5121a232e 1711 case XML_SCHEMA_FACET_MINLENGTH:
pcercuei 0:03b5121a232e 1712 *buf = xmlStrdup(BAD_CAST "facet '");
pcercuei 0:03b5121a232e 1713 *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
pcercuei 0:03b5121a232e 1714 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1715 break;
pcercuei 0:03b5121a232e 1716 case XML_SCHEMA_TYPE_GROUP: {
pcercuei 0:03b5121a232e 1717 *buf = xmlStrdup(BAD_CAST "model group def.");
pcercuei 0:03b5121a232e 1718 *buf = xmlStrcat(*buf, BAD_CAST " '");
pcercuei 0:03b5121a232e 1719 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
pcercuei 0:03b5121a232e 1720 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1721 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 1722 }
pcercuei 0:03b5121a232e 1723 break;
pcercuei 0:03b5121a232e 1724 case XML_SCHEMA_TYPE_SEQUENCE:
pcercuei 0:03b5121a232e 1725 case XML_SCHEMA_TYPE_CHOICE:
pcercuei 0:03b5121a232e 1726 case XML_SCHEMA_TYPE_ALL:
pcercuei 0:03b5121a232e 1727 case XML_SCHEMA_TYPE_PARTICLE:
pcercuei 0:03b5121a232e 1728 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
pcercuei 0:03b5121a232e 1729 break;
pcercuei 0:03b5121a232e 1730 case XML_SCHEMA_TYPE_NOTATION: {
pcercuei 0:03b5121a232e 1731 *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
pcercuei 0:03b5121a232e 1732 *buf = xmlStrcat(*buf, BAD_CAST " '");
pcercuei 0:03b5121a232e 1733 *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
pcercuei 0:03b5121a232e 1734 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1735 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 1736 }
pcercuei 0:03b5121a232e 1737 default:
pcercuei 0:03b5121a232e 1738 named = 0;
pcercuei 0:03b5121a232e 1739 }
pcercuei 0:03b5121a232e 1740 } else
pcercuei 0:03b5121a232e 1741 named = 0;
pcercuei 0:03b5121a232e 1742
pcercuei 0:03b5121a232e 1743 if ((named == 0) && (itemNode != NULL)) {
pcercuei 0:03b5121a232e 1744 xmlNodePtr elem;
pcercuei 0:03b5121a232e 1745
pcercuei 0:03b5121a232e 1746 if (itemNode->type == XML_ATTRIBUTE_NODE)
pcercuei 0:03b5121a232e 1747 elem = itemNode->parent;
pcercuei 0:03b5121a232e 1748 else
pcercuei 0:03b5121a232e 1749 elem = itemNode;
pcercuei 0:03b5121a232e 1750 *buf = xmlStrdup(BAD_CAST "Element '");
pcercuei 0:03b5121a232e 1751 if (elem->ns != NULL) {
pcercuei 0:03b5121a232e 1752 *buf = xmlStrcat(*buf,
pcercuei 0:03b5121a232e 1753 xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
pcercuei 0:03b5121a232e 1754 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 1755 } else
pcercuei 0:03b5121a232e 1756 *buf = xmlStrcat(*buf, elem->name);
pcercuei 0:03b5121a232e 1757 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1758
pcercuei 0:03b5121a232e 1759 }
pcercuei 0:03b5121a232e 1760 if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
pcercuei 0:03b5121a232e 1761 *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
pcercuei 0:03b5121a232e 1762 if (itemNode->ns != NULL) {
pcercuei 0:03b5121a232e 1763 *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 1764 itemNode->ns->href, itemNode->name));
pcercuei 0:03b5121a232e 1765 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 1766 } else
pcercuei 0:03b5121a232e 1767 *buf = xmlStrcat(*buf, itemNode->name);
pcercuei 0:03b5121a232e 1768 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1769 }
pcercuei 0:03b5121a232e 1770 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 1771
pcercuei 0:03b5121a232e 1772 return (*buf);
pcercuei 0:03b5121a232e 1773 }
pcercuei 0:03b5121a232e 1774
pcercuei 0:03b5121a232e 1775 /**
pcercuei 0:03b5121a232e 1776 * xmlSchemaFormatFacetEnumSet:
pcercuei 0:03b5121a232e 1777 * @buf: the string buffer
pcercuei 0:03b5121a232e 1778 * @type: the type holding the enumeration facets
pcercuei 0:03b5121a232e 1779 *
pcercuei 0:03b5121a232e 1780 * Builds a string consisting of all enumeration elements.
pcercuei 0:03b5121a232e 1781 *
pcercuei 0:03b5121a232e 1782 * Returns a string of all enumeration elements.
pcercuei 0:03b5121a232e 1783 */
pcercuei 0:03b5121a232e 1784 static const xmlChar *
pcercuei 0:03b5121a232e 1785 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 1786 xmlChar **buf, xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 1787 {
pcercuei 0:03b5121a232e 1788 xmlSchemaFacetPtr facet;
pcercuei 0:03b5121a232e 1789 xmlSchemaWhitespaceValueType ws;
pcercuei 0:03b5121a232e 1790 xmlChar *value = NULL;
pcercuei 0:03b5121a232e 1791 int res, found = 0;
pcercuei 0:03b5121a232e 1792
pcercuei 0:03b5121a232e 1793 if (*buf != NULL)
pcercuei 0:03b5121a232e 1794 xmlFree(*buf);
pcercuei 0:03b5121a232e 1795 *buf = NULL;
pcercuei 0:03b5121a232e 1796
pcercuei 0:03b5121a232e 1797 do {
pcercuei 0:03b5121a232e 1798 /*
pcercuei 0:03b5121a232e 1799 * Use the whitespace type of the base type.
pcercuei 0:03b5121a232e 1800 */
pcercuei 0:03b5121a232e 1801 ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
pcercuei 0:03b5121a232e 1802 for (facet = type->facets; facet != NULL; facet = facet->next) {
pcercuei 0:03b5121a232e 1803 if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
pcercuei 0:03b5121a232e 1804 continue;
pcercuei 0:03b5121a232e 1805 found = 1;
pcercuei 0:03b5121a232e 1806 res = xmlSchemaGetCanonValueWhtspExt(facet->val,
pcercuei 0:03b5121a232e 1807 ws, &value);
pcercuei 0:03b5121a232e 1808 if (res == -1) {
pcercuei 0:03b5121a232e 1809 xmlSchemaInternalErr(actxt,
pcercuei 0:03b5121a232e 1810 "xmlSchemaFormatFacetEnumSet",
pcercuei 0:03b5121a232e 1811 "compute the canonical lexical representation");
pcercuei 0:03b5121a232e 1812 if (*buf != NULL)
pcercuei 0:03b5121a232e 1813 xmlFree(*buf);
pcercuei 0:03b5121a232e 1814 *buf = NULL;
pcercuei 0:03b5121a232e 1815 return (NULL);
pcercuei 0:03b5121a232e 1816 }
pcercuei 0:03b5121a232e 1817 if (*buf == NULL)
pcercuei 0:03b5121a232e 1818 *buf = xmlStrdup(BAD_CAST "'");
pcercuei 0:03b5121a232e 1819 else
pcercuei 0:03b5121a232e 1820 *buf = xmlStrcat(*buf, BAD_CAST ", '");
pcercuei 0:03b5121a232e 1821 *buf = xmlStrcat(*buf, BAD_CAST value);
pcercuei 0:03b5121a232e 1822 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 1823 if (value != NULL) {
pcercuei 0:03b5121a232e 1824 xmlFree((xmlChar *)value);
pcercuei 0:03b5121a232e 1825 value = NULL;
pcercuei 0:03b5121a232e 1826 }
pcercuei 0:03b5121a232e 1827 }
pcercuei 0:03b5121a232e 1828 /*
pcercuei 0:03b5121a232e 1829 * The enumeration facet of a type restricts the enumeration
pcercuei 0:03b5121a232e 1830 * facet of the ancestor type; i.e., such restricted enumerations
pcercuei 0:03b5121a232e 1831 * do not belong to the set of the given type. Thus we break
pcercuei 0:03b5121a232e 1832 * on the first found enumeration.
pcercuei 0:03b5121a232e 1833 */
pcercuei 0:03b5121a232e 1834 if (found)
pcercuei 0:03b5121a232e 1835 break;
pcercuei 0:03b5121a232e 1836 type = type->baseType;
pcercuei 0:03b5121a232e 1837 } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
pcercuei 0:03b5121a232e 1838
pcercuei 0:03b5121a232e 1839 return ((const xmlChar *) *buf);
pcercuei 0:03b5121a232e 1840 }
pcercuei 0:03b5121a232e 1841
pcercuei 0:03b5121a232e 1842 /************************************************************************
pcercuei 0:03b5121a232e 1843 * *
pcercuei 0:03b5121a232e 1844 * Error functions *
pcercuei 0:03b5121a232e 1845 * *
pcercuei 0:03b5121a232e 1846 ************************************************************************/
pcercuei 0:03b5121a232e 1847
pcercuei 0:03b5121a232e 1848 #if 0
pcercuei 0:03b5121a232e 1849 static void
pcercuei 0:03b5121a232e 1850 xmlSchemaErrMemory(const char *msg)
pcercuei 0:03b5121a232e 1851 {
pcercuei 0:03b5121a232e 1852 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
pcercuei 0:03b5121a232e 1853 msg);
pcercuei 0:03b5121a232e 1854 }
pcercuei 0:03b5121a232e 1855 #endif
pcercuei 0:03b5121a232e 1856
pcercuei 0:03b5121a232e 1857 static void
pcercuei 0:03b5121a232e 1858 xmlSchemaPSimpleErr(const char *msg)
pcercuei 0:03b5121a232e 1859 {
pcercuei 0:03b5121a232e 1860 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
pcercuei 0:03b5121a232e 1861 msg);
pcercuei 0:03b5121a232e 1862 }
pcercuei 0:03b5121a232e 1863
pcercuei 0:03b5121a232e 1864 /**
pcercuei 0:03b5121a232e 1865 * xmlSchemaPErrMemory:
pcercuei 0:03b5121a232e 1866 * @node: a context node
pcercuei 0:03b5121a232e 1867 * @extra: extra informations
pcercuei 0:03b5121a232e 1868 *
pcercuei 0:03b5121a232e 1869 * Handle an out of memory condition
pcercuei 0:03b5121a232e 1870 */
pcercuei 0:03b5121a232e 1871 static void
pcercuei 0:03b5121a232e 1872 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 1873 const char *extra, xmlNodePtr node)
pcercuei 0:03b5121a232e 1874 {
pcercuei 0:03b5121a232e 1875 if (ctxt != NULL)
pcercuei 0:03b5121a232e 1876 ctxt->nberrors++;
pcercuei 0:03b5121a232e 1877 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
pcercuei 0:03b5121a232e 1878 extra);
pcercuei 0:03b5121a232e 1879 }
pcercuei 0:03b5121a232e 1880
pcercuei 0:03b5121a232e 1881 /**
pcercuei 0:03b5121a232e 1882 * xmlSchemaPErr:
pcercuei 0:03b5121a232e 1883 * @ctxt: the parsing context
pcercuei 0:03b5121a232e 1884 * @node: the context node
pcercuei 0:03b5121a232e 1885 * @error: the error code
pcercuei 0:03b5121a232e 1886 * @msg: the error message
pcercuei 0:03b5121a232e 1887 * @str1: extra data
pcercuei 0:03b5121a232e 1888 * @str2: extra data
pcercuei 0:03b5121a232e 1889 *
pcercuei 0:03b5121a232e 1890 * Handle a parser error
pcercuei 0:03b5121a232e 1891 */
pcercuei 0:03b5121a232e 1892 static void
pcercuei 0:03b5121a232e 1893 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
pcercuei 0:03b5121a232e 1894 const char *msg, const xmlChar * str1, const xmlChar * str2)
pcercuei 0:03b5121a232e 1895 {
pcercuei 0:03b5121a232e 1896 xmlGenericErrorFunc channel = NULL;
pcercuei 0:03b5121a232e 1897 xmlStructuredErrorFunc schannel = NULL;
pcercuei 0:03b5121a232e 1898 void *data = NULL;
pcercuei 0:03b5121a232e 1899
pcercuei 0:03b5121a232e 1900 if (ctxt != NULL) {
pcercuei 0:03b5121a232e 1901 ctxt->nberrors++;
pcercuei 0:03b5121a232e 1902 ctxt->err = error;
pcercuei 0:03b5121a232e 1903 channel = ctxt->error;
pcercuei 0:03b5121a232e 1904 data = ctxt->errCtxt;
pcercuei 0:03b5121a232e 1905 schannel = ctxt->serror;
pcercuei 0:03b5121a232e 1906 }
pcercuei 0:03b5121a232e 1907 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
pcercuei 0:03b5121a232e 1908 error, XML_ERR_ERROR, NULL, 0,
pcercuei 0:03b5121a232e 1909 (const char *) str1, (const char *) str2, NULL, 0, 0,
pcercuei 0:03b5121a232e 1910 msg, str1, str2);
pcercuei 0:03b5121a232e 1911 }
pcercuei 0:03b5121a232e 1912
pcercuei 0:03b5121a232e 1913 /**
pcercuei 0:03b5121a232e 1914 * xmlSchemaPErr2:
pcercuei 0:03b5121a232e 1915 * @ctxt: the parsing context
pcercuei 0:03b5121a232e 1916 * @node: the context node
pcercuei 0:03b5121a232e 1917 * @node: the current child
pcercuei 0:03b5121a232e 1918 * @error: the error code
pcercuei 0:03b5121a232e 1919 * @msg: the error message
pcercuei 0:03b5121a232e 1920 * @str1: extra data
pcercuei 0:03b5121a232e 1921 * @str2: extra data
pcercuei 0:03b5121a232e 1922 *
pcercuei 0:03b5121a232e 1923 * Handle a parser error
pcercuei 0:03b5121a232e 1924 */
pcercuei 0:03b5121a232e 1925 static void
pcercuei 0:03b5121a232e 1926 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
pcercuei 0:03b5121a232e 1927 xmlNodePtr child, int error,
pcercuei 0:03b5121a232e 1928 const char *msg, const xmlChar * str1, const xmlChar * str2)
pcercuei 0:03b5121a232e 1929 {
pcercuei 0:03b5121a232e 1930 if (child != NULL)
pcercuei 0:03b5121a232e 1931 xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
pcercuei 0:03b5121a232e 1932 else
pcercuei 0:03b5121a232e 1933 xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
pcercuei 0:03b5121a232e 1934 }
pcercuei 0:03b5121a232e 1935
pcercuei 0:03b5121a232e 1936
pcercuei 0:03b5121a232e 1937 /**
pcercuei 0:03b5121a232e 1938 * xmlSchemaPErrExt:
pcercuei 0:03b5121a232e 1939 * @ctxt: the parsing context
pcercuei 0:03b5121a232e 1940 * @node: the context node
pcercuei 0:03b5121a232e 1941 * @error: the error code
pcercuei 0:03b5121a232e 1942 * @strData1: extra data
pcercuei 0:03b5121a232e 1943 * @strData2: extra data
pcercuei 0:03b5121a232e 1944 * @strData3: extra data
pcercuei 0:03b5121a232e 1945 * @msg: the message
pcercuei 0:03b5121a232e 1946 * @str1: extra parameter for the message display
pcercuei 0:03b5121a232e 1947 * @str2: extra parameter for the message display
pcercuei 0:03b5121a232e 1948 * @str3: extra parameter for the message display
pcercuei 0:03b5121a232e 1949 * @str4: extra parameter for the message display
pcercuei 0:03b5121a232e 1950 * @str5: extra parameter for the message display
pcercuei 0:03b5121a232e 1951 *
pcercuei 0:03b5121a232e 1952 * Handle a parser error
pcercuei 0:03b5121a232e 1953 */
pcercuei 0:03b5121a232e 1954 static void
pcercuei 0:03b5121a232e 1955 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
pcercuei 0:03b5121a232e 1956 const xmlChar * strData1, const xmlChar * strData2,
pcercuei 0:03b5121a232e 1957 const xmlChar * strData3, const char *msg, const xmlChar * str1,
pcercuei 0:03b5121a232e 1958 const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
pcercuei 0:03b5121a232e 1959 const xmlChar * str5)
pcercuei 0:03b5121a232e 1960 {
pcercuei 0:03b5121a232e 1961
pcercuei 0:03b5121a232e 1962 xmlGenericErrorFunc channel = NULL;
pcercuei 0:03b5121a232e 1963 xmlStructuredErrorFunc schannel = NULL;
pcercuei 0:03b5121a232e 1964 void *data = NULL;
pcercuei 0:03b5121a232e 1965
pcercuei 0:03b5121a232e 1966 if (ctxt != NULL) {
pcercuei 0:03b5121a232e 1967 ctxt->nberrors++;
pcercuei 0:03b5121a232e 1968 ctxt->err = error;
pcercuei 0:03b5121a232e 1969 channel = ctxt->error;
pcercuei 0:03b5121a232e 1970 data = ctxt->errCtxt;
pcercuei 0:03b5121a232e 1971 schannel = ctxt->serror;
pcercuei 0:03b5121a232e 1972 }
pcercuei 0:03b5121a232e 1973 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
pcercuei 0:03b5121a232e 1974 error, XML_ERR_ERROR, NULL, 0,
pcercuei 0:03b5121a232e 1975 (const char *) strData1, (const char *) strData2,
pcercuei 0:03b5121a232e 1976 (const char *) strData3, 0, 0, msg, str1, str2,
pcercuei 0:03b5121a232e 1977 str3, str4, str5);
pcercuei 0:03b5121a232e 1978 }
pcercuei 0:03b5121a232e 1979
pcercuei 0:03b5121a232e 1980 /************************************************************************
pcercuei 0:03b5121a232e 1981 * *
pcercuei 0:03b5121a232e 1982 * Allround error functions *
pcercuei 0:03b5121a232e 1983 * *
pcercuei 0:03b5121a232e 1984 ************************************************************************/
pcercuei 0:03b5121a232e 1985
pcercuei 0:03b5121a232e 1986 /**
pcercuei 0:03b5121a232e 1987 * xmlSchemaVTypeErrMemory:
pcercuei 0:03b5121a232e 1988 * @node: a context node
pcercuei 0:03b5121a232e 1989 * @extra: extra informations
pcercuei 0:03b5121a232e 1990 *
pcercuei 0:03b5121a232e 1991 * Handle an out of memory condition
pcercuei 0:03b5121a232e 1992 */
pcercuei 0:03b5121a232e 1993 static void
pcercuei 0:03b5121a232e 1994 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
pcercuei 0:03b5121a232e 1995 const char *extra, xmlNodePtr node)
pcercuei 0:03b5121a232e 1996 {
pcercuei 0:03b5121a232e 1997 if (ctxt != NULL) {
pcercuei 0:03b5121a232e 1998 ctxt->nberrors++;
pcercuei 0:03b5121a232e 1999 ctxt->err = XML_SCHEMAV_INTERNAL;
pcercuei 0:03b5121a232e 2000 }
pcercuei 0:03b5121a232e 2001 __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
pcercuei 0:03b5121a232e 2002 extra);
pcercuei 0:03b5121a232e 2003 }
pcercuei 0:03b5121a232e 2004
pcercuei 0:03b5121a232e 2005 static void
pcercuei 0:03b5121a232e 2006 xmlSchemaPSimpleInternalErr(xmlNodePtr node,
pcercuei 0:03b5121a232e 2007 const char *msg, const xmlChar *str)
pcercuei 0:03b5121a232e 2008 {
pcercuei 0:03b5121a232e 2009 __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
pcercuei 0:03b5121a232e 2010 msg, (const char *) str);
pcercuei 0:03b5121a232e 2011 }
pcercuei 0:03b5121a232e 2012
pcercuei 0:03b5121a232e 2013 #define WXS_ERROR_TYPE_ERROR 1
pcercuei 0:03b5121a232e 2014 #define WXS_ERROR_TYPE_WARNING 2
pcercuei 0:03b5121a232e 2015 /**
pcercuei 0:03b5121a232e 2016 * xmlSchemaErr3:
pcercuei 0:03b5121a232e 2017 * @ctxt: the validation context
pcercuei 0:03b5121a232e 2018 * @node: the context node
pcercuei 0:03b5121a232e 2019 * @error: the error code
pcercuei 0:03b5121a232e 2020 * @msg: the error message
pcercuei 0:03b5121a232e 2021 * @str1: extra data
pcercuei 0:03b5121a232e 2022 * @str2: extra data
pcercuei 0:03b5121a232e 2023 * @str3: extra data
pcercuei 0:03b5121a232e 2024 *
pcercuei 0:03b5121a232e 2025 * Handle a validation error
pcercuei 0:03b5121a232e 2026 */
pcercuei 0:03b5121a232e 2027 static void
pcercuei 0:03b5121a232e 2028 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
pcercuei 0:03b5121a232e 2029 xmlErrorLevel errorLevel,
pcercuei 0:03b5121a232e 2030 int error, xmlNodePtr node, int line, const char *msg,
pcercuei 0:03b5121a232e 2031 const xmlChar *str1, const xmlChar *str2,
pcercuei 0:03b5121a232e 2032 const xmlChar *str3, const xmlChar *str4)
pcercuei 0:03b5121a232e 2033 {
pcercuei 0:03b5121a232e 2034 xmlStructuredErrorFunc schannel = NULL;
pcercuei 0:03b5121a232e 2035 xmlGenericErrorFunc channel = NULL;
pcercuei 0:03b5121a232e 2036 void *data = NULL;
pcercuei 0:03b5121a232e 2037
pcercuei 0:03b5121a232e 2038 if (ctxt != NULL) {
pcercuei 0:03b5121a232e 2039 if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
pcercuei 0:03b5121a232e 2040 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
pcercuei 0:03b5121a232e 2041 const char *file = NULL;
pcercuei 0:03b5121a232e 2042 int col = 0;
pcercuei 0:03b5121a232e 2043 if (errorLevel != XML_ERR_WARNING) {
pcercuei 0:03b5121a232e 2044 vctxt->nberrors++;
pcercuei 0:03b5121a232e 2045 vctxt->err = error;
pcercuei 0:03b5121a232e 2046 channel = vctxt->error;
pcercuei 0:03b5121a232e 2047 } else {
pcercuei 0:03b5121a232e 2048 channel = vctxt->warning;
pcercuei 0:03b5121a232e 2049 }
pcercuei 0:03b5121a232e 2050 schannel = vctxt->serror;
pcercuei 0:03b5121a232e 2051 data = vctxt->errCtxt;
pcercuei 0:03b5121a232e 2052
pcercuei 0:03b5121a232e 2053 /*
pcercuei 0:03b5121a232e 2054 * Error node. If we specify a line number, then
pcercuei 0:03b5121a232e 2055 * do not channel any node to the error function.
pcercuei 0:03b5121a232e 2056 */
pcercuei 0:03b5121a232e 2057 if (line == 0) {
pcercuei 0:03b5121a232e 2058 if ((node == NULL) &&
pcercuei 0:03b5121a232e 2059 (vctxt->depth >= 0) &&
pcercuei 0:03b5121a232e 2060 (vctxt->inode != NULL)) {
pcercuei 0:03b5121a232e 2061 node = vctxt->inode->node;
pcercuei 0:03b5121a232e 2062 }
pcercuei 0:03b5121a232e 2063 /*
pcercuei 0:03b5121a232e 2064 * Get filename and line if no node-tree.
pcercuei 0:03b5121a232e 2065 */
pcercuei 0:03b5121a232e 2066 if ((node == NULL) &&
pcercuei 0:03b5121a232e 2067 (vctxt->parserCtxt != NULL) &&
pcercuei 0:03b5121a232e 2068 (vctxt->parserCtxt->input != NULL)) {
pcercuei 0:03b5121a232e 2069 file = vctxt->parserCtxt->input->filename;
pcercuei 0:03b5121a232e 2070 line = vctxt->parserCtxt->input->line;
pcercuei 0:03b5121a232e 2071 col = vctxt->parserCtxt->input->col;
pcercuei 0:03b5121a232e 2072 }
pcercuei 0:03b5121a232e 2073 } else {
pcercuei 0:03b5121a232e 2074 /*
pcercuei 0:03b5121a232e 2075 * Override the given node's (if any) position
pcercuei 0:03b5121a232e 2076 * and channel only the given line number.
pcercuei 0:03b5121a232e 2077 */
pcercuei 0:03b5121a232e 2078 node = NULL;
pcercuei 0:03b5121a232e 2079 /*
pcercuei 0:03b5121a232e 2080 * Get filename.
pcercuei 0:03b5121a232e 2081 */
pcercuei 0:03b5121a232e 2082 if (vctxt->doc != NULL)
pcercuei 0:03b5121a232e 2083 file = (const char *) vctxt->doc->URL;
pcercuei 0:03b5121a232e 2084 else if ((vctxt->parserCtxt != NULL) &&
pcercuei 0:03b5121a232e 2085 (vctxt->parserCtxt->input != NULL))
pcercuei 0:03b5121a232e 2086 file = vctxt->parserCtxt->input->filename;
pcercuei 0:03b5121a232e 2087 }
pcercuei 0:03b5121a232e 2088 if (vctxt->locFunc != NULL) {
pcercuei 0:03b5121a232e 2089 if ((file == NULL) || (line == 0)) {
pcercuei 0:03b5121a232e 2090 unsigned long l;
pcercuei 0:03b5121a232e 2091 const char *f;
pcercuei 0:03b5121a232e 2092 vctxt->locFunc(vctxt->locCtxt, &f, &l);
pcercuei 0:03b5121a232e 2093 if (file == NULL)
pcercuei 0:03b5121a232e 2094 file = f;
pcercuei 0:03b5121a232e 2095 if (line == 0)
pcercuei 0:03b5121a232e 2096 line = (int) l;
pcercuei 0:03b5121a232e 2097 }
pcercuei 0:03b5121a232e 2098 }
pcercuei 0:03b5121a232e 2099 if ((file == NULL) && (vctxt->filename != NULL))
pcercuei 0:03b5121a232e 2100 file = vctxt->filename;
pcercuei 0:03b5121a232e 2101
pcercuei 0:03b5121a232e 2102 __xmlRaiseError(schannel, channel, data, ctxt,
pcercuei 0:03b5121a232e 2103 node, XML_FROM_SCHEMASV,
pcercuei 0:03b5121a232e 2104 error, errorLevel, file, line,
pcercuei 0:03b5121a232e 2105 (const char *) str1, (const char *) str2,
pcercuei 0:03b5121a232e 2106 (const char *) str3, 0, col, msg, str1, str2, str3, str4);
pcercuei 0:03b5121a232e 2107
pcercuei 0:03b5121a232e 2108 } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
pcercuei 0:03b5121a232e 2109 xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
pcercuei 0:03b5121a232e 2110 if (errorLevel != XML_ERR_WARNING) {
pcercuei 0:03b5121a232e 2111 pctxt->nberrors++;
pcercuei 0:03b5121a232e 2112 pctxt->err = error;
pcercuei 0:03b5121a232e 2113 channel = pctxt->error;
pcercuei 0:03b5121a232e 2114 } else {
pcercuei 0:03b5121a232e 2115 channel = pctxt->warning;
pcercuei 0:03b5121a232e 2116 }
pcercuei 0:03b5121a232e 2117 schannel = pctxt->serror;
pcercuei 0:03b5121a232e 2118 data = pctxt->errCtxt;
pcercuei 0:03b5121a232e 2119 __xmlRaiseError(schannel, channel, data, ctxt,
pcercuei 0:03b5121a232e 2120 node, XML_FROM_SCHEMASP, error,
pcercuei 0:03b5121a232e 2121 errorLevel, NULL, 0,
pcercuei 0:03b5121a232e 2122 (const char *) str1, (const char *) str2,
pcercuei 0:03b5121a232e 2123 (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
pcercuei 0:03b5121a232e 2124 } else {
pcercuei 0:03b5121a232e 2125 TODO
pcercuei 0:03b5121a232e 2126 }
pcercuei 0:03b5121a232e 2127 }
pcercuei 0:03b5121a232e 2128 }
pcercuei 0:03b5121a232e 2129
pcercuei 0:03b5121a232e 2130 /**
pcercuei 0:03b5121a232e 2131 * xmlSchemaErr3:
pcercuei 0:03b5121a232e 2132 * @ctxt: the validation context
pcercuei 0:03b5121a232e 2133 * @node: the context node
pcercuei 0:03b5121a232e 2134 * @error: the error code
pcercuei 0:03b5121a232e 2135 * @msg: the error message
pcercuei 0:03b5121a232e 2136 * @str1: extra data
pcercuei 0:03b5121a232e 2137 * @str2: extra data
pcercuei 0:03b5121a232e 2138 * @str3: extra data
pcercuei 0:03b5121a232e 2139 *
pcercuei 0:03b5121a232e 2140 * Handle a validation error
pcercuei 0:03b5121a232e 2141 */
pcercuei 0:03b5121a232e 2142 static void
pcercuei 0:03b5121a232e 2143 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2144 int error, xmlNodePtr node, const char *msg,
pcercuei 0:03b5121a232e 2145 const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
pcercuei 0:03b5121a232e 2146 {
pcercuei 0:03b5121a232e 2147 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
pcercuei 0:03b5121a232e 2148 msg, str1, str2, str3, NULL);
pcercuei 0:03b5121a232e 2149 }
pcercuei 0:03b5121a232e 2150
pcercuei 0:03b5121a232e 2151 static void
pcercuei 0:03b5121a232e 2152 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2153 int error, xmlNodePtr node, const char *msg,
pcercuei 0:03b5121a232e 2154 const xmlChar *str1, const xmlChar *str2,
pcercuei 0:03b5121a232e 2155 const xmlChar *str3, const xmlChar *str4)
pcercuei 0:03b5121a232e 2156 {
pcercuei 0:03b5121a232e 2157 xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
pcercuei 0:03b5121a232e 2158 msg, str1, str2, str3, str4);
pcercuei 0:03b5121a232e 2159 }
pcercuei 0:03b5121a232e 2160
pcercuei 0:03b5121a232e 2161 static void
pcercuei 0:03b5121a232e 2162 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2163 int error, xmlNodePtr node, const char *msg,
pcercuei 0:03b5121a232e 2164 const xmlChar *str1, const xmlChar *str2)
pcercuei 0:03b5121a232e 2165 {
pcercuei 0:03b5121a232e 2166 xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
pcercuei 0:03b5121a232e 2167 }
pcercuei 0:03b5121a232e 2168
pcercuei 0:03b5121a232e 2169 static xmlChar *
pcercuei 0:03b5121a232e 2170 xmlSchemaFormatNodeForError(xmlChar ** msg,
pcercuei 0:03b5121a232e 2171 xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2172 xmlNodePtr node)
pcercuei 0:03b5121a232e 2173 {
pcercuei 0:03b5121a232e 2174 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 2175
pcercuei 0:03b5121a232e 2176 *msg = NULL;
pcercuei 0:03b5121a232e 2177 if ((node != NULL) &&
pcercuei 0:03b5121a232e 2178 (node->type != XML_ELEMENT_NODE) &&
pcercuei 0:03b5121a232e 2179 (node->type != XML_ATTRIBUTE_NODE))
pcercuei 0:03b5121a232e 2180 {
pcercuei 0:03b5121a232e 2181 /*
pcercuei 0:03b5121a232e 2182 * Don't try to format other nodes than element and
pcercuei 0:03b5121a232e 2183 * attribute nodes.
pcercuei 0:03b5121a232e 2184 * Play save and return an empty string.
pcercuei 0:03b5121a232e 2185 */
pcercuei 0:03b5121a232e 2186 *msg = xmlStrdup(BAD_CAST "");
pcercuei 0:03b5121a232e 2187 return(*msg);
pcercuei 0:03b5121a232e 2188 }
pcercuei 0:03b5121a232e 2189 if (node != NULL) {
pcercuei 0:03b5121a232e 2190 /*
pcercuei 0:03b5121a232e 2191 * Work on tree nodes.
pcercuei 0:03b5121a232e 2192 */
pcercuei 0:03b5121a232e 2193 if (node->type == XML_ATTRIBUTE_NODE) {
pcercuei 0:03b5121a232e 2194 xmlNodePtr elem = node->parent;
pcercuei 0:03b5121a232e 2195
pcercuei 0:03b5121a232e 2196 *msg = xmlStrdup(BAD_CAST "Element '");
pcercuei 0:03b5121a232e 2197 if (elem->ns != NULL)
pcercuei 0:03b5121a232e 2198 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 2199 elem->ns->href, elem->name));
pcercuei 0:03b5121a232e 2200 else
pcercuei 0:03b5121a232e 2201 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 2202 NULL, elem->name));
pcercuei 0:03b5121a232e 2203 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 2204 *msg = xmlStrcat(*msg, BAD_CAST "', ");
pcercuei 0:03b5121a232e 2205 *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
pcercuei 0:03b5121a232e 2206 } else {
pcercuei 0:03b5121a232e 2207 *msg = xmlStrdup(BAD_CAST "Element '");
pcercuei 0:03b5121a232e 2208 }
pcercuei 0:03b5121a232e 2209 if (node->ns != NULL)
pcercuei 0:03b5121a232e 2210 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 2211 node->ns->href, node->name));
pcercuei 0:03b5121a232e 2212 else
pcercuei 0:03b5121a232e 2213 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 2214 NULL, node->name));
pcercuei 0:03b5121a232e 2215 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 2216 *msg = xmlStrcat(*msg, BAD_CAST "': ");
pcercuei 0:03b5121a232e 2217 } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
pcercuei 0:03b5121a232e 2218 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
pcercuei 0:03b5121a232e 2219 /*
pcercuei 0:03b5121a232e 2220 * Work on node infos.
pcercuei 0:03b5121a232e 2221 */
pcercuei 0:03b5121a232e 2222 if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
pcercuei 0:03b5121a232e 2223 xmlSchemaNodeInfoPtr ielem =
pcercuei 0:03b5121a232e 2224 vctxt->elemInfos[vctxt->depth];
pcercuei 0:03b5121a232e 2225
pcercuei 0:03b5121a232e 2226 *msg = xmlStrdup(BAD_CAST "Element '");
pcercuei 0:03b5121a232e 2227 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 2228 ielem->nsName, ielem->localName));
pcercuei 0:03b5121a232e 2229 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 2230 *msg = xmlStrcat(*msg, BAD_CAST "', ");
pcercuei 0:03b5121a232e 2231 *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
pcercuei 0:03b5121a232e 2232 } else {
pcercuei 0:03b5121a232e 2233 *msg = xmlStrdup(BAD_CAST "Element '");
pcercuei 0:03b5121a232e 2234 }
pcercuei 0:03b5121a232e 2235 *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 2236 vctxt->inode->nsName, vctxt->inode->localName));
pcercuei 0:03b5121a232e 2237 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 2238 *msg = xmlStrcat(*msg, BAD_CAST "': ");
pcercuei 0:03b5121a232e 2239 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
pcercuei 0:03b5121a232e 2240 /*
pcercuei 0:03b5121a232e 2241 * Hmm, no node while parsing?
pcercuei 0:03b5121a232e 2242 * Return an empty string, in case NULL will break something.
pcercuei 0:03b5121a232e 2243 */
pcercuei 0:03b5121a232e 2244 *msg = xmlStrdup(BAD_CAST "");
pcercuei 0:03b5121a232e 2245 } else {
pcercuei 0:03b5121a232e 2246 TODO
pcercuei 0:03b5121a232e 2247 return (NULL);
pcercuei 0:03b5121a232e 2248 }
pcercuei 0:03b5121a232e 2249 /*
pcercuei 0:03b5121a232e 2250 * VAL TODO: The output of the given schema component is currently
pcercuei 0:03b5121a232e 2251 * disabled.
pcercuei 0:03b5121a232e 2252 */
pcercuei 0:03b5121a232e 2253 #if 0
pcercuei 0:03b5121a232e 2254 if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
pcercuei 0:03b5121a232e 2255 *msg = xmlStrcat(*msg, BAD_CAST " [");
pcercuei 0:03b5121a232e 2256 *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
pcercuei 0:03b5121a232e 2257 NULL, type, NULL, 0));
pcercuei 0:03b5121a232e 2258 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 2259 *msg = xmlStrcat(*msg, BAD_CAST "]");
pcercuei 0:03b5121a232e 2260 }
pcercuei 0:03b5121a232e 2261 #endif
pcercuei 0:03b5121a232e 2262 return (*msg);
pcercuei 0:03b5121a232e 2263 }
pcercuei 0:03b5121a232e 2264
pcercuei 0:03b5121a232e 2265 static void
pcercuei 0:03b5121a232e 2266 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2267 const char *funcName,
pcercuei 0:03b5121a232e 2268 const char *message,
pcercuei 0:03b5121a232e 2269 const xmlChar *str1,
pcercuei 0:03b5121a232e 2270 const xmlChar *str2)
pcercuei 0:03b5121a232e 2271 {
pcercuei 0:03b5121a232e 2272 xmlChar *msg = NULL;
pcercuei 0:03b5121a232e 2273
pcercuei 0:03b5121a232e 2274 if (actxt == NULL)
pcercuei 0:03b5121a232e 2275 return;
pcercuei 0:03b5121a232e 2276 msg = xmlStrdup(BAD_CAST "Internal error: ");
pcercuei 0:03b5121a232e 2277 msg = xmlStrcat(msg, BAD_CAST funcName);
pcercuei 0:03b5121a232e 2278 msg = xmlStrcat(msg, BAD_CAST ", ");
pcercuei 0:03b5121a232e 2279 msg = xmlStrcat(msg, BAD_CAST message);
pcercuei 0:03b5121a232e 2280 msg = xmlStrcat(msg, BAD_CAST ".\n");
pcercuei 0:03b5121a232e 2281
pcercuei 0:03b5121a232e 2282 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
pcercuei 0:03b5121a232e 2283 xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
pcercuei 0:03b5121a232e 2284 (const char *) msg, str1, str2);
pcercuei 0:03b5121a232e 2285
pcercuei 0:03b5121a232e 2286 else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
pcercuei 0:03b5121a232e 2287 xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
pcercuei 0:03b5121a232e 2288 (const char *) msg, str1, str2);
pcercuei 0:03b5121a232e 2289
pcercuei 0:03b5121a232e 2290 FREE_AND_NULL(msg)
pcercuei 0:03b5121a232e 2291 }
pcercuei 0:03b5121a232e 2292
pcercuei 0:03b5121a232e 2293 static void
pcercuei 0:03b5121a232e 2294 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2295 const char *funcName,
pcercuei 0:03b5121a232e 2296 const char *message)
pcercuei 0:03b5121a232e 2297 {
pcercuei 0:03b5121a232e 2298 xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
pcercuei 0:03b5121a232e 2299 }
pcercuei 0:03b5121a232e 2300
pcercuei 0:03b5121a232e 2301 #if 0
pcercuei 0:03b5121a232e 2302 static void
pcercuei 0:03b5121a232e 2303 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 2304 const char *funcName,
pcercuei 0:03b5121a232e 2305 const char *message,
pcercuei 0:03b5121a232e 2306 const xmlChar *str1,
pcercuei 0:03b5121a232e 2307 const xmlChar *str2)
pcercuei 0:03b5121a232e 2308 {
pcercuei 0:03b5121a232e 2309 xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
pcercuei 0:03b5121a232e 2310 str1, str2);
pcercuei 0:03b5121a232e 2311 }
pcercuei 0:03b5121a232e 2312 #endif
pcercuei 0:03b5121a232e 2313
pcercuei 0:03b5121a232e 2314 static void
pcercuei 0:03b5121a232e 2315 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2316 xmlParserErrors error,
pcercuei 0:03b5121a232e 2317 xmlNodePtr node,
pcercuei 0:03b5121a232e 2318 xmlSchemaBasicItemPtr item,
pcercuei 0:03b5121a232e 2319 const char *message,
pcercuei 0:03b5121a232e 2320 const xmlChar *str1, const xmlChar *str2,
pcercuei 0:03b5121a232e 2321 const xmlChar *str3, const xmlChar *str4)
pcercuei 0:03b5121a232e 2322 {
pcercuei 0:03b5121a232e 2323 xmlChar *msg = NULL;
pcercuei 0:03b5121a232e 2324
pcercuei 0:03b5121a232e 2325 if ((node == NULL) && (item != NULL) &&
pcercuei 0:03b5121a232e 2326 (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
pcercuei 0:03b5121a232e 2327 node = WXS_ITEM_NODE(item);
pcercuei 0:03b5121a232e 2328 xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
pcercuei 0:03b5121a232e 2329 msg = xmlStrcat(msg, BAD_CAST ": ");
pcercuei 0:03b5121a232e 2330 } else
pcercuei 0:03b5121a232e 2331 xmlSchemaFormatNodeForError(&msg, actxt, node);
pcercuei 0:03b5121a232e 2332 msg = xmlStrcat(msg, (const xmlChar *) message);
pcercuei 0:03b5121a232e 2333 msg = xmlStrcat(msg, BAD_CAST ".\n");
pcercuei 0:03b5121a232e 2334 xmlSchemaErr4(actxt, error, node,
pcercuei 0:03b5121a232e 2335 (const char *) msg, str1, str2, str3, str4);
pcercuei 0:03b5121a232e 2336 FREE_AND_NULL(msg)
pcercuei 0:03b5121a232e 2337 }
pcercuei 0:03b5121a232e 2338
pcercuei 0:03b5121a232e 2339 static void
pcercuei 0:03b5121a232e 2340 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2341 xmlParserErrors error,
pcercuei 0:03b5121a232e 2342 xmlNodePtr node,
pcercuei 0:03b5121a232e 2343 xmlSchemaBasicItemPtr item,
pcercuei 0:03b5121a232e 2344 const char *message,
pcercuei 0:03b5121a232e 2345 const xmlChar *str1,
pcercuei 0:03b5121a232e 2346 const xmlChar *str2)
pcercuei 0:03b5121a232e 2347 {
pcercuei 0:03b5121a232e 2348 xmlSchemaCustomErr4(actxt, error, node, item,
pcercuei 0:03b5121a232e 2349 message, str1, str2, NULL, NULL);
pcercuei 0:03b5121a232e 2350 }
pcercuei 0:03b5121a232e 2351
pcercuei 0:03b5121a232e 2352
pcercuei 0:03b5121a232e 2353
pcercuei 0:03b5121a232e 2354 static void
pcercuei 0:03b5121a232e 2355 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2356 xmlParserErrors error,
pcercuei 0:03b5121a232e 2357 xmlNodePtr node,
pcercuei 0:03b5121a232e 2358 xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 2359 const char *message,
pcercuei 0:03b5121a232e 2360 const xmlChar *str1,
pcercuei 0:03b5121a232e 2361 const xmlChar *str2,
pcercuei 0:03b5121a232e 2362 const xmlChar *str3)
pcercuei 0:03b5121a232e 2363 {
pcercuei 0:03b5121a232e 2364 xmlChar *msg = NULL;
pcercuei 0:03b5121a232e 2365
pcercuei 0:03b5121a232e 2366 xmlSchemaFormatNodeForError(&msg, actxt, node);
pcercuei 0:03b5121a232e 2367 msg = xmlStrcat(msg, (const xmlChar *) message);
pcercuei 0:03b5121a232e 2368 msg = xmlStrcat(msg, BAD_CAST ".\n");
pcercuei 0:03b5121a232e 2369
pcercuei 0:03b5121a232e 2370 /* URGENT TODO: Set the error code to something sane. */
pcercuei 0:03b5121a232e 2371 xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
pcercuei 0:03b5121a232e 2372 (const char *) msg, str1, str2, str3, NULL);
pcercuei 0:03b5121a232e 2373
pcercuei 0:03b5121a232e 2374 FREE_AND_NULL(msg)
pcercuei 0:03b5121a232e 2375 }
pcercuei 0:03b5121a232e 2376
pcercuei 0:03b5121a232e 2377
pcercuei 0:03b5121a232e 2378
pcercuei 0:03b5121a232e 2379 static void
pcercuei 0:03b5121a232e 2380 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 2381 xmlParserErrors error,
pcercuei 0:03b5121a232e 2382 xmlSchemaPSVIIDCNodePtr idcNode,
pcercuei 0:03b5121a232e 2383 xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 2384 const char *message,
pcercuei 0:03b5121a232e 2385 const xmlChar *str1,
pcercuei 0:03b5121a232e 2386 const xmlChar *str2)
pcercuei 0:03b5121a232e 2387 {
pcercuei 0:03b5121a232e 2388 xmlChar *msg = NULL, *qname = NULL;
pcercuei 0:03b5121a232e 2389
pcercuei 0:03b5121a232e 2390 msg = xmlStrdup(BAD_CAST "Element '%s': ");
pcercuei 0:03b5121a232e 2391 msg = xmlStrcat(msg, (const xmlChar *) message);
pcercuei 0:03b5121a232e 2392 msg = xmlStrcat(msg, BAD_CAST ".\n");
pcercuei 0:03b5121a232e 2393 xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
pcercuei 0:03b5121a232e 2394 error, NULL, idcNode->nodeLine, (const char *) msg,
pcercuei 0:03b5121a232e 2395 xmlSchemaFormatQName(&qname,
pcercuei 0:03b5121a232e 2396 vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
pcercuei 0:03b5121a232e 2397 vctxt->nodeQNames->items[idcNode->nodeQNameID]),
pcercuei 0:03b5121a232e 2398 str1, str2, NULL);
pcercuei 0:03b5121a232e 2399 FREE_AND_NULL(qname);
pcercuei 0:03b5121a232e 2400 FREE_AND_NULL(msg);
pcercuei 0:03b5121a232e 2401 }
pcercuei 0:03b5121a232e 2402
pcercuei 0:03b5121a232e 2403 static int
pcercuei 0:03b5121a232e 2404 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2405 xmlNodePtr node)
pcercuei 0:03b5121a232e 2406 {
pcercuei 0:03b5121a232e 2407 if (node != NULL)
pcercuei 0:03b5121a232e 2408 return (node->type);
pcercuei 0:03b5121a232e 2409 if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
pcercuei 0:03b5121a232e 2410 (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
pcercuei 0:03b5121a232e 2411 return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
pcercuei 0:03b5121a232e 2412 return (-1);
pcercuei 0:03b5121a232e 2413 }
pcercuei 0:03b5121a232e 2414
pcercuei 0:03b5121a232e 2415 static int
pcercuei 0:03b5121a232e 2416 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
pcercuei 0:03b5121a232e 2417 {
pcercuei 0:03b5121a232e 2418 switch (item->type) {
pcercuei 0:03b5121a232e 2419 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 2420 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 2421 if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
pcercuei 0:03b5121a232e 2422 return(1);
pcercuei 0:03b5121a232e 2423 break;
pcercuei 0:03b5121a232e 2424 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 2425 return (1);
pcercuei 0:03b5121a232e 2426 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 2427 if ( ((xmlSchemaElementPtr) item)->flags &
pcercuei 0:03b5121a232e 2428 XML_SCHEMAS_ELEM_GLOBAL)
pcercuei 0:03b5121a232e 2429 return(1);
pcercuei 0:03b5121a232e 2430 break;
pcercuei 0:03b5121a232e 2431 case XML_SCHEMA_TYPE_ATTRIBUTE:
pcercuei 0:03b5121a232e 2432 if ( ((xmlSchemaAttributePtr) item)->flags &
pcercuei 0:03b5121a232e 2433 XML_SCHEMAS_ATTR_GLOBAL)
pcercuei 0:03b5121a232e 2434 return(1);
pcercuei 0:03b5121a232e 2435 break;
pcercuei 0:03b5121a232e 2436 /* Note that attribute groups are always global. */
pcercuei 0:03b5121a232e 2437 default:
pcercuei 0:03b5121a232e 2438 return(1);
pcercuei 0:03b5121a232e 2439 }
pcercuei 0:03b5121a232e 2440 return (0);
pcercuei 0:03b5121a232e 2441 }
pcercuei 0:03b5121a232e 2442
pcercuei 0:03b5121a232e 2443 static void
pcercuei 0:03b5121a232e 2444 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2445 xmlParserErrors error,
pcercuei 0:03b5121a232e 2446 xmlNodePtr node,
pcercuei 0:03b5121a232e 2447 const xmlChar *value,
pcercuei 0:03b5121a232e 2448 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 2449 int displayValue)
pcercuei 0:03b5121a232e 2450 {
pcercuei 0:03b5121a232e 2451 xmlChar *msg = NULL;
pcercuei 0:03b5121a232e 2452
pcercuei 0:03b5121a232e 2453 xmlSchemaFormatNodeForError(&msg, actxt, node);
pcercuei 0:03b5121a232e 2454
pcercuei 0:03b5121a232e 2455 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
pcercuei 0:03b5121a232e 2456 XML_ATTRIBUTE_NODE))
pcercuei 0:03b5121a232e 2457 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
pcercuei 0:03b5121a232e 2458 else
pcercuei 0:03b5121a232e 2459 msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
pcercuei 0:03b5121a232e 2460 "value of ");
pcercuei 0:03b5121a232e 2461
pcercuei 0:03b5121a232e 2462 if (! xmlSchemaIsGlobalItem(type))
pcercuei 0:03b5121a232e 2463 msg = xmlStrcat(msg, BAD_CAST "the local ");
pcercuei 0:03b5121a232e 2464 else
pcercuei 0:03b5121a232e 2465 msg = xmlStrcat(msg, BAD_CAST "the ");
pcercuei 0:03b5121a232e 2466
pcercuei 0:03b5121a232e 2467 if (WXS_IS_ATOMIC(type))
pcercuei 0:03b5121a232e 2468 msg = xmlStrcat(msg, BAD_CAST "atomic type");
pcercuei 0:03b5121a232e 2469 else if (WXS_IS_LIST(type))
pcercuei 0:03b5121a232e 2470 msg = xmlStrcat(msg, BAD_CAST "list type");
pcercuei 0:03b5121a232e 2471 else if (WXS_IS_UNION(type))
pcercuei 0:03b5121a232e 2472 msg = xmlStrcat(msg, BAD_CAST "union type");
pcercuei 0:03b5121a232e 2473
pcercuei 0:03b5121a232e 2474 if (xmlSchemaIsGlobalItem(type)) {
pcercuei 0:03b5121a232e 2475 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 2476 msg = xmlStrcat(msg, BAD_CAST " '");
pcercuei 0:03b5121a232e 2477 if (type->builtInType != 0) {
pcercuei 0:03b5121a232e 2478 msg = xmlStrcat(msg, BAD_CAST "xs:");
pcercuei 0:03b5121a232e 2479 msg = xmlStrcat(msg, type->name);
pcercuei 0:03b5121a232e 2480 } else
pcercuei 0:03b5121a232e 2481 msg = xmlStrcat(msg,
pcercuei 0:03b5121a232e 2482 xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 2483 type->targetNamespace, type->name));
pcercuei 0:03b5121a232e 2484 msg = xmlStrcat(msg, BAD_CAST "'");
pcercuei 0:03b5121a232e 2485 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 2486 }
pcercuei 0:03b5121a232e 2487 msg = xmlStrcat(msg, BAD_CAST ".\n");
pcercuei 0:03b5121a232e 2488 if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
pcercuei 0:03b5121a232e 2489 XML_ATTRIBUTE_NODE))
pcercuei 0:03b5121a232e 2490 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
pcercuei 0:03b5121a232e 2491 else
pcercuei 0:03b5121a232e 2492 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
pcercuei 0:03b5121a232e 2493 FREE_AND_NULL(msg)
pcercuei 0:03b5121a232e 2494 }
pcercuei 0:03b5121a232e 2495
pcercuei 0:03b5121a232e 2496 static const xmlChar *
pcercuei 0:03b5121a232e 2497 xmlSchemaFormatErrorNodeQName(xmlChar ** str,
pcercuei 0:03b5121a232e 2498 xmlSchemaNodeInfoPtr ni,
pcercuei 0:03b5121a232e 2499 xmlNodePtr node)
pcercuei 0:03b5121a232e 2500 {
pcercuei 0:03b5121a232e 2501 if (node != NULL) {
pcercuei 0:03b5121a232e 2502 if (node->ns != NULL)
pcercuei 0:03b5121a232e 2503 return (xmlSchemaFormatQName(str, node->ns->href, node->name));
pcercuei 0:03b5121a232e 2504 else
pcercuei 0:03b5121a232e 2505 return (xmlSchemaFormatQName(str, NULL, node->name));
pcercuei 0:03b5121a232e 2506 } else if (ni != NULL)
pcercuei 0:03b5121a232e 2507 return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
pcercuei 0:03b5121a232e 2508 return (NULL);
pcercuei 0:03b5121a232e 2509 }
pcercuei 0:03b5121a232e 2510
pcercuei 0:03b5121a232e 2511 static void
pcercuei 0:03b5121a232e 2512 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2513 xmlParserErrors error,
pcercuei 0:03b5121a232e 2514 xmlSchemaAttrInfoPtr ni,
pcercuei 0:03b5121a232e 2515 xmlNodePtr node)
pcercuei 0:03b5121a232e 2516 {
pcercuei 0:03b5121a232e 2517 xmlChar *msg = NULL, *str = NULL;
pcercuei 0:03b5121a232e 2518
pcercuei 0:03b5121a232e 2519 xmlSchemaFormatNodeForError(&msg, actxt, node);
pcercuei 0:03b5121a232e 2520 msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
pcercuei 0:03b5121a232e 2521 xmlSchemaErr(actxt, error, node, (const char *) msg,
pcercuei 0:03b5121a232e 2522 xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
pcercuei 0:03b5121a232e 2523 NULL);
pcercuei 0:03b5121a232e 2524 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 2525 FREE_AND_NULL(msg)
pcercuei 0:03b5121a232e 2526 }
pcercuei 0:03b5121a232e 2527
pcercuei 0:03b5121a232e 2528 static void
pcercuei 0:03b5121a232e 2529 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2530 xmlParserErrors error,
pcercuei 0:03b5121a232e 2531 xmlNodePtr node,
pcercuei 0:03b5121a232e 2532 xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 2533 const char *message,
pcercuei 0:03b5121a232e 2534 int nbval,
pcercuei 0:03b5121a232e 2535 int nbneg,
pcercuei 0:03b5121a232e 2536 xmlChar **values)
pcercuei 0:03b5121a232e 2537 {
pcercuei 0:03b5121a232e 2538 xmlChar *str = NULL, *msg = NULL;
pcercuei 0:03b5121a232e 2539 xmlChar *localName, *nsName;
pcercuei 0:03b5121a232e 2540 const xmlChar *cur, *end;
pcercuei 0:03b5121a232e 2541 int i;
pcercuei 0:03b5121a232e 2542
pcercuei 0:03b5121a232e 2543 xmlSchemaFormatNodeForError(&msg, actxt, node);
pcercuei 0:03b5121a232e 2544 msg = xmlStrcat(msg, (const xmlChar *) message);
pcercuei 0:03b5121a232e 2545 msg = xmlStrcat(msg, BAD_CAST ".");
pcercuei 0:03b5121a232e 2546 /*
pcercuei 0:03b5121a232e 2547 * Note that is does not make sense to report that we have a
pcercuei 0:03b5121a232e 2548 * wildcard here, since the wildcard might be unfolded into
pcercuei 0:03b5121a232e 2549 * multiple transitions.
pcercuei 0:03b5121a232e 2550 */
pcercuei 0:03b5121a232e 2551 if (nbval + nbneg > 0) {
pcercuei 0:03b5121a232e 2552 if (nbval + nbneg > 1) {
pcercuei 0:03b5121a232e 2553 str = xmlStrdup(BAD_CAST " Expected is one of ( ");
pcercuei 0:03b5121a232e 2554 } else
pcercuei 0:03b5121a232e 2555 str = xmlStrdup(BAD_CAST " Expected is ( ");
pcercuei 0:03b5121a232e 2556 nsName = NULL;
pcercuei 0:03b5121a232e 2557
pcercuei 0:03b5121a232e 2558 for (i = 0; i < nbval + nbneg; i++) {
pcercuei 0:03b5121a232e 2559 cur = values[i];
pcercuei 0:03b5121a232e 2560 if (cur == NULL)
pcercuei 0:03b5121a232e 2561 continue;
pcercuei 0:03b5121a232e 2562 if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
pcercuei 0:03b5121a232e 2563 (cur[3] == ' ')) {
pcercuei 0:03b5121a232e 2564 cur += 4;
pcercuei 0:03b5121a232e 2565 str = xmlStrcat(str, BAD_CAST "##other");
pcercuei 0:03b5121a232e 2566 }
pcercuei 0:03b5121a232e 2567 /*
pcercuei 0:03b5121a232e 2568 * Get the local name.
pcercuei 0:03b5121a232e 2569 */
pcercuei 0:03b5121a232e 2570 localName = NULL;
pcercuei 0:03b5121a232e 2571
pcercuei 0:03b5121a232e 2572 end = cur;
pcercuei 0:03b5121a232e 2573 if (*end == '*') {
pcercuei 0:03b5121a232e 2574 localName = xmlStrdup(BAD_CAST "*");
pcercuei 0:03b5121a232e 2575 end++;
pcercuei 0:03b5121a232e 2576 } else {
pcercuei 0:03b5121a232e 2577 while ((*end != 0) && (*end != '|'))
pcercuei 0:03b5121a232e 2578 end++;
pcercuei 0:03b5121a232e 2579 localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
pcercuei 0:03b5121a232e 2580 }
pcercuei 0:03b5121a232e 2581 if (*end != 0) {
pcercuei 0:03b5121a232e 2582 end++;
pcercuei 0:03b5121a232e 2583 /*
pcercuei 0:03b5121a232e 2584 * Skip "*|*" if they come with negated expressions, since
pcercuei 0:03b5121a232e 2585 * they represent the same negated wildcard.
pcercuei 0:03b5121a232e 2586 */
pcercuei 0:03b5121a232e 2587 if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
pcercuei 0:03b5121a232e 2588 /*
pcercuei 0:03b5121a232e 2589 * Get the namespace name.
pcercuei 0:03b5121a232e 2590 */
pcercuei 0:03b5121a232e 2591 cur = end;
pcercuei 0:03b5121a232e 2592 if (*end == '*') {
pcercuei 0:03b5121a232e 2593 nsName = xmlStrdup(BAD_CAST "{*}");
pcercuei 0:03b5121a232e 2594 } else {
pcercuei 0:03b5121a232e 2595 while (*end != 0)
pcercuei 0:03b5121a232e 2596 end++;
pcercuei 0:03b5121a232e 2597
pcercuei 0:03b5121a232e 2598 if (i >= nbval)
pcercuei 0:03b5121a232e 2599 nsName = xmlStrdup(BAD_CAST "{##other:");
pcercuei 0:03b5121a232e 2600 else
pcercuei 0:03b5121a232e 2601 nsName = xmlStrdup(BAD_CAST "{");
pcercuei 0:03b5121a232e 2602
pcercuei 0:03b5121a232e 2603 nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
pcercuei 0:03b5121a232e 2604 nsName = xmlStrcat(nsName, BAD_CAST "}");
pcercuei 0:03b5121a232e 2605 }
pcercuei 0:03b5121a232e 2606 str = xmlStrcat(str, BAD_CAST nsName);
pcercuei 0:03b5121a232e 2607 FREE_AND_NULL(nsName)
pcercuei 0:03b5121a232e 2608 } else {
pcercuei 0:03b5121a232e 2609 FREE_AND_NULL(localName);
pcercuei 0:03b5121a232e 2610 continue;
pcercuei 0:03b5121a232e 2611 }
pcercuei 0:03b5121a232e 2612 }
pcercuei 0:03b5121a232e 2613 str = xmlStrcat(str, BAD_CAST localName);
pcercuei 0:03b5121a232e 2614 FREE_AND_NULL(localName);
pcercuei 0:03b5121a232e 2615
pcercuei 0:03b5121a232e 2616 if (i < nbval + nbneg -1)
pcercuei 0:03b5121a232e 2617 str = xmlStrcat(str, BAD_CAST ", ");
pcercuei 0:03b5121a232e 2618 }
pcercuei 0:03b5121a232e 2619 str = xmlStrcat(str, BAD_CAST " ).\n");
pcercuei 0:03b5121a232e 2620 msg = xmlStrcat(msg, BAD_CAST str);
pcercuei 0:03b5121a232e 2621 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 2622 } else
pcercuei 0:03b5121a232e 2623 msg = xmlStrcat(msg, BAD_CAST "\n");
pcercuei 0:03b5121a232e 2624 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
pcercuei 0:03b5121a232e 2625 xmlFree(msg);
pcercuei 0:03b5121a232e 2626 }
pcercuei 0:03b5121a232e 2627
pcercuei 0:03b5121a232e 2628 static void
pcercuei 0:03b5121a232e 2629 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 2630 xmlParserErrors error,
pcercuei 0:03b5121a232e 2631 xmlNodePtr node,
pcercuei 0:03b5121a232e 2632 const xmlChar *value,
pcercuei 0:03b5121a232e 2633 unsigned long length,
pcercuei 0:03b5121a232e 2634 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 2635 xmlSchemaFacetPtr facet,
pcercuei 0:03b5121a232e 2636 const char *message,
pcercuei 0:03b5121a232e 2637 const xmlChar *str1,
pcercuei 0:03b5121a232e 2638 const xmlChar *str2)
pcercuei 0:03b5121a232e 2639 {
pcercuei 0:03b5121a232e 2640 xmlChar *str = NULL, *msg = NULL;
pcercuei 0:03b5121a232e 2641 xmlSchemaTypeType facetType;
pcercuei 0:03b5121a232e 2642 int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
pcercuei 0:03b5121a232e 2643
pcercuei 0:03b5121a232e 2644 xmlSchemaFormatNodeForError(&msg, actxt, node);
pcercuei 0:03b5121a232e 2645 if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
pcercuei 0:03b5121a232e 2646 facetType = XML_SCHEMA_FACET_ENUMERATION;
pcercuei 0:03b5121a232e 2647 /*
pcercuei 0:03b5121a232e 2648 * If enumerations are validated, one must not expect the
pcercuei 0:03b5121a232e 2649 * facet to be given.
pcercuei 0:03b5121a232e 2650 */
pcercuei 0:03b5121a232e 2651 } else
pcercuei 0:03b5121a232e 2652 facetType = facet->type;
pcercuei 0:03b5121a232e 2653 msg = xmlStrcat(msg, BAD_CAST "[");
pcercuei 0:03b5121a232e 2654 msg = xmlStrcat(msg, BAD_CAST "facet '");
pcercuei 0:03b5121a232e 2655 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
pcercuei 0:03b5121a232e 2656 msg = xmlStrcat(msg, BAD_CAST "'] ");
pcercuei 0:03b5121a232e 2657 if (message == NULL) {
pcercuei 0:03b5121a232e 2658 /*
pcercuei 0:03b5121a232e 2659 * Use a default message.
pcercuei 0:03b5121a232e 2660 */
pcercuei 0:03b5121a232e 2661 if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
pcercuei 0:03b5121a232e 2662 (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
pcercuei 0:03b5121a232e 2663 (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
pcercuei 0:03b5121a232e 2664
pcercuei 0:03b5121a232e 2665 char len[25], actLen[25];
pcercuei 0:03b5121a232e 2666
pcercuei 0:03b5121a232e 2667 /* FIXME, TODO: What is the max expected string length of the
pcercuei 0:03b5121a232e 2668 * this value?
pcercuei 0:03b5121a232e 2669 */
pcercuei 0:03b5121a232e 2670 if (nodeType == XML_ATTRIBUTE_NODE)
pcercuei 0:03b5121a232e 2671 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
pcercuei 0:03b5121a232e 2672 else
pcercuei 0:03b5121a232e 2673 msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
pcercuei 0:03b5121a232e 2674
pcercuei 0:03b5121a232e 2675 snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
pcercuei 0:03b5121a232e 2676 snprintf(actLen, 24, "%lu", length);
pcercuei 0:03b5121a232e 2677
pcercuei 0:03b5121a232e 2678 if (facetType == XML_SCHEMA_FACET_LENGTH)
pcercuei 0:03b5121a232e 2679 msg = xmlStrcat(msg,
pcercuei 0:03b5121a232e 2680 BAD_CAST "this differs from the allowed length of '%s'.\n");
pcercuei 0:03b5121a232e 2681 else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
pcercuei 0:03b5121a232e 2682 msg = xmlStrcat(msg,
pcercuei 0:03b5121a232e 2683 BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
pcercuei 0:03b5121a232e 2684 else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
pcercuei 0:03b5121a232e 2685 msg = xmlStrcat(msg,
pcercuei 0:03b5121a232e 2686 BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
pcercuei 0:03b5121a232e 2687
pcercuei 0:03b5121a232e 2688 if (nodeType == XML_ATTRIBUTE_NODE)
pcercuei 0:03b5121a232e 2689 xmlSchemaErr3(actxt, error, node, (const char *) msg,
pcercuei 0:03b5121a232e 2690 value, (const xmlChar *) actLen, (const xmlChar *) len);
pcercuei 0:03b5121a232e 2691 else
pcercuei 0:03b5121a232e 2692 xmlSchemaErr(actxt, error, node, (const char *) msg,
pcercuei 0:03b5121a232e 2693 (const xmlChar *) actLen, (const xmlChar *) len);
pcercuei 0:03b5121a232e 2694
pcercuei 0:03b5121a232e 2695 } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
pcercuei 0:03b5121a232e 2696 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
pcercuei 0:03b5121a232e 2697 "of the set {%s}.\n");
pcercuei 0:03b5121a232e 2698 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
pcercuei 0:03b5121a232e 2699 xmlSchemaFormatFacetEnumSet(actxt, &str, type));
pcercuei 0:03b5121a232e 2700 } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
pcercuei 0:03b5121a232e 2701 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
pcercuei 0:03b5121a232e 2702 "by the pattern '%s'.\n");
pcercuei 0:03b5121a232e 2703 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
pcercuei 0:03b5121a232e 2704 facet->value);
pcercuei 0:03b5121a232e 2705 } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
pcercuei 0:03b5121a232e 2706 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
pcercuei 0:03b5121a232e 2707 "minimum value allowed ('%s').\n");
pcercuei 0:03b5121a232e 2708 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
pcercuei 0:03b5121a232e 2709 facet->value);
pcercuei 0:03b5121a232e 2710 } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
pcercuei 0:03b5121a232e 2711 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
pcercuei 0:03b5121a232e 2712 "maximum value allowed ('%s').\n");
pcercuei 0:03b5121a232e 2713 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
pcercuei 0:03b5121a232e 2714 facet->value);
pcercuei 0:03b5121a232e 2715 } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
pcercuei 0:03b5121a232e 2716 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
pcercuei 0:03b5121a232e 2717 "'%s'.\n");
pcercuei 0:03b5121a232e 2718 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
pcercuei 0:03b5121a232e 2719 facet->value);
pcercuei 0:03b5121a232e 2720 } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
pcercuei 0:03b5121a232e 2721 msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
pcercuei 0:03b5121a232e 2722 "'%s'.\n");
pcercuei 0:03b5121a232e 2723 xmlSchemaErr(actxt, error, node, (const char *) msg, value,
pcercuei 0:03b5121a232e 2724 facet->value);
pcercuei 0:03b5121a232e 2725 } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
pcercuei 0:03b5121a232e 2726 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
pcercuei 0:03b5121a232e 2727 "digits than are allowed ('%s').\n");
pcercuei 0:03b5121a232e 2728 xmlSchemaErr(actxt, error, node, (const char*) msg, value,
pcercuei 0:03b5121a232e 2729 facet->value);
pcercuei 0:03b5121a232e 2730 } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
pcercuei 0:03b5121a232e 2731 msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
pcercuei 0:03b5121a232e 2732 "digits than are allowed ('%s').\n");
pcercuei 0:03b5121a232e 2733 xmlSchemaErr(actxt, error, node, (const char*) msg, value,
pcercuei 0:03b5121a232e 2734 facet->value);
pcercuei 0:03b5121a232e 2735 } else if (nodeType == XML_ATTRIBUTE_NODE) {
pcercuei 0:03b5121a232e 2736 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
pcercuei 0:03b5121a232e 2737 xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
pcercuei 0:03b5121a232e 2738 } else {
pcercuei 0:03b5121a232e 2739 msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
pcercuei 0:03b5121a232e 2740 xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
pcercuei 0:03b5121a232e 2741 }
pcercuei 0:03b5121a232e 2742 } else {
pcercuei 0:03b5121a232e 2743 msg = xmlStrcat(msg, (const xmlChar *) message);
pcercuei 0:03b5121a232e 2744 msg = xmlStrcat(msg, BAD_CAST ".\n");
pcercuei 0:03b5121a232e 2745 xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
pcercuei 0:03b5121a232e 2746 }
pcercuei 0:03b5121a232e 2747 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 2748 xmlFree(msg);
pcercuei 0:03b5121a232e 2749 }
pcercuei 0:03b5121a232e 2750
pcercuei 0:03b5121a232e 2751 #define VERROR(err, type, msg) \
pcercuei 0:03b5121a232e 2752 xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
pcercuei 0:03b5121a232e 2753
pcercuei 0:03b5121a232e 2754 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
pcercuei 0:03b5121a232e 2755
pcercuei 0:03b5121a232e 2756 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
pcercuei 0:03b5121a232e 2757 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
pcercuei 0:03b5121a232e 2758
pcercuei 0:03b5121a232e 2759 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
pcercuei 0:03b5121a232e 2760
pcercuei 0:03b5121a232e 2761
pcercuei 0:03b5121a232e 2762 /**
pcercuei 0:03b5121a232e 2763 * xmlSchemaPMissingAttrErr:
pcercuei 0:03b5121a232e 2764 * @ctxt: the schema validation context
pcercuei 0:03b5121a232e 2765 * @ownerDes: the designation of the owner
pcercuei 0:03b5121a232e 2766 * @ownerName: the name of the owner
pcercuei 0:03b5121a232e 2767 * @ownerItem: the owner as a schema object
pcercuei 0:03b5121a232e 2768 * @ownerElem: the owner as an element node
pcercuei 0:03b5121a232e 2769 * @node: the parent element node of the missing attribute node
pcercuei 0:03b5121a232e 2770 * @type: the corresponding type of the attribute node
pcercuei 0:03b5121a232e 2771 *
pcercuei 0:03b5121a232e 2772 * Reports an illegal attribute.
pcercuei 0:03b5121a232e 2773 */
pcercuei 0:03b5121a232e 2774 static void
pcercuei 0:03b5121a232e 2775 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 2776 xmlParserErrors error,
pcercuei 0:03b5121a232e 2777 xmlSchemaBasicItemPtr ownerItem,
pcercuei 0:03b5121a232e 2778 xmlNodePtr ownerElem,
pcercuei 0:03b5121a232e 2779 const char *name,
pcercuei 0:03b5121a232e 2780 const char *message)
pcercuei 0:03b5121a232e 2781 {
pcercuei 0:03b5121a232e 2782 xmlChar *des = NULL;
pcercuei 0:03b5121a232e 2783
pcercuei 0:03b5121a232e 2784 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
pcercuei 0:03b5121a232e 2785
pcercuei 0:03b5121a232e 2786 if (message != NULL)
pcercuei 0:03b5121a232e 2787 xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
pcercuei 0:03b5121a232e 2788 else
pcercuei 0:03b5121a232e 2789 xmlSchemaPErr(ctxt, ownerElem, error,
pcercuei 0:03b5121a232e 2790 "%s: The attribute '%s' is required but missing.\n",
pcercuei 0:03b5121a232e 2791 BAD_CAST des, BAD_CAST name);
pcercuei 0:03b5121a232e 2792 FREE_AND_NULL(des);
pcercuei 0:03b5121a232e 2793 }
pcercuei 0:03b5121a232e 2794
pcercuei 0:03b5121a232e 2795
pcercuei 0:03b5121a232e 2796 /**
pcercuei 0:03b5121a232e 2797 * xmlSchemaPResCompAttrErr:
pcercuei 0:03b5121a232e 2798 * @ctxt: the schema validation context
pcercuei 0:03b5121a232e 2799 * @error: the error code
pcercuei 0:03b5121a232e 2800 * @ownerDes: the designation of the owner
pcercuei 0:03b5121a232e 2801 * @ownerItem: the owner as a schema object
pcercuei 0:03b5121a232e 2802 * @ownerElem: the owner as an element node
pcercuei 0:03b5121a232e 2803 * @name: the name of the attribute holding the QName
pcercuei 0:03b5121a232e 2804 * @refName: the referenced local name
pcercuei 0:03b5121a232e 2805 * @refURI: the referenced namespace URI
pcercuei 0:03b5121a232e 2806 * @message: optional message
pcercuei 0:03b5121a232e 2807 *
pcercuei 0:03b5121a232e 2808 * Used to report QName attribute values that failed to resolve
pcercuei 0:03b5121a232e 2809 * to schema components.
pcercuei 0:03b5121a232e 2810 */
pcercuei 0:03b5121a232e 2811 static void
pcercuei 0:03b5121a232e 2812 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 2813 xmlParserErrors error,
pcercuei 0:03b5121a232e 2814 xmlSchemaBasicItemPtr ownerItem,
pcercuei 0:03b5121a232e 2815 xmlNodePtr ownerElem,
pcercuei 0:03b5121a232e 2816 const char *name,
pcercuei 0:03b5121a232e 2817 const xmlChar *refName,
pcercuei 0:03b5121a232e 2818 const xmlChar *refURI,
pcercuei 0:03b5121a232e 2819 xmlSchemaTypeType refType,
pcercuei 0:03b5121a232e 2820 const char *refTypeStr)
pcercuei 0:03b5121a232e 2821 {
pcercuei 0:03b5121a232e 2822 xmlChar *des = NULL, *strA = NULL;
pcercuei 0:03b5121a232e 2823
pcercuei 0:03b5121a232e 2824 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
pcercuei 0:03b5121a232e 2825 if (refTypeStr == NULL)
pcercuei 0:03b5121a232e 2826 refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
pcercuei 0:03b5121a232e 2827 xmlSchemaPErrExt(ctxt, ownerElem, error,
pcercuei 0:03b5121a232e 2828 NULL, NULL, NULL,
pcercuei 0:03b5121a232e 2829 "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
pcercuei 0:03b5121a232e 2830 "%s.\n", BAD_CAST des, BAD_CAST name,
pcercuei 0:03b5121a232e 2831 xmlSchemaFormatQName(&strA, refURI, refName),
pcercuei 0:03b5121a232e 2832 BAD_CAST refTypeStr, NULL);
pcercuei 0:03b5121a232e 2833 FREE_AND_NULL(des)
pcercuei 0:03b5121a232e 2834 FREE_AND_NULL(strA)
pcercuei 0:03b5121a232e 2835 }
pcercuei 0:03b5121a232e 2836
pcercuei 0:03b5121a232e 2837 /**
pcercuei 0:03b5121a232e 2838 * xmlSchemaPCustomAttrErr:
pcercuei 0:03b5121a232e 2839 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 2840 * @error: the error code
pcercuei 0:03b5121a232e 2841 * @ownerDes: the designation of the owner
pcercuei 0:03b5121a232e 2842 * @ownerItem: the owner as a schema object
pcercuei 0:03b5121a232e 2843 * @attr: the illegal attribute node
pcercuei 0:03b5121a232e 2844 *
pcercuei 0:03b5121a232e 2845 * Reports an illegal attribute during the parse.
pcercuei 0:03b5121a232e 2846 */
pcercuei 0:03b5121a232e 2847 static void
pcercuei 0:03b5121a232e 2848 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 2849 xmlParserErrors error,
pcercuei 0:03b5121a232e 2850 xmlChar **ownerDes,
pcercuei 0:03b5121a232e 2851 xmlSchemaBasicItemPtr ownerItem,
pcercuei 0:03b5121a232e 2852 xmlAttrPtr attr,
pcercuei 0:03b5121a232e 2853 const char *msg)
pcercuei 0:03b5121a232e 2854 {
pcercuei 0:03b5121a232e 2855 xmlChar *des = NULL;
pcercuei 0:03b5121a232e 2856
pcercuei 0:03b5121a232e 2857 if (ownerDes == NULL)
pcercuei 0:03b5121a232e 2858 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
pcercuei 0:03b5121a232e 2859 else if (*ownerDes == NULL) {
pcercuei 0:03b5121a232e 2860 xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
pcercuei 0:03b5121a232e 2861 des = *ownerDes;
pcercuei 0:03b5121a232e 2862 } else
pcercuei 0:03b5121a232e 2863 des = *ownerDes;
pcercuei 0:03b5121a232e 2864 if (attr == NULL) {
pcercuei 0:03b5121a232e 2865 xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
pcercuei 0:03b5121a232e 2866 "%s, attribute '%s': %s.\n",
pcercuei 0:03b5121a232e 2867 BAD_CAST des, (const xmlChar *) "Unknown",
pcercuei 0:03b5121a232e 2868 (const xmlChar *) msg, NULL, NULL);
pcercuei 0:03b5121a232e 2869 } else {
pcercuei 0:03b5121a232e 2870 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
pcercuei 0:03b5121a232e 2871 "%s, attribute '%s': %s.\n",
pcercuei 0:03b5121a232e 2872 BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
pcercuei 0:03b5121a232e 2873 }
pcercuei 0:03b5121a232e 2874 if (ownerDes == NULL)
pcercuei 0:03b5121a232e 2875 FREE_AND_NULL(des);
pcercuei 0:03b5121a232e 2876 }
pcercuei 0:03b5121a232e 2877
pcercuei 0:03b5121a232e 2878 /**
pcercuei 0:03b5121a232e 2879 * xmlSchemaPIllegalAttrErr:
pcercuei 0:03b5121a232e 2880 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 2881 * @error: the error code
pcercuei 0:03b5121a232e 2882 * @ownerDes: the designation of the attribute's owner
pcercuei 0:03b5121a232e 2883 * @ownerItem: the attribute's owner item
pcercuei 0:03b5121a232e 2884 * @attr: the illegal attribute node
pcercuei 0:03b5121a232e 2885 *
pcercuei 0:03b5121a232e 2886 * Reports an illegal attribute during the parse.
pcercuei 0:03b5121a232e 2887 */
pcercuei 0:03b5121a232e 2888 static void
pcercuei 0:03b5121a232e 2889 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 2890 xmlParserErrors error,
pcercuei 0:03b5121a232e 2891 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 2892 xmlAttrPtr attr)
pcercuei 0:03b5121a232e 2893 {
pcercuei 0:03b5121a232e 2894 xmlChar *strA = NULL, *strB = NULL;
pcercuei 0:03b5121a232e 2895
pcercuei 0:03b5121a232e 2896 xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
pcercuei 0:03b5121a232e 2897 xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 2898 "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
pcercuei 0:03b5121a232e 2899 xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
pcercuei 0:03b5121a232e 2900 NULL, NULL);
pcercuei 0:03b5121a232e 2901 FREE_AND_NULL(strA);
pcercuei 0:03b5121a232e 2902 FREE_AND_NULL(strB);
pcercuei 0:03b5121a232e 2903 }
pcercuei 0:03b5121a232e 2904
pcercuei 0:03b5121a232e 2905 /**
pcercuei 0:03b5121a232e 2906 * xmlSchemaPCustomErr:
pcercuei 0:03b5121a232e 2907 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 2908 * @error: the error code
pcercuei 0:03b5121a232e 2909 * @itemDes: the designation of the schema item
pcercuei 0:03b5121a232e 2910 * @item: the schema item
pcercuei 0:03b5121a232e 2911 * @itemElem: the node of the schema item
pcercuei 0:03b5121a232e 2912 * @message: the error message
pcercuei 0:03b5121a232e 2913 * @str1: an optional param for the error message
pcercuei 0:03b5121a232e 2914 * @str2: an optional param for the error message
pcercuei 0:03b5121a232e 2915 * @str3: an optional param for the error message
pcercuei 0:03b5121a232e 2916 *
pcercuei 0:03b5121a232e 2917 * Reports an error during parsing.
pcercuei 0:03b5121a232e 2918 */
pcercuei 0:03b5121a232e 2919 static void
pcercuei 0:03b5121a232e 2920 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 2921 xmlParserErrors error,
pcercuei 0:03b5121a232e 2922 xmlSchemaBasicItemPtr item,
pcercuei 0:03b5121a232e 2923 xmlNodePtr itemElem,
pcercuei 0:03b5121a232e 2924 const char *message,
pcercuei 0:03b5121a232e 2925 const xmlChar *str1,
pcercuei 0:03b5121a232e 2926 const xmlChar *str2,
pcercuei 0:03b5121a232e 2927 const xmlChar *str3)
pcercuei 0:03b5121a232e 2928 {
pcercuei 0:03b5121a232e 2929 xmlChar *des = NULL, *msg = NULL;
pcercuei 0:03b5121a232e 2930
pcercuei 0:03b5121a232e 2931 xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
pcercuei 0:03b5121a232e 2932 msg = xmlStrdup(BAD_CAST "%s: ");
pcercuei 0:03b5121a232e 2933 msg = xmlStrcat(msg, (const xmlChar *) message);
pcercuei 0:03b5121a232e 2934 msg = xmlStrcat(msg, BAD_CAST ".\n");
pcercuei 0:03b5121a232e 2935 if ((itemElem == NULL) && (item != NULL))
pcercuei 0:03b5121a232e 2936 itemElem = WXS_ITEM_NODE(item);
pcercuei 0:03b5121a232e 2937 xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
pcercuei 0:03b5121a232e 2938 (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
pcercuei 0:03b5121a232e 2939 FREE_AND_NULL(des);
pcercuei 0:03b5121a232e 2940 FREE_AND_NULL(msg);
pcercuei 0:03b5121a232e 2941 }
pcercuei 0:03b5121a232e 2942
pcercuei 0:03b5121a232e 2943 /**
pcercuei 0:03b5121a232e 2944 * xmlSchemaPCustomErr:
pcercuei 0:03b5121a232e 2945 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 2946 * @error: the error code
pcercuei 0:03b5121a232e 2947 * @itemDes: the designation of the schema item
pcercuei 0:03b5121a232e 2948 * @item: the schema item
pcercuei 0:03b5121a232e 2949 * @itemElem: the node of the schema item
pcercuei 0:03b5121a232e 2950 * @message: the error message
pcercuei 0:03b5121a232e 2951 * @str1: the optional param for the error message
pcercuei 0:03b5121a232e 2952 *
pcercuei 0:03b5121a232e 2953 * Reports an error during parsing.
pcercuei 0:03b5121a232e 2954 */
pcercuei 0:03b5121a232e 2955 static void
pcercuei 0:03b5121a232e 2956 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 2957 xmlParserErrors error,
pcercuei 0:03b5121a232e 2958 xmlSchemaBasicItemPtr item,
pcercuei 0:03b5121a232e 2959 xmlNodePtr itemElem,
pcercuei 0:03b5121a232e 2960 const char *message,
pcercuei 0:03b5121a232e 2961 const xmlChar *str1)
pcercuei 0:03b5121a232e 2962 {
pcercuei 0:03b5121a232e 2963 xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
pcercuei 0:03b5121a232e 2964 str1, NULL, NULL);
pcercuei 0:03b5121a232e 2965 }
pcercuei 0:03b5121a232e 2966
pcercuei 0:03b5121a232e 2967 /**
pcercuei 0:03b5121a232e 2968 * xmlSchemaPAttrUseErr:
pcercuei 0:03b5121a232e 2969 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 2970 * @error: the error code
pcercuei 0:03b5121a232e 2971 * @itemDes: the designation of the schema type
pcercuei 0:03b5121a232e 2972 * @item: the schema type
pcercuei 0:03b5121a232e 2973 * @itemElem: the node of the schema type
pcercuei 0:03b5121a232e 2974 * @attr: the invalid schema attribute
pcercuei 0:03b5121a232e 2975 * @message: the error message
pcercuei 0:03b5121a232e 2976 * @str1: the optional param for the error message
pcercuei 0:03b5121a232e 2977 *
pcercuei 0:03b5121a232e 2978 * Reports an attribute use error during parsing.
pcercuei 0:03b5121a232e 2979 */
pcercuei 0:03b5121a232e 2980 static void
pcercuei 0:03b5121a232e 2981 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 2982 xmlParserErrors error,
pcercuei 0:03b5121a232e 2983 xmlNodePtr node,
pcercuei 0:03b5121a232e 2984 xmlSchemaBasicItemPtr ownerItem,
pcercuei 0:03b5121a232e 2985 const xmlSchemaAttributeUsePtr attruse,
pcercuei 0:03b5121a232e 2986 const char *message,
pcercuei 0:03b5121a232e 2987 const xmlChar *str1, const xmlChar *str2,
pcercuei 0:03b5121a232e 2988 const xmlChar *str3,const xmlChar *str4)
pcercuei 0:03b5121a232e 2989 {
pcercuei 0:03b5121a232e 2990 xmlChar *str = NULL, *msg = NULL;
pcercuei 0:03b5121a232e 2991
pcercuei 0:03b5121a232e 2992 xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
pcercuei 0:03b5121a232e 2993 msg = xmlStrcat(msg, BAD_CAST ", ");
pcercuei 0:03b5121a232e 2994 msg = xmlStrcat(msg,
pcercuei 0:03b5121a232e 2995 BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
pcercuei 0:03b5121a232e 2996 WXS_BASIC_CAST attruse, NULL));
pcercuei 0:03b5121a232e 2997 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 2998 msg = xmlStrcat(msg, BAD_CAST ": ");
pcercuei 0:03b5121a232e 2999 msg = xmlStrcat(msg, (const xmlChar *) message);
pcercuei 0:03b5121a232e 3000 msg = xmlStrcat(msg, BAD_CAST ".\n");
pcercuei 0:03b5121a232e 3001 xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
pcercuei 0:03b5121a232e 3002 (const char *) msg, str1, str2, str3, str4);
pcercuei 0:03b5121a232e 3003 xmlFree(msg);
pcercuei 0:03b5121a232e 3004 }
pcercuei 0:03b5121a232e 3005
pcercuei 0:03b5121a232e 3006 /**
pcercuei 0:03b5121a232e 3007 * xmlSchemaPIllegalFacetAtomicErr:
pcercuei 0:03b5121a232e 3008 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 3009 * @error: the error code
pcercuei 0:03b5121a232e 3010 * @type: the schema type
pcercuei 0:03b5121a232e 3011 * @baseType: the base type of type
pcercuei 0:03b5121a232e 3012 * @facet: the illegal facet
pcercuei 0:03b5121a232e 3013 *
pcercuei 0:03b5121a232e 3014 * Reports an illegal facet for atomic simple types.
pcercuei 0:03b5121a232e 3015 */
pcercuei 0:03b5121a232e 3016 static void
pcercuei 0:03b5121a232e 3017 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 3018 xmlParserErrors error,
pcercuei 0:03b5121a232e 3019 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 3020 xmlSchemaTypePtr baseType,
pcercuei 0:03b5121a232e 3021 xmlSchemaFacetPtr facet)
pcercuei 0:03b5121a232e 3022 {
pcercuei 0:03b5121a232e 3023 xmlChar *des = NULL, *strT = NULL;
pcercuei 0:03b5121a232e 3024
pcercuei 0:03b5121a232e 3025 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
pcercuei 0:03b5121a232e 3026 xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
pcercuei 0:03b5121a232e 3027 "%s: The facet '%s' is not allowed on types derived from the "
pcercuei 0:03b5121a232e 3028 "type %s.\n",
pcercuei 0:03b5121a232e 3029 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
pcercuei 0:03b5121a232e 3030 xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
pcercuei 0:03b5121a232e 3031 NULL, NULL);
pcercuei 0:03b5121a232e 3032 FREE_AND_NULL(des);
pcercuei 0:03b5121a232e 3033 FREE_AND_NULL(strT);
pcercuei 0:03b5121a232e 3034 }
pcercuei 0:03b5121a232e 3035
pcercuei 0:03b5121a232e 3036 /**
pcercuei 0:03b5121a232e 3037 * xmlSchemaPIllegalFacetListUnionErr:
pcercuei 0:03b5121a232e 3038 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 3039 * @error: the error code
pcercuei 0:03b5121a232e 3040 * @itemDes: the designation of the schema item involved
pcercuei 0:03b5121a232e 3041 * @item: the schema item involved
pcercuei 0:03b5121a232e 3042 * @facet: the illegal facet
pcercuei 0:03b5121a232e 3043 *
pcercuei 0:03b5121a232e 3044 * Reports an illegal facet for <list> and <union>.
pcercuei 0:03b5121a232e 3045 */
pcercuei 0:03b5121a232e 3046 static void
pcercuei 0:03b5121a232e 3047 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 3048 xmlParserErrors error,
pcercuei 0:03b5121a232e 3049 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 3050 xmlSchemaFacetPtr facet)
pcercuei 0:03b5121a232e 3051 {
pcercuei 0:03b5121a232e 3052 xmlChar *des = NULL;
pcercuei 0:03b5121a232e 3053
pcercuei 0:03b5121a232e 3054 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
pcercuei 0:03b5121a232e 3055 type->node);
pcercuei 0:03b5121a232e 3056 xmlSchemaPErr(ctxt, type->node, error,
pcercuei 0:03b5121a232e 3057 "%s: The facet '%s' is not allowed.\n",
pcercuei 0:03b5121a232e 3058 BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
pcercuei 0:03b5121a232e 3059 FREE_AND_NULL(des);
pcercuei 0:03b5121a232e 3060 }
pcercuei 0:03b5121a232e 3061
pcercuei 0:03b5121a232e 3062 /**
pcercuei 0:03b5121a232e 3063 * xmlSchemaPMutualExclAttrErr:
pcercuei 0:03b5121a232e 3064 * @ctxt: the schema validation context
pcercuei 0:03b5121a232e 3065 * @error: the error code
pcercuei 0:03b5121a232e 3066 * @elemDes: the designation of the parent element node
pcercuei 0:03b5121a232e 3067 * @attr: the bad attribute node
pcercuei 0:03b5121a232e 3068 * @type: the corresponding type of the attribute node
pcercuei 0:03b5121a232e 3069 *
pcercuei 0:03b5121a232e 3070 * Reports an illegal attribute.
pcercuei 0:03b5121a232e 3071 */
pcercuei 0:03b5121a232e 3072 static void
pcercuei 0:03b5121a232e 3073 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 3074 xmlParserErrors error,
pcercuei 0:03b5121a232e 3075 xmlSchemaBasicItemPtr ownerItem,
pcercuei 0:03b5121a232e 3076 xmlAttrPtr attr,
pcercuei 0:03b5121a232e 3077 const char *name1,
pcercuei 0:03b5121a232e 3078 const char *name2)
pcercuei 0:03b5121a232e 3079 {
pcercuei 0:03b5121a232e 3080 xmlChar *des = NULL;
pcercuei 0:03b5121a232e 3081
pcercuei 0:03b5121a232e 3082 xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
pcercuei 0:03b5121a232e 3083 xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
pcercuei 0:03b5121a232e 3084 "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
pcercuei 0:03b5121a232e 3085 BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
pcercuei 0:03b5121a232e 3086 FREE_AND_NULL(des);
pcercuei 0:03b5121a232e 3087 }
pcercuei 0:03b5121a232e 3088
pcercuei 0:03b5121a232e 3089 /**
pcercuei 0:03b5121a232e 3090 * xmlSchemaPSimpleTypeErr:
pcercuei 0:03b5121a232e 3091 * @ctxt: the schema validation context
pcercuei 0:03b5121a232e 3092 * @error: the error code
pcercuei 0:03b5121a232e 3093 * @type: the type specifier
pcercuei 0:03b5121a232e 3094 * @ownerDes: the designation of the owner
pcercuei 0:03b5121a232e 3095 * @ownerItem: the schema object if existent
pcercuei 0:03b5121a232e 3096 * @node: the validated node
pcercuei 0:03b5121a232e 3097 * @value: the validated value
pcercuei 0:03b5121a232e 3098 *
pcercuei 0:03b5121a232e 3099 * Reports a simple type validation error.
pcercuei 0:03b5121a232e 3100 * TODO: Should this report the value of an element as well?
pcercuei 0:03b5121a232e 3101 */
pcercuei 0:03b5121a232e 3102 static void
pcercuei 0:03b5121a232e 3103 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 3104 xmlParserErrors error,
pcercuei 0:03b5121a232e 3105 xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 3106 xmlNodePtr node,
pcercuei 0:03b5121a232e 3107 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 3108 const char *expected,
pcercuei 0:03b5121a232e 3109 const xmlChar *value,
pcercuei 0:03b5121a232e 3110 const char *message,
pcercuei 0:03b5121a232e 3111 const xmlChar *str1,
pcercuei 0:03b5121a232e 3112 const xmlChar *str2)
pcercuei 0:03b5121a232e 3113 {
pcercuei 0:03b5121a232e 3114 xmlChar *msg = NULL;
pcercuei 0:03b5121a232e 3115
pcercuei 0:03b5121a232e 3116 xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
pcercuei 0:03b5121a232e 3117 if (message == NULL) {
pcercuei 0:03b5121a232e 3118 /*
pcercuei 0:03b5121a232e 3119 * Use default messages.
pcercuei 0:03b5121a232e 3120 */
pcercuei 0:03b5121a232e 3121 if (type != NULL) {
pcercuei 0:03b5121a232e 3122 if (node->type == XML_ATTRIBUTE_NODE)
pcercuei 0:03b5121a232e 3123 msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
pcercuei 0:03b5121a232e 3124 else
pcercuei 0:03b5121a232e 3125 msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
pcercuei 0:03b5121a232e 3126 "valid value of ");
pcercuei 0:03b5121a232e 3127 if (! xmlSchemaIsGlobalItem(type))
pcercuei 0:03b5121a232e 3128 msg = xmlStrcat(msg, BAD_CAST "the local ");
pcercuei 0:03b5121a232e 3129 else
pcercuei 0:03b5121a232e 3130 msg = xmlStrcat(msg, BAD_CAST "the ");
pcercuei 0:03b5121a232e 3131
pcercuei 0:03b5121a232e 3132 if (WXS_IS_ATOMIC(type))
pcercuei 0:03b5121a232e 3133 msg = xmlStrcat(msg, BAD_CAST "atomic type");
pcercuei 0:03b5121a232e 3134 else if (WXS_IS_LIST(type))
pcercuei 0:03b5121a232e 3135 msg = xmlStrcat(msg, BAD_CAST "list type");
pcercuei 0:03b5121a232e 3136 else if (WXS_IS_UNION(type))
pcercuei 0:03b5121a232e 3137 msg = xmlStrcat(msg, BAD_CAST "union type");
pcercuei 0:03b5121a232e 3138
pcercuei 0:03b5121a232e 3139 if (xmlSchemaIsGlobalItem(type)) {
pcercuei 0:03b5121a232e 3140 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 3141 msg = xmlStrcat(msg, BAD_CAST " '");
pcercuei 0:03b5121a232e 3142 if (type->builtInType != 0) {
pcercuei 0:03b5121a232e 3143 msg = xmlStrcat(msg, BAD_CAST "xs:");
pcercuei 0:03b5121a232e 3144 msg = xmlStrcat(msg, type->name);
pcercuei 0:03b5121a232e 3145 } else
pcercuei 0:03b5121a232e 3146 msg = xmlStrcat(msg,
pcercuei 0:03b5121a232e 3147 xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 3148 type->targetNamespace, type->name));
pcercuei 0:03b5121a232e 3149 msg = xmlStrcat(msg, BAD_CAST "'.");
pcercuei 0:03b5121a232e 3150 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 3151 }
pcercuei 0:03b5121a232e 3152 } else {
pcercuei 0:03b5121a232e 3153 if (node->type == XML_ATTRIBUTE_NODE)
pcercuei 0:03b5121a232e 3154 msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
pcercuei 0:03b5121a232e 3155 else
pcercuei 0:03b5121a232e 3156 msg = xmlStrcat(msg, BAD_CAST "The character content is not "
pcercuei 0:03b5121a232e 3157 "valid.");
pcercuei 0:03b5121a232e 3158 }
pcercuei 0:03b5121a232e 3159 if (expected) {
pcercuei 0:03b5121a232e 3160 msg = xmlStrcat(msg, BAD_CAST " Expected is '");
pcercuei 0:03b5121a232e 3161 msg = xmlStrcat(msg, BAD_CAST expected);
pcercuei 0:03b5121a232e 3162 msg = xmlStrcat(msg, BAD_CAST "'.\n");
pcercuei 0:03b5121a232e 3163 } else
pcercuei 0:03b5121a232e 3164 msg = xmlStrcat(msg, BAD_CAST "\n");
pcercuei 0:03b5121a232e 3165 if (node->type == XML_ATTRIBUTE_NODE)
pcercuei 0:03b5121a232e 3166 xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
pcercuei 0:03b5121a232e 3167 else
pcercuei 0:03b5121a232e 3168 xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
pcercuei 0:03b5121a232e 3169 } else {
pcercuei 0:03b5121a232e 3170 msg = xmlStrcat(msg, BAD_CAST message);
pcercuei 0:03b5121a232e 3171 msg = xmlStrcat(msg, BAD_CAST ".\n");
pcercuei 0:03b5121a232e 3172 xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
pcercuei 0:03b5121a232e 3173 (const char*) msg, str1, str2, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 3174 }
pcercuei 0:03b5121a232e 3175 /* Cleanup. */
pcercuei 0:03b5121a232e 3176 FREE_AND_NULL(msg)
pcercuei 0:03b5121a232e 3177 }
pcercuei 0:03b5121a232e 3178
pcercuei 0:03b5121a232e 3179 /**
pcercuei 0:03b5121a232e 3180 * xmlSchemaPContentErr:
pcercuei 0:03b5121a232e 3181 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 3182 * @error: the error code
pcercuei 0:03b5121a232e 3183 * @onwerDes: the designation of the holder of the content
pcercuei 0:03b5121a232e 3184 * @ownerItem: the owner item of the holder of the content
pcercuei 0:03b5121a232e 3185 * @ownerElem: the node of the holder of the content
pcercuei 0:03b5121a232e 3186 * @child: the invalid child node
pcercuei 0:03b5121a232e 3187 * @message: the optional error message
pcercuei 0:03b5121a232e 3188 * @content: the optional string describing the correct content
pcercuei 0:03b5121a232e 3189 *
pcercuei 0:03b5121a232e 3190 * Reports an error concerning the content of a schema element.
pcercuei 0:03b5121a232e 3191 */
pcercuei 0:03b5121a232e 3192 static void
pcercuei 0:03b5121a232e 3193 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 3194 xmlParserErrors error,
pcercuei 0:03b5121a232e 3195 xmlSchemaBasicItemPtr ownerItem,
pcercuei 0:03b5121a232e 3196 xmlNodePtr ownerElem,
pcercuei 0:03b5121a232e 3197 xmlNodePtr child,
pcercuei 0:03b5121a232e 3198 const char *message,
pcercuei 0:03b5121a232e 3199 const char *content)
pcercuei 0:03b5121a232e 3200 {
pcercuei 0:03b5121a232e 3201 xmlChar *des = NULL;
pcercuei 0:03b5121a232e 3202
pcercuei 0:03b5121a232e 3203 xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
pcercuei 0:03b5121a232e 3204 if (message != NULL)
pcercuei 0:03b5121a232e 3205 xmlSchemaPErr2(ctxt, ownerElem, child, error,
pcercuei 0:03b5121a232e 3206 "%s: %s.\n",
pcercuei 0:03b5121a232e 3207 BAD_CAST des, BAD_CAST message);
pcercuei 0:03b5121a232e 3208 else {
pcercuei 0:03b5121a232e 3209 if (content != NULL) {
pcercuei 0:03b5121a232e 3210 xmlSchemaPErr2(ctxt, ownerElem, child, error,
pcercuei 0:03b5121a232e 3211 "%s: The content is not valid. Expected is %s.\n",
pcercuei 0:03b5121a232e 3212 BAD_CAST des, BAD_CAST content);
pcercuei 0:03b5121a232e 3213 } else {
pcercuei 0:03b5121a232e 3214 xmlSchemaPErr2(ctxt, ownerElem, child, error,
pcercuei 0:03b5121a232e 3215 "%s: The content is not valid.\n",
pcercuei 0:03b5121a232e 3216 BAD_CAST des, NULL);
pcercuei 0:03b5121a232e 3217 }
pcercuei 0:03b5121a232e 3218 }
pcercuei 0:03b5121a232e 3219 FREE_AND_NULL(des)
pcercuei 0:03b5121a232e 3220 }
pcercuei 0:03b5121a232e 3221
pcercuei 0:03b5121a232e 3222 /************************************************************************
pcercuei 0:03b5121a232e 3223 * *
pcercuei 0:03b5121a232e 3224 * Streamable error functions *
pcercuei 0:03b5121a232e 3225 * *
pcercuei 0:03b5121a232e 3226 ************************************************************************/
pcercuei 0:03b5121a232e 3227
pcercuei 0:03b5121a232e 3228
pcercuei 0:03b5121a232e 3229
pcercuei 0:03b5121a232e 3230
pcercuei 0:03b5121a232e 3231 /************************************************************************
pcercuei 0:03b5121a232e 3232 * *
pcercuei 0:03b5121a232e 3233 * Validation helper functions *
pcercuei 0:03b5121a232e 3234 * *
pcercuei 0:03b5121a232e 3235 ************************************************************************/
pcercuei 0:03b5121a232e 3236
pcercuei 0:03b5121a232e 3237
pcercuei 0:03b5121a232e 3238 /************************************************************************
pcercuei 0:03b5121a232e 3239 * *
pcercuei 0:03b5121a232e 3240 * Allocation functions *
pcercuei 0:03b5121a232e 3241 * *
pcercuei 0:03b5121a232e 3242 ************************************************************************/
pcercuei 0:03b5121a232e 3243
pcercuei 0:03b5121a232e 3244 /**
pcercuei 0:03b5121a232e 3245 * xmlSchemaNewSchemaForParserCtxt:
pcercuei 0:03b5121a232e 3246 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 3247 *
pcercuei 0:03b5121a232e 3248 * Allocate a new Schema structure.
pcercuei 0:03b5121a232e 3249 *
pcercuei 0:03b5121a232e 3250 * Returns the newly allocated structure or NULL in case or error
pcercuei 0:03b5121a232e 3251 */
pcercuei 0:03b5121a232e 3252 static xmlSchemaPtr
pcercuei 0:03b5121a232e 3253 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 3254 {
pcercuei 0:03b5121a232e 3255 xmlSchemaPtr ret;
pcercuei 0:03b5121a232e 3256
pcercuei 0:03b5121a232e 3257 ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
pcercuei 0:03b5121a232e 3258 if (ret == NULL) {
pcercuei 0:03b5121a232e 3259 xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
pcercuei 0:03b5121a232e 3260 return (NULL);
pcercuei 0:03b5121a232e 3261 }
pcercuei 0:03b5121a232e 3262 memset(ret, 0, sizeof(xmlSchema));
pcercuei 0:03b5121a232e 3263 ret->dict = ctxt->dict;
pcercuei 0:03b5121a232e 3264 xmlDictReference(ret->dict);
pcercuei 0:03b5121a232e 3265
pcercuei 0:03b5121a232e 3266 return (ret);
pcercuei 0:03b5121a232e 3267 }
pcercuei 0:03b5121a232e 3268
pcercuei 0:03b5121a232e 3269 /**
pcercuei 0:03b5121a232e 3270 * xmlSchemaNewFacet:
pcercuei 0:03b5121a232e 3271 *
pcercuei 0:03b5121a232e 3272 * Allocate a new Facet structure.
pcercuei 0:03b5121a232e 3273 *
pcercuei 0:03b5121a232e 3274 * Returns the newly allocated structure or NULL in case or error
pcercuei 0:03b5121a232e 3275 */
pcercuei 0:03b5121a232e 3276 xmlSchemaFacetPtr
pcercuei 0:03b5121a232e 3277 xmlSchemaNewFacet(void)
pcercuei 0:03b5121a232e 3278 {
pcercuei 0:03b5121a232e 3279 xmlSchemaFacetPtr ret;
pcercuei 0:03b5121a232e 3280
pcercuei 0:03b5121a232e 3281 ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
pcercuei 0:03b5121a232e 3282 if (ret == NULL) {
pcercuei 0:03b5121a232e 3283 return (NULL);
pcercuei 0:03b5121a232e 3284 }
pcercuei 0:03b5121a232e 3285 memset(ret, 0, sizeof(xmlSchemaFacet));
pcercuei 0:03b5121a232e 3286
pcercuei 0:03b5121a232e 3287 return (ret);
pcercuei 0:03b5121a232e 3288 }
pcercuei 0:03b5121a232e 3289
pcercuei 0:03b5121a232e 3290 /**
pcercuei 0:03b5121a232e 3291 * xmlSchemaNewAnnot:
pcercuei 0:03b5121a232e 3292 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 3293 * @node: a node
pcercuei 0:03b5121a232e 3294 *
pcercuei 0:03b5121a232e 3295 * Allocate a new annotation structure.
pcercuei 0:03b5121a232e 3296 *
pcercuei 0:03b5121a232e 3297 * Returns the newly allocated structure or NULL in case or error
pcercuei 0:03b5121a232e 3298 */
pcercuei 0:03b5121a232e 3299 static xmlSchemaAnnotPtr
pcercuei 0:03b5121a232e 3300 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
pcercuei 0:03b5121a232e 3301 {
pcercuei 0:03b5121a232e 3302 xmlSchemaAnnotPtr ret;
pcercuei 0:03b5121a232e 3303
pcercuei 0:03b5121a232e 3304 ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
pcercuei 0:03b5121a232e 3305 if (ret == NULL) {
pcercuei 0:03b5121a232e 3306 xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
pcercuei 0:03b5121a232e 3307 return (NULL);
pcercuei 0:03b5121a232e 3308 }
pcercuei 0:03b5121a232e 3309 memset(ret, 0, sizeof(xmlSchemaAnnot));
pcercuei 0:03b5121a232e 3310 ret->content = node;
pcercuei 0:03b5121a232e 3311 return (ret);
pcercuei 0:03b5121a232e 3312 }
pcercuei 0:03b5121a232e 3313
pcercuei 0:03b5121a232e 3314 static xmlSchemaItemListPtr
pcercuei 0:03b5121a232e 3315 xmlSchemaItemListCreate(void)
pcercuei 0:03b5121a232e 3316 {
pcercuei 0:03b5121a232e 3317 xmlSchemaItemListPtr ret;
pcercuei 0:03b5121a232e 3318
pcercuei 0:03b5121a232e 3319 ret = xmlMalloc(sizeof(xmlSchemaItemList));
pcercuei 0:03b5121a232e 3320 if (ret == NULL) {
pcercuei 0:03b5121a232e 3321 xmlSchemaPErrMemory(NULL,
pcercuei 0:03b5121a232e 3322 "allocating an item list structure", NULL);
pcercuei 0:03b5121a232e 3323 return (NULL);
pcercuei 0:03b5121a232e 3324 }
pcercuei 0:03b5121a232e 3325 memset(ret, 0, sizeof(xmlSchemaItemList));
pcercuei 0:03b5121a232e 3326 return (ret);
pcercuei 0:03b5121a232e 3327 }
pcercuei 0:03b5121a232e 3328
pcercuei 0:03b5121a232e 3329 static void
pcercuei 0:03b5121a232e 3330 xmlSchemaItemListClear(xmlSchemaItemListPtr list)
pcercuei 0:03b5121a232e 3331 {
pcercuei 0:03b5121a232e 3332 if (list->items != NULL) {
pcercuei 0:03b5121a232e 3333 xmlFree(list->items);
pcercuei 0:03b5121a232e 3334 list->items = NULL;
pcercuei 0:03b5121a232e 3335 }
pcercuei 0:03b5121a232e 3336 list->nbItems = 0;
pcercuei 0:03b5121a232e 3337 list->sizeItems = 0;
pcercuei 0:03b5121a232e 3338 }
pcercuei 0:03b5121a232e 3339
pcercuei 0:03b5121a232e 3340 static int
pcercuei 0:03b5121a232e 3341 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
pcercuei 0:03b5121a232e 3342 {
pcercuei 0:03b5121a232e 3343 if (list->items == NULL) {
pcercuei 0:03b5121a232e 3344 list->items = (void **) xmlMalloc(
pcercuei 0:03b5121a232e 3345 20 * sizeof(void *));
pcercuei 0:03b5121a232e 3346 if (list->items == NULL) {
pcercuei 0:03b5121a232e 3347 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
pcercuei 0:03b5121a232e 3348 return(-1);
pcercuei 0:03b5121a232e 3349 }
pcercuei 0:03b5121a232e 3350 list->sizeItems = 20;
pcercuei 0:03b5121a232e 3351 } else if (list->sizeItems <= list->nbItems) {
pcercuei 0:03b5121a232e 3352 list->sizeItems *= 2;
pcercuei 0:03b5121a232e 3353 list->items = (void **) xmlRealloc(list->items,
pcercuei 0:03b5121a232e 3354 list->sizeItems * sizeof(void *));
pcercuei 0:03b5121a232e 3355 if (list->items == NULL) {
pcercuei 0:03b5121a232e 3356 xmlSchemaPErrMemory(NULL, "growing item list", NULL);
pcercuei 0:03b5121a232e 3357 list->sizeItems = 0;
pcercuei 0:03b5121a232e 3358 return(-1);
pcercuei 0:03b5121a232e 3359 }
pcercuei 0:03b5121a232e 3360 }
pcercuei 0:03b5121a232e 3361 list->items[list->nbItems++] = item;
pcercuei 0:03b5121a232e 3362 return(0);
pcercuei 0:03b5121a232e 3363 }
pcercuei 0:03b5121a232e 3364
pcercuei 0:03b5121a232e 3365 static int
pcercuei 0:03b5121a232e 3366 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
pcercuei 0:03b5121a232e 3367 int initialSize,
pcercuei 0:03b5121a232e 3368 void *item)
pcercuei 0:03b5121a232e 3369 {
pcercuei 0:03b5121a232e 3370 if (list->items == NULL) {
pcercuei 0:03b5121a232e 3371 if (initialSize <= 0)
pcercuei 0:03b5121a232e 3372 initialSize = 1;
pcercuei 0:03b5121a232e 3373 list->items = (void **) xmlMalloc(
pcercuei 0:03b5121a232e 3374 initialSize * sizeof(void *));
pcercuei 0:03b5121a232e 3375 if (list->items == NULL) {
pcercuei 0:03b5121a232e 3376 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
pcercuei 0:03b5121a232e 3377 return(-1);
pcercuei 0:03b5121a232e 3378 }
pcercuei 0:03b5121a232e 3379 list->sizeItems = initialSize;
pcercuei 0:03b5121a232e 3380 } else if (list->sizeItems <= list->nbItems) {
pcercuei 0:03b5121a232e 3381 list->sizeItems *= 2;
pcercuei 0:03b5121a232e 3382 list->items = (void **) xmlRealloc(list->items,
pcercuei 0:03b5121a232e 3383 list->sizeItems * sizeof(void *));
pcercuei 0:03b5121a232e 3384 if (list->items == NULL) {
pcercuei 0:03b5121a232e 3385 xmlSchemaPErrMemory(NULL, "growing item list", NULL);
pcercuei 0:03b5121a232e 3386 list->sizeItems = 0;
pcercuei 0:03b5121a232e 3387 return(-1);
pcercuei 0:03b5121a232e 3388 }
pcercuei 0:03b5121a232e 3389 }
pcercuei 0:03b5121a232e 3390 list->items[list->nbItems++] = item;
pcercuei 0:03b5121a232e 3391 return(0);
pcercuei 0:03b5121a232e 3392 }
pcercuei 0:03b5121a232e 3393
pcercuei 0:03b5121a232e 3394 static int
pcercuei 0:03b5121a232e 3395 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
pcercuei 0:03b5121a232e 3396 {
pcercuei 0:03b5121a232e 3397 if (list->items == NULL) {
pcercuei 0:03b5121a232e 3398 list->items = (void **) xmlMalloc(
pcercuei 0:03b5121a232e 3399 20 * sizeof(void *));
pcercuei 0:03b5121a232e 3400 if (list->items == NULL) {
pcercuei 0:03b5121a232e 3401 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
pcercuei 0:03b5121a232e 3402 return(-1);
pcercuei 0:03b5121a232e 3403 }
pcercuei 0:03b5121a232e 3404 list->sizeItems = 20;
pcercuei 0:03b5121a232e 3405 } else if (list->sizeItems <= list->nbItems) {
pcercuei 0:03b5121a232e 3406 list->sizeItems *= 2;
pcercuei 0:03b5121a232e 3407 list->items = (void **) xmlRealloc(list->items,
pcercuei 0:03b5121a232e 3408 list->sizeItems * sizeof(void *));
pcercuei 0:03b5121a232e 3409 if (list->items == NULL) {
pcercuei 0:03b5121a232e 3410 xmlSchemaPErrMemory(NULL, "growing item list", NULL);
pcercuei 0:03b5121a232e 3411 list->sizeItems = 0;
pcercuei 0:03b5121a232e 3412 return(-1);
pcercuei 0:03b5121a232e 3413 }
pcercuei 0:03b5121a232e 3414 }
pcercuei 0:03b5121a232e 3415 /*
pcercuei 0:03b5121a232e 3416 * Just append if the index is greater/equal than the item count.
pcercuei 0:03b5121a232e 3417 */
pcercuei 0:03b5121a232e 3418 if (idx >= list->nbItems) {
pcercuei 0:03b5121a232e 3419 list->items[list->nbItems++] = item;
pcercuei 0:03b5121a232e 3420 } else {
pcercuei 0:03b5121a232e 3421 int i;
pcercuei 0:03b5121a232e 3422 for (i = list->nbItems; i > idx; i--)
pcercuei 0:03b5121a232e 3423 list->items[i] = list->items[i-1];
pcercuei 0:03b5121a232e 3424 list->items[idx] = item;
pcercuei 0:03b5121a232e 3425 list->nbItems++;
pcercuei 0:03b5121a232e 3426 }
pcercuei 0:03b5121a232e 3427 return(0);
pcercuei 0:03b5121a232e 3428 }
pcercuei 0:03b5121a232e 3429
pcercuei 0:03b5121a232e 3430 #if 0 /* enable if ever needed */
pcercuei 0:03b5121a232e 3431 static int
pcercuei 0:03b5121a232e 3432 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
pcercuei 0:03b5121a232e 3433 int initialSize,
pcercuei 0:03b5121a232e 3434 void *item,
pcercuei 0:03b5121a232e 3435 int idx)
pcercuei 0:03b5121a232e 3436 {
pcercuei 0:03b5121a232e 3437 if (list->items == NULL) {
pcercuei 0:03b5121a232e 3438 if (initialSize <= 0)
pcercuei 0:03b5121a232e 3439 initialSize = 1;
pcercuei 0:03b5121a232e 3440 list->items = (void **) xmlMalloc(
pcercuei 0:03b5121a232e 3441 initialSize * sizeof(void *));
pcercuei 0:03b5121a232e 3442 if (list->items == NULL) {
pcercuei 0:03b5121a232e 3443 xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
pcercuei 0:03b5121a232e 3444 return(-1);
pcercuei 0:03b5121a232e 3445 }
pcercuei 0:03b5121a232e 3446 list->sizeItems = initialSize;
pcercuei 0:03b5121a232e 3447 } else if (list->sizeItems <= list->nbItems) {
pcercuei 0:03b5121a232e 3448 list->sizeItems *= 2;
pcercuei 0:03b5121a232e 3449 list->items = (void **) xmlRealloc(list->items,
pcercuei 0:03b5121a232e 3450 list->sizeItems * sizeof(void *));
pcercuei 0:03b5121a232e 3451 if (list->items == NULL) {
pcercuei 0:03b5121a232e 3452 xmlSchemaPErrMemory(NULL, "growing item list", NULL);
pcercuei 0:03b5121a232e 3453 list->sizeItems = 0;
pcercuei 0:03b5121a232e 3454 return(-1);
pcercuei 0:03b5121a232e 3455 }
pcercuei 0:03b5121a232e 3456 }
pcercuei 0:03b5121a232e 3457 /*
pcercuei 0:03b5121a232e 3458 * Just append if the index is greater/equal than the item count.
pcercuei 0:03b5121a232e 3459 */
pcercuei 0:03b5121a232e 3460 if (idx >= list->nbItems) {
pcercuei 0:03b5121a232e 3461 list->items[list->nbItems++] = item;
pcercuei 0:03b5121a232e 3462 } else {
pcercuei 0:03b5121a232e 3463 int i;
pcercuei 0:03b5121a232e 3464 for (i = list->nbItems; i > idx; i--)
pcercuei 0:03b5121a232e 3465 list->items[i] = list->items[i-1];
pcercuei 0:03b5121a232e 3466 list->items[idx] = item;
pcercuei 0:03b5121a232e 3467 list->nbItems++;
pcercuei 0:03b5121a232e 3468 }
pcercuei 0:03b5121a232e 3469 return(0);
pcercuei 0:03b5121a232e 3470 }
pcercuei 0:03b5121a232e 3471 #endif
pcercuei 0:03b5121a232e 3472
pcercuei 0:03b5121a232e 3473 static int
pcercuei 0:03b5121a232e 3474 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
pcercuei 0:03b5121a232e 3475 {
pcercuei 0:03b5121a232e 3476 int i;
pcercuei 0:03b5121a232e 3477 if ((list->items == NULL) || (idx >= list->nbItems)) {
pcercuei 0:03b5121a232e 3478 xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
pcercuei 0:03b5121a232e 3479 "index error.\n");
pcercuei 0:03b5121a232e 3480 return(-1);
pcercuei 0:03b5121a232e 3481 }
pcercuei 0:03b5121a232e 3482
pcercuei 0:03b5121a232e 3483 if (list->nbItems == 1) {
pcercuei 0:03b5121a232e 3484 /* TODO: Really free the list? */
pcercuei 0:03b5121a232e 3485 xmlFree(list->items);
pcercuei 0:03b5121a232e 3486 list->items = NULL;
pcercuei 0:03b5121a232e 3487 list->nbItems = 0;
pcercuei 0:03b5121a232e 3488 list->sizeItems = 0;
pcercuei 0:03b5121a232e 3489 } else if (list->nbItems -1 == idx) {
pcercuei 0:03b5121a232e 3490 list->nbItems--;
pcercuei 0:03b5121a232e 3491 } else {
pcercuei 0:03b5121a232e 3492 for (i = idx; i < list->nbItems -1; i++)
pcercuei 0:03b5121a232e 3493 list->items[i] = list->items[i+1];
pcercuei 0:03b5121a232e 3494 list->nbItems--;
pcercuei 0:03b5121a232e 3495 }
pcercuei 0:03b5121a232e 3496 return(0);
pcercuei 0:03b5121a232e 3497 }
pcercuei 0:03b5121a232e 3498
pcercuei 0:03b5121a232e 3499 /**
pcercuei 0:03b5121a232e 3500 * xmlSchemaItemListFree:
pcercuei 0:03b5121a232e 3501 * @annot: a schema type structure
pcercuei 0:03b5121a232e 3502 *
pcercuei 0:03b5121a232e 3503 * Deallocate a annotation structure
pcercuei 0:03b5121a232e 3504 */
pcercuei 0:03b5121a232e 3505 static void
pcercuei 0:03b5121a232e 3506 xmlSchemaItemListFree(xmlSchemaItemListPtr list)
pcercuei 0:03b5121a232e 3507 {
pcercuei 0:03b5121a232e 3508 if (list == NULL)
pcercuei 0:03b5121a232e 3509 return;
pcercuei 0:03b5121a232e 3510 if (list->items != NULL)
pcercuei 0:03b5121a232e 3511 xmlFree(list->items);
pcercuei 0:03b5121a232e 3512 xmlFree(list);
pcercuei 0:03b5121a232e 3513 }
pcercuei 0:03b5121a232e 3514
pcercuei 0:03b5121a232e 3515 static void
pcercuei 0:03b5121a232e 3516 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
pcercuei 0:03b5121a232e 3517 {
pcercuei 0:03b5121a232e 3518 if (bucket == NULL)
pcercuei 0:03b5121a232e 3519 return;
pcercuei 0:03b5121a232e 3520 if (bucket->globals != NULL) {
pcercuei 0:03b5121a232e 3521 xmlSchemaComponentListFree(bucket->globals);
pcercuei 0:03b5121a232e 3522 xmlSchemaItemListFree(bucket->globals);
pcercuei 0:03b5121a232e 3523 }
pcercuei 0:03b5121a232e 3524 if (bucket->locals != NULL) {
pcercuei 0:03b5121a232e 3525 xmlSchemaComponentListFree(bucket->locals);
pcercuei 0:03b5121a232e 3526 xmlSchemaItemListFree(bucket->locals);
pcercuei 0:03b5121a232e 3527 }
pcercuei 0:03b5121a232e 3528 if (bucket->relations != NULL) {
pcercuei 0:03b5121a232e 3529 xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
pcercuei 0:03b5121a232e 3530 do {
pcercuei 0:03b5121a232e 3531 prev = cur;
pcercuei 0:03b5121a232e 3532 cur = cur->next;
pcercuei 0:03b5121a232e 3533 xmlFree(prev);
pcercuei 0:03b5121a232e 3534 } while (cur != NULL);
pcercuei 0:03b5121a232e 3535 }
pcercuei 0:03b5121a232e 3536 if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
pcercuei 0:03b5121a232e 3537 xmlFreeDoc(bucket->doc);
pcercuei 0:03b5121a232e 3538 }
pcercuei 0:03b5121a232e 3539 if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
pcercuei 0:03b5121a232e 3540 if (WXS_IMPBUCKET(bucket)->schema != NULL)
pcercuei 0:03b5121a232e 3541 xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
pcercuei 0:03b5121a232e 3542 }
pcercuei 0:03b5121a232e 3543 xmlFree(bucket);
pcercuei 0:03b5121a232e 3544 }
pcercuei 0:03b5121a232e 3545
pcercuei 0:03b5121a232e 3546 static xmlSchemaBucketPtr
pcercuei 0:03b5121a232e 3547 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 3548 int type, const xmlChar *targetNamespace)
pcercuei 0:03b5121a232e 3549 {
pcercuei 0:03b5121a232e 3550 xmlSchemaBucketPtr ret;
pcercuei 0:03b5121a232e 3551 int size;
pcercuei 0:03b5121a232e 3552 xmlSchemaPtr mainSchema;
pcercuei 0:03b5121a232e 3553
pcercuei 0:03b5121a232e 3554 if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
pcercuei 0:03b5121a232e 3555 PERROR_INT("xmlSchemaBucketCreate",
pcercuei 0:03b5121a232e 3556 "no main schema on constructor");
pcercuei 0:03b5121a232e 3557 return(NULL);
pcercuei 0:03b5121a232e 3558 }
pcercuei 0:03b5121a232e 3559 mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
pcercuei 0:03b5121a232e 3560 /* Create the schema bucket. */
pcercuei 0:03b5121a232e 3561 if (WXS_IS_BUCKET_INCREDEF(type))
pcercuei 0:03b5121a232e 3562 size = sizeof(xmlSchemaInclude);
pcercuei 0:03b5121a232e 3563 else
pcercuei 0:03b5121a232e 3564 size = sizeof(xmlSchemaImport);
pcercuei 0:03b5121a232e 3565 ret = (xmlSchemaBucketPtr) xmlMalloc(size);
pcercuei 0:03b5121a232e 3566 if (ret == NULL) {
pcercuei 0:03b5121a232e 3567 xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
pcercuei 0:03b5121a232e 3568 return(NULL);
pcercuei 0:03b5121a232e 3569 }
pcercuei 0:03b5121a232e 3570 memset(ret, 0, size);
pcercuei 0:03b5121a232e 3571 ret->targetNamespace = targetNamespace;
pcercuei 0:03b5121a232e 3572 ret->type = type;
pcercuei 0:03b5121a232e 3573 ret->globals = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 3574 if (ret->globals == NULL) {
pcercuei 0:03b5121a232e 3575 xmlFree(ret);
pcercuei 0:03b5121a232e 3576 return(NULL);
pcercuei 0:03b5121a232e 3577 }
pcercuei 0:03b5121a232e 3578 ret->locals = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 3579 if (ret->locals == NULL) {
pcercuei 0:03b5121a232e 3580 xmlFree(ret);
pcercuei 0:03b5121a232e 3581 return(NULL);
pcercuei 0:03b5121a232e 3582 }
pcercuei 0:03b5121a232e 3583 /*
pcercuei 0:03b5121a232e 3584 * The following will assure that only the first bucket is marked as
pcercuei 0:03b5121a232e 3585 * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
pcercuei 0:03b5121a232e 3586 * For each following import buckets an xmlSchema will be created.
pcercuei 0:03b5121a232e 3587 * An xmlSchema will be created for every distinct targetNamespace.
pcercuei 0:03b5121a232e 3588 * We assign the targetNamespace to the schemata here.
pcercuei 0:03b5121a232e 3589 */
pcercuei 0:03b5121a232e 3590 if (! WXS_HAS_BUCKETS(pctxt)) {
pcercuei 0:03b5121a232e 3591 if (WXS_IS_BUCKET_INCREDEF(type)) {
pcercuei 0:03b5121a232e 3592 PERROR_INT("xmlSchemaBucketCreate",
pcercuei 0:03b5121a232e 3593 "first bucket but it's an include or redefine");
pcercuei 0:03b5121a232e 3594 xmlSchemaBucketFree(ret);
pcercuei 0:03b5121a232e 3595 return(NULL);
pcercuei 0:03b5121a232e 3596 }
pcercuei 0:03b5121a232e 3597 /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
pcercuei 0:03b5121a232e 3598 ret->type = XML_SCHEMA_SCHEMA_MAIN;
pcercuei 0:03b5121a232e 3599 /* Point to the *main* schema. */
pcercuei 0:03b5121a232e 3600 WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
pcercuei 0:03b5121a232e 3601 WXS_IMPBUCKET(ret)->schema = mainSchema;
pcercuei 0:03b5121a232e 3602 /*
pcercuei 0:03b5121a232e 3603 * Ensure that the main schema gets a targetNamespace.
pcercuei 0:03b5121a232e 3604 */
pcercuei 0:03b5121a232e 3605 mainSchema->targetNamespace = targetNamespace;
pcercuei 0:03b5121a232e 3606 } else {
pcercuei 0:03b5121a232e 3607 if (type == XML_SCHEMA_SCHEMA_MAIN) {
pcercuei 0:03b5121a232e 3608 PERROR_INT("xmlSchemaBucketCreate",
pcercuei 0:03b5121a232e 3609 "main bucket but it's not the first one");
pcercuei 0:03b5121a232e 3610 xmlSchemaBucketFree(ret);
pcercuei 0:03b5121a232e 3611 return(NULL);
pcercuei 0:03b5121a232e 3612 } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
pcercuei 0:03b5121a232e 3613 /*
pcercuei 0:03b5121a232e 3614 * Create a schema for imports and assign the
pcercuei 0:03b5121a232e 3615 * targetNamespace.
pcercuei 0:03b5121a232e 3616 */
pcercuei 0:03b5121a232e 3617 WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
pcercuei 0:03b5121a232e 3618 if (WXS_IMPBUCKET(ret)->schema == NULL) {
pcercuei 0:03b5121a232e 3619 xmlSchemaBucketFree(ret);
pcercuei 0:03b5121a232e 3620 return(NULL);
pcercuei 0:03b5121a232e 3621 }
pcercuei 0:03b5121a232e 3622 WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
pcercuei 0:03b5121a232e 3623 }
pcercuei 0:03b5121a232e 3624 }
pcercuei 0:03b5121a232e 3625 if (WXS_IS_BUCKET_IMPMAIN(type)) {
pcercuei 0:03b5121a232e 3626 int res;
pcercuei 0:03b5121a232e 3627 /*
pcercuei 0:03b5121a232e 3628 * Imports go into the "schemasImports" slot of the main *schema*.
pcercuei 0:03b5121a232e 3629 * Note that we create an import entry for the main schema as well; i.e.,
pcercuei 0:03b5121a232e 3630 * even if there's only one schema, we'll get an import.
pcercuei 0:03b5121a232e 3631 */
pcercuei 0:03b5121a232e 3632 if (mainSchema->schemasImports == NULL) {
pcercuei 0:03b5121a232e 3633 mainSchema->schemasImports = xmlHashCreateDict(5,
pcercuei 0:03b5121a232e 3634 WXS_CONSTRUCTOR(pctxt)->dict);
pcercuei 0:03b5121a232e 3635 if (mainSchema->schemasImports == NULL) {
pcercuei 0:03b5121a232e 3636 xmlSchemaBucketFree(ret);
pcercuei 0:03b5121a232e 3637 return(NULL);
pcercuei 0:03b5121a232e 3638 }
pcercuei 0:03b5121a232e 3639 }
pcercuei 0:03b5121a232e 3640 if (targetNamespace == NULL)
pcercuei 0:03b5121a232e 3641 res = xmlHashAddEntry(mainSchema->schemasImports,
pcercuei 0:03b5121a232e 3642 XML_SCHEMAS_NO_NAMESPACE, ret);
pcercuei 0:03b5121a232e 3643 else
pcercuei 0:03b5121a232e 3644 res = xmlHashAddEntry(mainSchema->schemasImports,
pcercuei 0:03b5121a232e 3645 targetNamespace, ret);
pcercuei 0:03b5121a232e 3646 if (res != 0) {
pcercuei 0:03b5121a232e 3647 PERROR_INT("xmlSchemaBucketCreate",
pcercuei 0:03b5121a232e 3648 "failed to add the schema bucket to the hash");
pcercuei 0:03b5121a232e 3649 xmlSchemaBucketFree(ret);
pcercuei 0:03b5121a232e 3650 return(NULL);
pcercuei 0:03b5121a232e 3651 }
pcercuei 0:03b5121a232e 3652 } else {
pcercuei 0:03b5121a232e 3653 /* Set the @ownerImport of an include bucket. */
pcercuei 0:03b5121a232e 3654 if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
pcercuei 0:03b5121a232e 3655 WXS_INCBUCKET(ret)->ownerImport =
pcercuei 0:03b5121a232e 3656 WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
pcercuei 0:03b5121a232e 3657 else
pcercuei 0:03b5121a232e 3658 WXS_INCBUCKET(ret)->ownerImport =
pcercuei 0:03b5121a232e 3659 WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
pcercuei 0:03b5121a232e 3660
pcercuei 0:03b5121a232e 3661 /* Includes got into the "includes" slot of the *main* schema. */
pcercuei 0:03b5121a232e 3662 if (mainSchema->includes == NULL) {
pcercuei 0:03b5121a232e 3663 mainSchema->includes = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 3664 if (mainSchema->includes == NULL) {
pcercuei 0:03b5121a232e 3665 xmlSchemaBucketFree(ret);
pcercuei 0:03b5121a232e 3666 return(NULL);
pcercuei 0:03b5121a232e 3667 }
pcercuei 0:03b5121a232e 3668 }
pcercuei 0:03b5121a232e 3669 xmlSchemaItemListAdd(mainSchema->includes, ret);
pcercuei 0:03b5121a232e 3670 }
pcercuei 0:03b5121a232e 3671 /*
pcercuei 0:03b5121a232e 3672 * Add to list of all buckets; this is used for lookup
pcercuei 0:03b5121a232e 3673 * during schema construction time only.
pcercuei 0:03b5121a232e 3674 */
pcercuei 0:03b5121a232e 3675 if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
pcercuei 0:03b5121a232e 3676 return(NULL);
pcercuei 0:03b5121a232e 3677 return(ret);
pcercuei 0:03b5121a232e 3678 }
pcercuei 0:03b5121a232e 3679
pcercuei 0:03b5121a232e 3680 static int
pcercuei 0:03b5121a232e 3681 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
pcercuei 0:03b5121a232e 3682 {
pcercuei 0:03b5121a232e 3683 if (*list == NULL) {
pcercuei 0:03b5121a232e 3684 *list = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 3685 if (*list == NULL)
pcercuei 0:03b5121a232e 3686 return(-1);
pcercuei 0:03b5121a232e 3687 }
pcercuei 0:03b5121a232e 3688 xmlSchemaItemListAddSize(*list, initialSize, item);
pcercuei 0:03b5121a232e 3689 return(0);
pcercuei 0:03b5121a232e 3690 }
pcercuei 0:03b5121a232e 3691
pcercuei 0:03b5121a232e 3692 /**
pcercuei 0:03b5121a232e 3693 * xmlSchemaFreeAnnot:
pcercuei 0:03b5121a232e 3694 * @annot: a schema type structure
pcercuei 0:03b5121a232e 3695 *
pcercuei 0:03b5121a232e 3696 * Deallocate a annotation structure
pcercuei 0:03b5121a232e 3697 */
pcercuei 0:03b5121a232e 3698 static void
pcercuei 0:03b5121a232e 3699 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
pcercuei 0:03b5121a232e 3700 {
pcercuei 0:03b5121a232e 3701 if (annot == NULL)
pcercuei 0:03b5121a232e 3702 return;
pcercuei 0:03b5121a232e 3703 if (annot->next == NULL) {
pcercuei 0:03b5121a232e 3704 xmlFree(annot);
pcercuei 0:03b5121a232e 3705 } else {
pcercuei 0:03b5121a232e 3706 xmlSchemaAnnotPtr prev;
pcercuei 0:03b5121a232e 3707
pcercuei 0:03b5121a232e 3708 do {
pcercuei 0:03b5121a232e 3709 prev = annot;
pcercuei 0:03b5121a232e 3710 annot = annot->next;
pcercuei 0:03b5121a232e 3711 xmlFree(prev);
pcercuei 0:03b5121a232e 3712 } while (annot != NULL);
pcercuei 0:03b5121a232e 3713 }
pcercuei 0:03b5121a232e 3714 }
pcercuei 0:03b5121a232e 3715
pcercuei 0:03b5121a232e 3716 /**
pcercuei 0:03b5121a232e 3717 * xmlSchemaFreeNotation:
pcercuei 0:03b5121a232e 3718 * @schema: a schema notation structure
pcercuei 0:03b5121a232e 3719 *
pcercuei 0:03b5121a232e 3720 * Deallocate a Schema Notation structure.
pcercuei 0:03b5121a232e 3721 */
pcercuei 0:03b5121a232e 3722 static void
pcercuei 0:03b5121a232e 3723 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
pcercuei 0:03b5121a232e 3724 {
pcercuei 0:03b5121a232e 3725 if (nota == NULL)
pcercuei 0:03b5121a232e 3726 return;
pcercuei 0:03b5121a232e 3727 xmlFree(nota);
pcercuei 0:03b5121a232e 3728 }
pcercuei 0:03b5121a232e 3729
pcercuei 0:03b5121a232e 3730 /**
pcercuei 0:03b5121a232e 3731 * xmlSchemaFreeAttribute:
pcercuei 0:03b5121a232e 3732 * @attr: an attribute declaration
pcercuei 0:03b5121a232e 3733 *
pcercuei 0:03b5121a232e 3734 * Deallocates an attribute declaration structure.
pcercuei 0:03b5121a232e 3735 */
pcercuei 0:03b5121a232e 3736 static void
pcercuei 0:03b5121a232e 3737 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
pcercuei 0:03b5121a232e 3738 {
pcercuei 0:03b5121a232e 3739 if (attr == NULL)
pcercuei 0:03b5121a232e 3740 return;
pcercuei 0:03b5121a232e 3741 if (attr->annot != NULL)
pcercuei 0:03b5121a232e 3742 xmlSchemaFreeAnnot(attr->annot);
pcercuei 0:03b5121a232e 3743 if (attr->defVal != NULL)
pcercuei 0:03b5121a232e 3744 xmlSchemaFreeValue(attr->defVal);
pcercuei 0:03b5121a232e 3745 xmlFree(attr);
pcercuei 0:03b5121a232e 3746 }
pcercuei 0:03b5121a232e 3747
pcercuei 0:03b5121a232e 3748 /**
pcercuei 0:03b5121a232e 3749 * xmlSchemaFreeAttributeUse:
pcercuei 0:03b5121a232e 3750 * @use: an attribute use
pcercuei 0:03b5121a232e 3751 *
pcercuei 0:03b5121a232e 3752 * Deallocates an attribute use structure.
pcercuei 0:03b5121a232e 3753 */
pcercuei 0:03b5121a232e 3754 static void
pcercuei 0:03b5121a232e 3755 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
pcercuei 0:03b5121a232e 3756 {
pcercuei 0:03b5121a232e 3757 if (use == NULL)
pcercuei 0:03b5121a232e 3758 return;
pcercuei 0:03b5121a232e 3759 if (use->annot != NULL)
pcercuei 0:03b5121a232e 3760 xmlSchemaFreeAnnot(use->annot);
pcercuei 0:03b5121a232e 3761 if (use->defVal != NULL)
pcercuei 0:03b5121a232e 3762 xmlSchemaFreeValue(use->defVal);
pcercuei 0:03b5121a232e 3763 xmlFree(use);
pcercuei 0:03b5121a232e 3764 }
pcercuei 0:03b5121a232e 3765
pcercuei 0:03b5121a232e 3766 /**
pcercuei 0:03b5121a232e 3767 * xmlSchemaFreeAttributeUseProhib:
pcercuei 0:03b5121a232e 3768 * @prohib: an attribute use prohibition
pcercuei 0:03b5121a232e 3769 *
pcercuei 0:03b5121a232e 3770 * Deallocates an attribute use structure.
pcercuei 0:03b5121a232e 3771 */
pcercuei 0:03b5121a232e 3772 static void
pcercuei 0:03b5121a232e 3773 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
pcercuei 0:03b5121a232e 3774 {
pcercuei 0:03b5121a232e 3775 if (prohib == NULL)
pcercuei 0:03b5121a232e 3776 return;
pcercuei 0:03b5121a232e 3777 xmlFree(prohib);
pcercuei 0:03b5121a232e 3778 }
pcercuei 0:03b5121a232e 3779
pcercuei 0:03b5121a232e 3780 /**
pcercuei 0:03b5121a232e 3781 * xmlSchemaFreeWildcardNsSet:
pcercuei 0:03b5121a232e 3782 * set: a schema wildcard namespace
pcercuei 0:03b5121a232e 3783 *
pcercuei 0:03b5121a232e 3784 * Deallocates a list of wildcard constraint structures.
pcercuei 0:03b5121a232e 3785 */
pcercuei 0:03b5121a232e 3786 static void
pcercuei 0:03b5121a232e 3787 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
pcercuei 0:03b5121a232e 3788 {
pcercuei 0:03b5121a232e 3789 xmlSchemaWildcardNsPtr next;
pcercuei 0:03b5121a232e 3790
pcercuei 0:03b5121a232e 3791 while (set != NULL) {
pcercuei 0:03b5121a232e 3792 next = set->next;
pcercuei 0:03b5121a232e 3793 xmlFree(set);
pcercuei 0:03b5121a232e 3794 set = next;
pcercuei 0:03b5121a232e 3795 }
pcercuei 0:03b5121a232e 3796 }
pcercuei 0:03b5121a232e 3797
pcercuei 0:03b5121a232e 3798 /**
pcercuei 0:03b5121a232e 3799 * xmlSchemaFreeWildcard:
pcercuei 0:03b5121a232e 3800 * @wildcard: a wildcard structure
pcercuei 0:03b5121a232e 3801 *
pcercuei 0:03b5121a232e 3802 * Deallocates a wildcard structure.
pcercuei 0:03b5121a232e 3803 */
pcercuei 0:03b5121a232e 3804 void
pcercuei 0:03b5121a232e 3805 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
pcercuei 0:03b5121a232e 3806 {
pcercuei 0:03b5121a232e 3807 if (wildcard == NULL)
pcercuei 0:03b5121a232e 3808 return;
pcercuei 0:03b5121a232e 3809 if (wildcard->annot != NULL)
pcercuei 0:03b5121a232e 3810 xmlSchemaFreeAnnot(wildcard->annot);
pcercuei 0:03b5121a232e 3811 if (wildcard->nsSet != NULL)
pcercuei 0:03b5121a232e 3812 xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
pcercuei 0:03b5121a232e 3813 if (wildcard->negNsSet != NULL)
pcercuei 0:03b5121a232e 3814 xmlFree(wildcard->negNsSet);
pcercuei 0:03b5121a232e 3815 xmlFree(wildcard);
pcercuei 0:03b5121a232e 3816 }
pcercuei 0:03b5121a232e 3817
pcercuei 0:03b5121a232e 3818 /**
pcercuei 0:03b5121a232e 3819 * xmlSchemaFreeAttributeGroup:
pcercuei 0:03b5121a232e 3820 * @schema: a schema attribute group structure
pcercuei 0:03b5121a232e 3821 *
pcercuei 0:03b5121a232e 3822 * Deallocate a Schema Attribute Group structure.
pcercuei 0:03b5121a232e 3823 */
pcercuei 0:03b5121a232e 3824 static void
pcercuei 0:03b5121a232e 3825 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
pcercuei 0:03b5121a232e 3826 {
pcercuei 0:03b5121a232e 3827 if (attrGr == NULL)
pcercuei 0:03b5121a232e 3828 return;
pcercuei 0:03b5121a232e 3829 if (attrGr->annot != NULL)
pcercuei 0:03b5121a232e 3830 xmlSchemaFreeAnnot(attrGr->annot);
pcercuei 0:03b5121a232e 3831 if (attrGr->attrUses != NULL)
pcercuei 0:03b5121a232e 3832 xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
pcercuei 0:03b5121a232e 3833 xmlFree(attrGr);
pcercuei 0:03b5121a232e 3834 }
pcercuei 0:03b5121a232e 3835
pcercuei 0:03b5121a232e 3836 /**
pcercuei 0:03b5121a232e 3837 * xmlSchemaFreeQNameRef:
pcercuei 0:03b5121a232e 3838 * @item: a QName reference structure
pcercuei 0:03b5121a232e 3839 *
pcercuei 0:03b5121a232e 3840 * Deallocatea a QName reference structure.
pcercuei 0:03b5121a232e 3841 */
pcercuei 0:03b5121a232e 3842 static void
pcercuei 0:03b5121a232e 3843 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
pcercuei 0:03b5121a232e 3844 {
pcercuei 0:03b5121a232e 3845 xmlFree(item);
pcercuei 0:03b5121a232e 3846 }
pcercuei 0:03b5121a232e 3847
pcercuei 0:03b5121a232e 3848 /**
pcercuei 0:03b5121a232e 3849 * xmlSchemaFreeTypeLinkList:
pcercuei 0:03b5121a232e 3850 * @alink: a type link
pcercuei 0:03b5121a232e 3851 *
pcercuei 0:03b5121a232e 3852 * Deallocate a list of types.
pcercuei 0:03b5121a232e 3853 */
pcercuei 0:03b5121a232e 3854 static void
pcercuei 0:03b5121a232e 3855 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
pcercuei 0:03b5121a232e 3856 {
pcercuei 0:03b5121a232e 3857 xmlSchemaTypeLinkPtr next;
pcercuei 0:03b5121a232e 3858
pcercuei 0:03b5121a232e 3859 while (link != NULL) {
pcercuei 0:03b5121a232e 3860 next = link->next;
pcercuei 0:03b5121a232e 3861 xmlFree(link);
pcercuei 0:03b5121a232e 3862 link = next;
pcercuei 0:03b5121a232e 3863 }
pcercuei 0:03b5121a232e 3864 }
pcercuei 0:03b5121a232e 3865
pcercuei 0:03b5121a232e 3866 static void
pcercuei 0:03b5121a232e 3867 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
pcercuei 0:03b5121a232e 3868 {
pcercuei 0:03b5121a232e 3869 xmlSchemaIDCStateObjPtr next;
pcercuei 0:03b5121a232e 3870 while (sto != NULL) {
pcercuei 0:03b5121a232e 3871 next = sto->next;
pcercuei 0:03b5121a232e 3872 if (sto->history != NULL)
pcercuei 0:03b5121a232e 3873 xmlFree(sto->history);
pcercuei 0:03b5121a232e 3874 if (sto->xpathCtxt != NULL)
pcercuei 0:03b5121a232e 3875 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
pcercuei 0:03b5121a232e 3876 xmlFree(sto);
pcercuei 0:03b5121a232e 3877 sto = next;
pcercuei 0:03b5121a232e 3878 }
pcercuei 0:03b5121a232e 3879 }
pcercuei 0:03b5121a232e 3880
pcercuei 0:03b5121a232e 3881 /**
pcercuei 0:03b5121a232e 3882 * xmlSchemaFreeIDC:
pcercuei 0:03b5121a232e 3883 * @idc: a identity-constraint definition
pcercuei 0:03b5121a232e 3884 *
pcercuei 0:03b5121a232e 3885 * Deallocates an identity-constraint definition.
pcercuei 0:03b5121a232e 3886 */
pcercuei 0:03b5121a232e 3887 static void
pcercuei 0:03b5121a232e 3888 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
pcercuei 0:03b5121a232e 3889 {
pcercuei 0:03b5121a232e 3890 xmlSchemaIDCSelectPtr cur, prev;
pcercuei 0:03b5121a232e 3891
pcercuei 0:03b5121a232e 3892 if (idcDef == NULL)
pcercuei 0:03b5121a232e 3893 return;
pcercuei 0:03b5121a232e 3894 if (idcDef->annot != NULL)
pcercuei 0:03b5121a232e 3895 xmlSchemaFreeAnnot(idcDef->annot);
pcercuei 0:03b5121a232e 3896 /* Selector */
pcercuei 0:03b5121a232e 3897 if (idcDef->selector != NULL) {
pcercuei 0:03b5121a232e 3898 if (idcDef->selector->xpathComp != NULL)
pcercuei 0:03b5121a232e 3899 xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
pcercuei 0:03b5121a232e 3900 xmlFree(idcDef->selector);
pcercuei 0:03b5121a232e 3901 }
pcercuei 0:03b5121a232e 3902 /* Fields */
pcercuei 0:03b5121a232e 3903 if (idcDef->fields != NULL) {
pcercuei 0:03b5121a232e 3904 cur = idcDef->fields;
pcercuei 0:03b5121a232e 3905 do {
pcercuei 0:03b5121a232e 3906 prev = cur;
pcercuei 0:03b5121a232e 3907 cur = cur->next;
pcercuei 0:03b5121a232e 3908 if (prev->xpathComp != NULL)
pcercuei 0:03b5121a232e 3909 xmlFreePattern((xmlPatternPtr) prev->xpathComp);
pcercuei 0:03b5121a232e 3910 xmlFree(prev);
pcercuei 0:03b5121a232e 3911 } while (cur != NULL);
pcercuei 0:03b5121a232e 3912 }
pcercuei 0:03b5121a232e 3913 xmlFree(idcDef);
pcercuei 0:03b5121a232e 3914 }
pcercuei 0:03b5121a232e 3915
pcercuei 0:03b5121a232e 3916 /**
pcercuei 0:03b5121a232e 3917 * xmlSchemaFreeElement:
pcercuei 0:03b5121a232e 3918 * @schema: a schema element structure
pcercuei 0:03b5121a232e 3919 *
pcercuei 0:03b5121a232e 3920 * Deallocate a Schema Element structure.
pcercuei 0:03b5121a232e 3921 */
pcercuei 0:03b5121a232e 3922 static void
pcercuei 0:03b5121a232e 3923 xmlSchemaFreeElement(xmlSchemaElementPtr elem)
pcercuei 0:03b5121a232e 3924 {
pcercuei 0:03b5121a232e 3925 if (elem == NULL)
pcercuei 0:03b5121a232e 3926 return;
pcercuei 0:03b5121a232e 3927 if (elem->annot != NULL)
pcercuei 0:03b5121a232e 3928 xmlSchemaFreeAnnot(elem->annot);
pcercuei 0:03b5121a232e 3929 if (elem->contModel != NULL)
pcercuei 0:03b5121a232e 3930 xmlRegFreeRegexp(elem->contModel);
pcercuei 0:03b5121a232e 3931 if (elem->defVal != NULL)
pcercuei 0:03b5121a232e 3932 xmlSchemaFreeValue(elem->defVal);
pcercuei 0:03b5121a232e 3933 xmlFree(elem);
pcercuei 0:03b5121a232e 3934 }
pcercuei 0:03b5121a232e 3935
pcercuei 0:03b5121a232e 3936 /**
pcercuei 0:03b5121a232e 3937 * xmlSchemaFreeFacet:
pcercuei 0:03b5121a232e 3938 * @facet: a schema facet structure
pcercuei 0:03b5121a232e 3939 *
pcercuei 0:03b5121a232e 3940 * Deallocate a Schema Facet structure.
pcercuei 0:03b5121a232e 3941 */
pcercuei 0:03b5121a232e 3942 void
pcercuei 0:03b5121a232e 3943 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
pcercuei 0:03b5121a232e 3944 {
pcercuei 0:03b5121a232e 3945 if (facet == NULL)
pcercuei 0:03b5121a232e 3946 return;
pcercuei 0:03b5121a232e 3947 if (facet->val != NULL)
pcercuei 0:03b5121a232e 3948 xmlSchemaFreeValue(facet->val);
pcercuei 0:03b5121a232e 3949 if (facet->regexp != NULL)
pcercuei 0:03b5121a232e 3950 xmlRegFreeRegexp(facet->regexp);
pcercuei 0:03b5121a232e 3951 if (facet->annot != NULL)
pcercuei 0:03b5121a232e 3952 xmlSchemaFreeAnnot(facet->annot);
pcercuei 0:03b5121a232e 3953 xmlFree(facet);
pcercuei 0:03b5121a232e 3954 }
pcercuei 0:03b5121a232e 3955
pcercuei 0:03b5121a232e 3956 /**
pcercuei 0:03b5121a232e 3957 * xmlSchemaFreeType:
pcercuei 0:03b5121a232e 3958 * @type: a schema type structure
pcercuei 0:03b5121a232e 3959 *
pcercuei 0:03b5121a232e 3960 * Deallocate a Schema Type structure.
pcercuei 0:03b5121a232e 3961 */
pcercuei 0:03b5121a232e 3962 void
pcercuei 0:03b5121a232e 3963 xmlSchemaFreeType(xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 3964 {
pcercuei 0:03b5121a232e 3965 if (type == NULL)
pcercuei 0:03b5121a232e 3966 return;
pcercuei 0:03b5121a232e 3967 if (type->annot != NULL)
pcercuei 0:03b5121a232e 3968 xmlSchemaFreeAnnot(type->annot);
pcercuei 0:03b5121a232e 3969 if (type->facets != NULL) {
pcercuei 0:03b5121a232e 3970 xmlSchemaFacetPtr facet, next;
pcercuei 0:03b5121a232e 3971
pcercuei 0:03b5121a232e 3972 facet = type->facets;
pcercuei 0:03b5121a232e 3973 while (facet != NULL) {
pcercuei 0:03b5121a232e 3974 next = facet->next;
pcercuei 0:03b5121a232e 3975 xmlSchemaFreeFacet(facet);
pcercuei 0:03b5121a232e 3976 facet = next;
pcercuei 0:03b5121a232e 3977 }
pcercuei 0:03b5121a232e 3978 }
pcercuei 0:03b5121a232e 3979 if (type->attrUses != NULL)
pcercuei 0:03b5121a232e 3980 xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
pcercuei 0:03b5121a232e 3981 if (type->memberTypes != NULL)
pcercuei 0:03b5121a232e 3982 xmlSchemaFreeTypeLinkList(type->memberTypes);
pcercuei 0:03b5121a232e 3983 if (type->facetSet != NULL) {
pcercuei 0:03b5121a232e 3984 xmlSchemaFacetLinkPtr next, link;
pcercuei 0:03b5121a232e 3985
pcercuei 0:03b5121a232e 3986 link = type->facetSet;
pcercuei 0:03b5121a232e 3987 do {
pcercuei 0:03b5121a232e 3988 next = link->next;
pcercuei 0:03b5121a232e 3989 xmlFree(link);
pcercuei 0:03b5121a232e 3990 link = next;
pcercuei 0:03b5121a232e 3991 } while (link != NULL);
pcercuei 0:03b5121a232e 3992 }
pcercuei 0:03b5121a232e 3993 if (type->contModel != NULL)
pcercuei 0:03b5121a232e 3994 xmlRegFreeRegexp(type->contModel);
pcercuei 0:03b5121a232e 3995 xmlFree(type);
pcercuei 0:03b5121a232e 3996 }
pcercuei 0:03b5121a232e 3997
pcercuei 0:03b5121a232e 3998 /**
pcercuei 0:03b5121a232e 3999 * xmlSchemaFreeModelGroupDef:
pcercuei 0:03b5121a232e 4000 * @item: a schema model group definition
pcercuei 0:03b5121a232e 4001 *
pcercuei 0:03b5121a232e 4002 * Deallocates a schema model group definition.
pcercuei 0:03b5121a232e 4003 */
pcercuei 0:03b5121a232e 4004 static void
pcercuei 0:03b5121a232e 4005 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
pcercuei 0:03b5121a232e 4006 {
pcercuei 0:03b5121a232e 4007 if (item->annot != NULL)
pcercuei 0:03b5121a232e 4008 xmlSchemaFreeAnnot(item->annot);
pcercuei 0:03b5121a232e 4009 xmlFree(item);
pcercuei 0:03b5121a232e 4010 }
pcercuei 0:03b5121a232e 4011
pcercuei 0:03b5121a232e 4012 /**
pcercuei 0:03b5121a232e 4013 * xmlSchemaFreeModelGroup:
pcercuei 0:03b5121a232e 4014 * @item: a schema model group
pcercuei 0:03b5121a232e 4015 *
pcercuei 0:03b5121a232e 4016 * Deallocates a schema model group structure.
pcercuei 0:03b5121a232e 4017 */
pcercuei 0:03b5121a232e 4018 static void
pcercuei 0:03b5121a232e 4019 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
pcercuei 0:03b5121a232e 4020 {
pcercuei 0:03b5121a232e 4021 if (item->annot != NULL)
pcercuei 0:03b5121a232e 4022 xmlSchemaFreeAnnot(item->annot);
pcercuei 0:03b5121a232e 4023 xmlFree(item);
pcercuei 0:03b5121a232e 4024 }
pcercuei 0:03b5121a232e 4025
pcercuei 0:03b5121a232e 4026 static void
pcercuei 0:03b5121a232e 4027 xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
pcercuei 0:03b5121a232e 4028 {
pcercuei 0:03b5121a232e 4029 if ((list == NULL) || (list->nbItems == 0))
pcercuei 0:03b5121a232e 4030 return;
pcercuei 0:03b5121a232e 4031 {
pcercuei 0:03b5121a232e 4032 xmlSchemaTreeItemPtr item;
pcercuei 0:03b5121a232e 4033 xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
pcercuei 0:03b5121a232e 4034 int i;
pcercuei 0:03b5121a232e 4035
pcercuei 0:03b5121a232e 4036 for (i = 0; i < list->nbItems; i++) {
pcercuei 0:03b5121a232e 4037 item = items[i];
pcercuei 0:03b5121a232e 4038 if (item == NULL)
pcercuei 0:03b5121a232e 4039 continue;
pcercuei 0:03b5121a232e 4040 switch (item->type) {
pcercuei 0:03b5121a232e 4041 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 4042 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 4043 xmlSchemaFreeType((xmlSchemaTypePtr) item);
pcercuei 0:03b5121a232e 4044 break;
pcercuei 0:03b5121a232e 4045 case XML_SCHEMA_TYPE_ATTRIBUTE:
pcercuei 0:03b5121a232e 4046 xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
pcercuei 0:03b5121a232e 4047 break;
pcercuei 0:03b5121a232e 4048 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
pcercuei 0:03b5121a232e 4049 xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
pcercuei 0:03b5121a232e 4050 break;
pcercuei 0:03b5121a232e 4051 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
pcercuei 0:03b5121a232e 4052 xmlSchemaFreeAttributeUseProhib(
pcercuei 0:03b5121a232e 4053 (xmlSchemaAttributeUseProhibPtr) item);
pcercuei 0:03b5121a232e 4054 break;
pcercuei 0:03b5121a232e 4055 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 4056 xmlSchemaFreeElement((xmlSchemaElementPtr) item);
pcercuei 0:03b5121a232e 4057 break;
pcercuei 0:03b5121a232e 4058 case XML_SCHEMA_TYPE_PARTICLE:
pcercuei 0:03b5121a232e 4059 if (item->annot != NULL)
pcercuei 0:03b5121a232e 4060 xmlSchemaFreeAnnot(item->annot);
pcercuei 0:03b5121a232e 4061 xmlFree(item);
pcercuei 0:03b5121a232e 4062 break;
pcercuei 0:03b5121a232e 4063 case XML_SCHEMA_TYPE_SEQUENCE:
pcercuei 0:03b5121a232e 4064 case XML_SCHEMA_TYPE_CHOICE:
pcercuei 0:03b5121a232e 4065 case XML_SCHEMA_TYPE_ALL:
pcercuei 0:03b5121a232e 4066 xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
pcercuei 0:03b5121a232e 4067 break;
pcercuei 0:03b5121a232e 4068 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 4069 xmlSchemaFreeAttributeGroup(
pcercuei 0:03b5121a232e 4070 (xmlSchemaAttributeGroupPtr) item);
pcercuei 0:03b5121a232e 4071 break;
pcercuei 0:03b5121a232e 4072 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 4073 xmlSchemaFreeModelGroupDef(
pcercuei 0:03b5121a232e 4074 (xmlSchemaModelGroupDefPtr) item);
pcercuei 0:03b5121a232e 4075 break;
pcercuei 0:03b5121a232e 4076 case XML_SCHEMA_TYPE_ANY:
pcercuei 0:03b5121a232e 4077 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
pcercuei 0:03b5121a232e 4078 xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
pcercuei 0:03b5121a232e 4079 break;
pcercuei 0:03b5121a232e 4080 case XML_SCHEMA_TYPE_IDC_KEY:
pcercuei 0:03b5121a232e 4081 case XML_SCHEMA_TYPE_IDC_UNIQUE:
pcercuei 0:03b5121a232e 4082 case XML_SCHEMA_TYPE_IDC_KEYREF:
pcercuei 0:03b5121a232e 4083 xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
pcercuei 0:03b5121a232e 4084 break;
pcercuei 0:03b5121a232e 4085 case XML_SCHEMA_TYPE_NOTATION:
pcercuei 0:03b5121a232e 4086 xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
pcercuei 0:03b5121a232e 4087 break;
pcercuei 0:03b5121a232e 4088 case XML_SCHEMA_EXTRA_QNAMEREF:
pcercuei 0:03b5121a232e 4089 xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
pcercuei 0:03b5121a232e 4090 break;
pcercuei 0:03b5121a232e 4091 default: {
pcercuei 0:03b5121a232e 4092 /* TODO: This should never be hit. */
pcercuei 0:03b5121a232e 4093 xmlSchemaPSimpleInternalErr(NULL,
pcercuei 0:03b5121a232e 4094 "Internal error: xmlSchemaComponentListFree, "
pcercuei 0:03b5121a232e 4095 "unexpected component type '%s'\n",
pcercuei 0:03b5121a232e 4096 (const xmlChar *) WXS_ITEM_TYPE_NAME(item));
pcercuei 0:03b5121a232e 4097 }
pcercuei 0:03b5121a232e 4098 break;
pcercuei 0:03b5121a232e 4099 }
pcercuei 0:03b5121a232e 4100 }
pcercuei 0:03b5121a232e 4101 list->nbItems = 0;
pcercuei 0:03b5121a232e 4102 }
pcercuei 0:03b5121a232e 4103 }
pcercuei 0:03b5121a232e 4104
pcercuei 0:03b5121a232e 4105 /**
pcercuei 0:03b5121a232e 4106 * xmlSchemaFree:
pcercuei 0:03b5121a232e 4107 * @schema: a schema structure
pcercuei 0:03b5121a232e 4108 *
pcercuei 0:03b5121a232e 4109 * Deallocate a Schema structure.
pcercuei 0:03b5121a232e 4110 */
pcercuei 0:03b5121a232e 4111 void
pcercuei 0:03b5121a232e 4112 xmlSchemaFree(xmlSchemaPtr schema)
pcercuei 0:03b5121a232e 4113 {
pcercuei 0:03b5121a232e 4114 if (schema == NULL)
pcercuei 0:03b5121a232e 4115 return;
pcercuei 0:03b5121a232e 4116 /* @volatiles is not used anymore :-/ */
pcercuei 0:03b5121a232e 4117 if (schema->volatiles != NULL)
pcercuei 0:03b5121a232e 4118 TODO
pcercuei 0:03b5121a232e 4119 /*
pcercuei 0:03b5121a232e 4120 * Note that those slots are not responsible for freeing
pcercuei 0:03b5121a232e 4121 * schema components anymore; this will now be done by
pcercuei 0:03b5121a232e 4122 * the schema buckets.
pcercuei 0:03b5121a232e 4123 */
pcercuei 0:03b5121a232e 4124 if (schema->notaDecl != NULL)
pcercuei 0:03b5121a232e 4125 xmlHashFree(schema->notaDecl, NULL);
pcercuei 0:03b5121a232e 4126 if (schema->attrDecl != NULL)
pcercuei 0:03b5121a232e 4127 xmlHashFree(schema->attrDecl, NULL);
pcercuei 0:03b5121a232e 4128 if (schema->attrgrpDecl != NULL)
pcercuei 0:03b5121a232e 4129 xmlHashFree(schema->attrgrpDecl, NULL);
pcercuei 0:03b5121a232e 4130 if (schema->elemDecl != NULL)
pcercuei 0:03b5121a232e 4131 xmlHashFree(schema->elemDecl, NULL);
pcercuei 0:03b5121a232e 4132 if (schema->typeDecl != NULL)
pcercuei 0:03b5121a232e 4133 xmlHashFree(schema->typeDecl, NULL);
pcercuei 0:03b5121a232e 4134 if (schema->groupDecl != NULL)
pcercuei 0:03b5121a232e 4135 xmlHashFree(schema->groupDecl, NULL);
pcercuei 0:03b5121a232e 4136 if (schema->idcDef != NULL)
pcercuei 0:03b5121a232e 4137 xmlHashFree(schema->idcDef, NULL);
pcercuei 0:03b5121a232e 4138
pcercuei 0:03b5121a232e 4139 if (schema->schemasImports != NULL)
pcercuei 0:03b5121a232e 4140 xmlHashFree(schema->schemasImports,
pcercuei 0:03b5121a232e 4141 (xmlHashDeallocator) xmlSchemaBucketFree);
pcercuei 0:03b5121a232e 4142 if (schema->includes != NULL) {
pcercuei 0:03b5121a232e 4143 xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
pcercuei 0:03b5121a232e 4144 int i;
pcercuei 0:03b5121a232e 4145 for (i = 0; i < list->nbItems; i++) {
pcercuei 0:03b5121a232e 4146 xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
pcercuei 0:03b5121a232e 4147 }
pcercuei 0:03b5121a232e 4148 xmlSchemaItemListFree(list);
pcercuei 0:03b5121a232e 4149 }
pcercuei 0:03b5121a232e 4150 if (schema->annot != NULL)
pcercuei 0:03b5121a232e 4151 xmlSchemaFreeAnnot(schema->annot);
pcercuei 0:03b5121a232e 4152 /* Never free the doc here, since this will be done by the buckets. */
pcercuei 0:03b5121a232e 4153
pcercuei 0:03b5121a232e 4154 xmlDictFree(schema->dict);
pcercuei 0:03b5121a232e 4155 xmlFree(schema);
pcercuei 0:03b5121a232e 4156 }
pcercuei 0:03b5121a232e 4157
pcercuei 0:03b5121a232e 4158 /************************************************************************
pcercuei 0:03b5121a232e 4159 * *
pcercuei 0:03b5121a232e 4160 * Debug functions *
pcercuei 0:03b5121a232e 4161 * *
pcercuei 0:03b5121a232e 4162 ************************************************************************/
pcercuei 0:03b5121a232e 4163
pcercuei 0:03b5121a232e 4164 #ifdef LIBXML_OUTPUT_ENABLED
pcercuei 0:03b5121a232e 4165
pcercuei 0:03b5121a232e 4166 static void
pcercuei 0:03b5121a232e 4167 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
pcercuei 0:03b5121a232e 4168
pcercuei 0:03b5121a232e 4169 /**
pcercuei 0:03b5121a232e 4170 * xmlSchemaElementDump:
pcercuei 0:03b5121a232e 4171 * @elem: an element
pcercuei 0:03b5121a232e 4172 * @output: the file output
pcercuei 0:03b5121a232e 4173 *
pcercuei 0:03b5121a232e 4174 * Dump the element
pcercuei 0:03b5121a232e 4175 */
pcercuei 0:03b5121a232e 4176 static void
pcercuei 0:03b5121a232e 4177 xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
pcercuei 0:03b5121a232e 4178 const xmlChar * name ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 4179 const xmlChar * namespace ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 4180 const xmlChar * context ATTRIBUTE_UNUSED)
pcercuei 0:03b5121a232e 4181 {
pcercuei 0:03b5121a232e 4182 if (elem == NULL)
pcercuei 0:03b5121a232e 4183 return;
pcercuei 0:03b5121a232e 4184
pcercuei 0:03b5121a232e 4185
pcercuei 0:03b5121a232e 4186 fprintf(output, "Element");
pcercuei 0:03b5121a232e 4187 if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
pcercuei 0:03b5121a232e 4188 fprintf(output, " (global)");
pcercuei 0:03b5121a232e 4189 fprintf(output, ": '%s' ", elem->name);
pcercuei 0:03b5121a232e 4190 if (namespace != NULL)
pcercuei 0:03b5121a232e 4191 fprintf(output, "ns '%s'", namespace);
pcercuei 0:03b5121a232e 4192 fprintf(output, "\n");
pcercuei 0:03b5121a232e 4193 #if 0
pcercuei 0:03b5121a232e 4194 if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
pcercuei 0:03b5121a232e 4195 fprintf(output, " min %d ", elem->minOccurs);
pcercuei 0:03b5121a232e 4196 if (elem->maxOccurs >= UNBOUNDED)
pcercuei 0:03b5121a232e 4197 fprintf(output, "max: unbounded\n");
pcercuei 0:03b5121a232e 4198 else if (elem->maxOccurs != 1)
pcercuei 0:03b5121a232e 4199 fprintf(output, "max: %d\n", elem->maxOccurs);
pcercuei 0:03b5121a232e 4200 else
pcercuei 0:03b5121a232e 4201 fprintf(output, "\n");
pcercuei 0:03b5121a232e 4202 }
pcercuei 0:03b5121a232e 4203 #endif
pcercuei 0:03b5121a232e 4204 /*
pcercuei 0:03b5121a232e 4205 * Misc other properties.
pcercuei 0:03b5121a232e 4206 */
pcercuei 0:03b5121a232e 4207 if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
pcercuei 0:03b5121a232e 4208 (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
pcercuei 0:03b5121a232e 4209 (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
pcercuei 0:03b5121a232e 4210 (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
pcercuei 0:03b5121a232e 4211 fprintf(output, " props: ");
pcercuei 0:03b5121a232e 4212 if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
pcercuei 0:03b5121a232e 4213 fprintf(output, "[fixed] ");
pcercuei 0:03b5121a232e 4214 if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
pcercuei 0:03b5121a232e 4215 fprintf(output, "[default] ");
pcercuei 0:03b5121a232e 4216 if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
pcercuei 0:03b5121a232e 4217 fprintf(output, "[abstract] ");
pcercuei 0:03b5121a232e 4218 if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
pcercuei 0:03b5121a232e 4219 fprintf(output, "[nillable] ");
pcercuei 0:03b5121a232e 4220 fprintf(output, "\n");
pcercuei 0:03b5121a232e 4221 }
pcercuei 0:03b5121a232e 4222 /*
pcercuei 0:03b5121a232e 4223 * Default/fixed value.
pcercuei 0:03b5121a232e 4224 */
pcercuei 0:03b5121a232e 4225 if (elem->value != NULL)
pcercuei 0:03b5121a232e 4226 fprintf(output, " value: '%s'\n", elem->value);
pcercuei 0:03b5121a232e 4227 /*
pcercuei 0:03b5121a232e 4228 * Type.
pcercuei 0:03b5121a232e 4229 */
pcercuei 0:03b5121a232e 4230 if (elem->namedType != NULL) {
pcercuei 0:03b5121a232e 4231 fprintf(output, " type: '%s' ", elem->namedType);
pcercuei 0:03b5121a232e 4232 if (elem->namedTypeNs != NULL)
pcercuei 0:03b5121a232e 4233 fprintf(output, "ns '%s'\n", elem->namedTypeNs);
pcercuei 0:03b5121a232e 4234 else
pcercuei 0:03b5121a232e 4235 fprintf(output, "\n");
pcercuei 0:03b5121a232e 4236 } else if (elem->subtypes != NULL) {
pcercuei 0:03b5121a232e 4237 /*
pcercuei 0:03b5121a232e 4238 * Dump local types.
pcercuei 0:03b5121a232e 4239 */
pcercuei 0:03b5121a232e 4240 xmlSchemaTypeDump(elem->subtypes, output);
pcercuei 0:03b5121a232e 4241 }
pcercuei 0:03b5121a232e 4242 /*
pcercuei 0:03b5121a232e 4243 * Substitution group.
pcercuei 0:03b5121a232e 4244 */
pcercuei 0:03b5121a232e 4245 if (elem->substGroup != NULL) {
pcercuei 0:03b5121a232e 4246 fprintf(output, " substitutionGroup: '%s' ", elem->substGroup);
pcercuei 0:03b5121a232e 4247 if (elem->substGroupNs != NULL)
pcercuei 0:03b5121a232e 4248 fprintf(output, "ns '%s'\n", elem->substGroupNs);
pcercuei 0:03b5121a232e 4249 else
pcercuei 0:03b5121a232e 4250 fprintf(output, "\n");
pcercuei 0:03b5121a232e 4251 }
pcercuei 0:03b5121a232e 4252 }
pcercuei 0:03b5121a232e 4253
pcercuei 0:03b5121a232e 4254 /**
pcercuei 0:03b5121a232e 4255 * xmlSchemaAnnotDump:
pcercuei 0:03b5121a232e 4256 * @output: the file output
pcercuei 0:03b5121a232e 4257 * @annot: a annotation
pcercuei 0:03b5121a232e 4258 *
pcercuei 0:03b5121a232e 4259 * Dump the annotation
pcercuei 0:03b5121a232e 4260 */
pcercuei 0:03b5121a232e 4261 static void
pcercuei 0:03b5121a232e 4262 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
pcercuei 0:03b5121a232e 4263 {
pcercuei 0:03b5121a232e 4264 xmlChar *content;
pcercuei 0:03b5121a232e 4265
pcercuei 0:03b5121a232e 4266 if (annot == NULL)
pcercuei 0:03b5121a232e 4267 return;
pcercuei 0:03b5121a232e 4268
pcercuei 0:03b5121a232e 4269 content = xmlNodeGetContent(annot->content);
pcercuei 0:03b5121a232e 4270 if (content != NULL) {
pcercuei 0:03b5121a232e 4271 fprintf(output, " Annot: %s\n", content);
pcercuei 0:03b5121a232e 4272 xmlFree(content);
pcercuei 0:03b5121a232e 4273 } else
pcercuei 0:03b5121a232e 4274 fprintf(output, " Annot: empty\n");
pcercuei 0:03b5121a232e 4275 }
pcercuei 0:03b5121a232e 4276
pcercuei 0:03b5121a232e 4277 /**
pcercuei 0:03b5121a232e 4278 * xmlSchemaContentModelDump:
pcercuei 0:03b5121a232e 4279 * @particle: the schema particle
pcercuei 0:03b5121a232e 4280 * @output: the file output
pcercuei 0:03b5121a232e 4281 * @depth: the depth used for intentation
pcercuei 0:03b5121a232e 4282 *
pcercuei 0:03b5121a232e 4283 * Dump a SchemaType structure
pcercuei 0:03b5121a232e 4284 */
pcercuei 0:03b5121a232e 4285 static void
pcercuei 0:03b5121a232e 4286 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
pcercuei 0:03b5121a232e 4287 {
pcercuei 0:03b5121a232e 4288 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 4289 xmlSchemaTreeItemPtr term;
pcercuei 0:03b5121a232e 4290 char shift[100];
pcercuei 0:03b5121a232e 4291 int i;
pcercuei 0:03b5121a232e 4292
pcercuei 0:03b5121a232e 4293 if (particle == NULL)
pcercuei 0:03b5121a232e 4294 return;
pcercuei 0:03b5121a232e 4295 for (i = 0;((i < depth) && (i < 25));i++)
pcercuei 0:03b5121a232e 4296 shift[2 * i] = shift[2 * i + 1] = ' ';
pcercuei 0:03b5121a232e 4297 shift[2 * i] = shift[2 * i + 1] = 0;
pcercuei 0:03b5121a232e 4298 fprintf(output, "%s", shift);
pcercuei 0:03b5121a232e 4299 if (particle->children == NULL) {
pcercuei 0:03b5121a232e 4300 fprintf(output, "MISSING particle term\n");
pcercuei 0:03b5121a232e 4301 return;
pcercuei 0:03b5121a232e 4302 }
pcercuei 0:03b5121a232e 4303 term = particle->children;
pcercuei 0:03b5121a232e 4304 if (term == NULL) {
pcercuei 0:03b5121a232e 4305 fprintf(output, "(NULL)");
pcercuei 0:03b5121a232e 4306 } else {
pcercuei 0:03b5121a232e 4307 switch (term->type) {
pcercuei 0:03b5121a232e 4308 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 4309 fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 4310 ((xmlSchemaElementPtr)term)->targetNamespace,
pcercuei 0:03b5121a232e 4311 ((xmlSchemaElementPtr)term)->name));
pcercuei 0:03b5121a232e 4312 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 4313 break;
pcercuei 0:03b5121a232e 4314 case XML_SCHEMA_TYPE_SEQUENCE:
pcercuei 0:03b5121a232e 4315 fprintf(output, "SEQUENCE");
pcercuei 0:03b5121a232e 4316 break;
pcercuei 0:03b5121a232e 4317 case XML_SCHEMA_TYPE_CHOICE:
pcercuei 0:03b5121a232e 4318 fprintf(output, "CHOICE");
pcercuei 0:03b5121a232e 4319 break;
pcercuei 0:03b5121a232e 4320 case XML_SCHEMA_TYPE_ALL:
pcercuei 0:03b5121a232e 4321 fprintf(output, "ALL");
pcercuei 0:03b5121a232e 4322 break;
pcercuei 0:03b5121a232e 4323 case XML_SCHEMA_TYPE_ANY:
pcercuei 0:03b5121a232e 4324 fprintf(output, "ANY");
pcercuei 0:03b5121a232e 4325 break;
pcercuei 0:03b5121a232e 4326 default:
pcercuei 0:03b5121a232e 4327 fprintf(output, "UNKNOWN\n");
pcercuei 0:03b5121a232e 4328 return;
pcercuei 0:03b5121a232e 4329 }
pcercuei 0:03b5121a232e 4330 }
pcercuei 0:03b5121a232e 4331 if (particle->minOccurs != 1)
pcercuei 0:03b5121a232e 4332 fprintf(output, " min: %d", particle->minOccurs);
pcercuei 0:03b5121a232e 4333 if (particle->maxOccurs >= UNBOUNDED)
pcercuei 0:03b5121a232e 4334 fprintf(output, " max: unbounded");
pcercuei 0:03b5121a232e 4335 else if (particle->maxOccurs != 1)
pcercuei 0:03b5121a232e 4336 fprintf(output, " max: %d", particle->maxOccurs);
pcercuei 0:03b5121a232e 4337 fprintf(output, "\n");
pcercuei 0:03b5121a232e 4338 if (term &&
pcercuei 0:03b5121a232e 4339 ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
pcercuei 0:03b5121a232e 4340 (term->type == XML_SCHEMA_TYPE_CHOICE) ||
pcercuei 0:03b5121a232e 4341 (term->type == XML_SCHEMA_TYPE_ALL)) &&
pcercuei 0:03b5121a232e 4342 (term->children != NULL)) {
pcercuei 0:03b5121a232e 4343 xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
pcercuei 0:03b5121a232e 4344 output, depth +1);
pcercuei 0:03b5121a232e 4345 }
pcercuei 0:03b5121a232e 4346 if (particle->next != NULL)
pcercuei 0:03b5121a232e 4347 xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
pcercuei 0:03b5121a232e 4348 output, depth);
pcercuei 0:03b5121a232e 4349 }
pcercuei 0:03b5121a232e 4350
pcercuei 0:03b5121a232e 4351 /**
pcercuei 0:03b5121a232e 4352 * xmlSchemaAttrUsesDump:
pcercuei 0:03b5121a232e 4353 * @uses: attribute uses list
pcercuei 0:03b5121a232e 4354 * @output: the file output
pcercuei 0:03b5121a232e 4355 *
pcercuei 0:03b5121a232e 4356 * Dumps a list of attribute use components.
pcercuei 0:03b5121a232e 4357 */
pcercuei 0:03b5121a232e 4358 static void
pcercuei 0:03b5121a232e 4359 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
pcercuei 0:03b5121a232e 4360 {
pcercuei 0:03b5121a232e 4361 xmlSchemaAttributeUsePtr use;
pcercuei 0:03b5121a232e 4362 xmlSchemaAttributeUseProhibPtr prohib;
pcercuei 0:03b5121a232e 4363 xmlSchemaQNameRefPtr ref;
pcercuei 0:03b5121a232e 4364 const xmlChar *name, *tns;
pcercuei 0:03b5121a232e 4365 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 4366 int i;
pcercuei 0:03b5121a232e 4367
pcercuei 0:03b5121a232e 4368 if ((uses == NULL) || (uses->nbItems == 0))
pcercuei 0:03b5121a232e 4369 return;
pcercuei 0:03b5121a232e 4370
pcercuei 0:03b5121a232e 4371 fprintf(output, " attributes:\n");
pcercuei 0:03b5121a232e 4372 for (i = 0; i < uses->nbItems; i++) {
pcercuei 0:03b5121a232e 4373 use = uses->items[i];
pcercuei 0:03b5121a232e 4374 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
pcercuei 0:03b5121a232e 4375 fprintf(output, " [prohibition] ");
pcercuei 0:03b5121a232e 4376 prohib = (xmlSchemaAttributeUseProhibPtr) use;
pcercuei 0:03b5121a232e 4377 name = prohib->name;
pcercuei 0:03b5121a232e 4378 tns = prohib->targetNamespace;
pcercuei 0:03b5121a232e 4379 } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
pcercuei 0:03b5121a232e 4380 fprintf(output, " [reference] ");
pcercuei 0:03b5121a232e 4381 ref = (xmlSchemaQNameRefPtr) use;
pcercuei 0:03b5121a232e 4382 name = ref->name;
pcercuei 0:03b5121a232e 4383 tns = ref->targetNamespace;
pcercuei 0:03b5121a232e 4384 } else {
pcercuei 0:03b5121a232e 4385 fprintf(output, " [use] ");
pcercuei 0:03b5121a232e 4386 name = WXS_ATTRUSE_DECL_NAME(use);
pcercuei 0:03b5121a232e 4387 tns = WXS_ATTRUSE_DECL_TNS(use);
pcercuei 0:03b5121a232e 4388 }
pcercuei 0:03b5121a232e 4389 fprintf(output, "'%s'\n",
pcercuei 0:03b5121a232e 4390 (const char *) xmlSchemaFormatQName(&str, tns, name));
pcercuei 0:03b5121a232e 4391 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 4392 }
pcercuei 0:03b5121a232e 4393 }
pcercuei 0:03b5121a232e 4394
pcercuei 0:03b5121a232e 4395 /**
pcercuei 0:03b5121a232e 4396 * xmlSchemaTypeDump:
pcercuei 0:03b5121a232e 4397 * @output: the file output
pcercuei 0:03b5121a232e 4398 * @type: a type structure
pcercuei 0:03b5121a232e 4399 *
pcercuei 0:03b5121a232e 4400 * Dump a SchemaType structure
pcercuei 0:03b5121a232e 4401 */
pcercuei 0:03b5121a232e 4402 static void
pcercuei 0:03b5121a232e 4403 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
pcercuei 0:03b5121a232e 4404 {
pcercuei 0:03b5121a232e 4405 if (type == NULL) {
pcercuei 0:03b5121a232e 4406 fprintf(output, "Type: NULL\n");
pcercuei 0:03b5121a232e 4407 return;
pcercuei 0:03b5121a232e 4408 }
pcercuei 0:03b5121a232e 4409 fprintf(output, "Type: ");
pcercuei 0:03b5121a232e 4410 if (type->name != NULL)
pcercuei 0:03b5121a232e 4411 fprintf(output, "'%s' ", type->name);
pcercuei 0:03b5121a232e 4412 else
pcercuei 0:03b5121a232e 4413 fprintf(output, "(no name) ");
pcercuei 0:03b5121a232e 4414 if (type->targetNamespace != NULL)
pcercuei 0:03b5121a232e 4415 fprintf(output, "ns '%s' ", type->targetNamespace);
pcercuei 0:03b5121a232e 4416 switch (type->type) {
pcercuei 0:03b5121a232e 4417 case XML_SCHEMA_TYPE_BASIC:
pcercuei 0:03b5121a232e 4418 fprintf(output, "[basic] ");
pcercuei 0:03b5121a232e 4419 break;
pcercuei 0:03b5121a232e 4420 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 4421 fprintf(output, "[simple] ");
pcercuei 0:03b5121a232e 4422 break;
pcercuei 0:03b5121a232e 4423 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 4424 fprintf(output, "[complex] ");
pcercuei 0:03b5121a232e 4425 break;
pcercuei 0:03b5121a232e 4426 case XML_SCHEMA_TYPE_SEQUENCE:
pcercuei 0:03b5121a232e 4427 fprintf(output, "[sequence] ");
pcercuei 0:03b5121a232e 4428 break;
pcercuei 0:03b5121a232e 4429 case XML_SCHEMA_TYPE_CHOICE:
pcercuei 0:03b5121a232e 4430 fprintf(output, "[choice] ");
pcercuei 0:03b5121a232e 4431 break;
pcercuei 0:03b5121a232e 4432 case XML_SCHEMA_TYPE_ALL:
pcercuei 0:03b5121a232e 4433 fprintf(output, "[all] ");
pcercuei 0:03b5121a232e 4434 break;
pcercuei 0:03b5121a232e 4435 case XML_SCHEMA_TYPE_UR:
pcercuei 0:03b5121a232e 4436 fprintf(output, "[ur] ");
pcercuei 0:03b5121a232e 4437 break;
pcercuei 0:03b5121a232e 4438 case XML_SCHEMA_TYPE_RESTRICTION:
pcercuei 0:03b5121a232e 4439 fprintf(output, "[restriction] ");
pcercuei 0:03b5121a232e 4440 break;
pcercuei 0:03b5121a232e 4441 case XML_SCHEMA_TYPE_EXTENSION:
pcercuei 0:03b5121a232e 4442 fprintf(output, "[extension] ");
pcercuei 0:03b5121a232e 4443 break;
pcercuei 0:03b5121a232e 4444 default:
pcercuei 0:03b5121a232e 4445 fprintf(output, "[unknown type %d] ", type->type);
pcercuei 0:03b5121a232e 4446 break;
pcercuei 0:03b5121a232e 4447 }
pcercuei 0:03b5121a232e 4448 fprintf(output, "content: ");
pcercuei 0:03b5121a232e 4449 switch (type->contentType) {
pcercuei 0:03b5121a232e 4450 case XML_SCHEMA_CONTENT_UNKNOWN:
pcercuei 0:03b5121a232e 4451 fprintf(output, "[unknown] ");
pcercuei 0:03b5121a232e 4452 break;
pcercuei 0:03b5121a232e 4453 case XML_SCHEMA_CONTENT_EMPTY:
pcercuei 0:03b5121a232e 4454 fprintf(output, "[empty] ");
pcercuei 0:03b5121a232e 4455 break;
pcercuei 0:03b5121a232e 4456 case XML_SCHEMA_CONTENT_ELEMENTS:
pcercuei 0:03b5121a232e 4457 fprintf(output, "[element] ");
pcercuei 0:03b5121a232e 4458 break;
pcercuei 0:03b5121a232e 4459 case XML_SCHEMA_CONTENT_MIXED:
pcercuei 0:03b5121a232e 4460 fprintf(output, "[mixed] ");
pcercuei 0:03b5121a232e 4461 break;
pcercuei 0:03b5121a232e 4462 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
pcercuei 0:03b5121a232e 4463 /* not used. */
pcercuei 0:03b5121a232e 4464 break;
pcercuei 0:03b5121a232e 4465 case XML_SCHEMA_CONTENT_BASIC:
pcercuei 0:03b5121a232e 4466 fprintf(output, "[basic] ");
pcercuei 0:03b5121a232e 4467 break;
pcercuei 0:03b5121a232e 4468 case XML_SCHEMA_CONTENT_SIMPLE:
pcercuei 0:03b5121a232e 4469 fprintf(output, "[simple] ");
pcercuei 0:03b5121a232e 4470 break;
pcercuei 0:03b5121a232e 4471 case XML_SCHEMA_CONTENT_ANY:
pcercuei 0:03b5121a232e 4472 fprintf(output, "[any] ");
pcercuei 0:03b5121a232e 4473 break;
pcercuei 0:03b5121a232e 4474 }
pcercuei 0:03b5121a232e 4475 fprintf(output, "\n");
pcercuei 0:03b5121a232e 4476 if (type->base != NULL) {
pcercuei 0:03b5121a232e 4477 fprintf(output, " base type: '%s'", type->base);
pcercuei 0:03b5121a232e 4478 if (type->baseNs != NULL)
pcercuei 0:03b5121a232e 4479 fprintf(output, " ns '%s'\n", type->baseNs);
pcercuei 0:03b5121a232e 4480 else
pcercuei 0:03b5121a232e 4481 fprintf(output, "\n");
pcercuei 0:03b5121a232e 4482 }
pcercuei 0:03b5121a232e 4483 if (type->attrUses != NULL)
pcercuei 0:03b5121a232e 4484 xmlSchemaAttrUsesDump(type->attrUses, output);
pcercuei 0:03b5121a232e 4485 if (type->annot != NULL)
pcercuei 0:03b5121a232e 4486 xmlSchemaAnnotDump(output, type->annot);
pcercuei 0:03b5121a232e 4487 #ifdef DUMP_CONTENT_MODEL
pcercuei 0:03b5121a232e 4488 if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
pcercuei 0:03b5121a232e 4489 (type->subtypes != NULL)) {
pcercuei 0:03b5121a232e 4490 xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
pcercuei 0:03b5121a232e 4491 output, 1);
pcercuei 0:03b5121a232e 4492 }
pcercuei 0:03b5121a232e 4493 #endif
pcercuei 0:03b5121a232e 4494 }
pcercuei 0:03b5121a232e 4495
pcercuei 0:03b5121a232e 4496 /**
pcercuei 0:03b5121a232e 4497 * xmlSchemaDump:
pcercuei 0:03b5121a232e 4498 * @output: the file output
pcercuei 0:03b5121a232e 4499 * @schema: a schema structure
pcercuei 0:03b5121a232e 4500 *
pcercuei 0:03b5121a232e 4501 * Dump a Schema structure.
pcercuei 0:03b5121a232e 4502 */
pcercuei 0:03b5121a232e 4503 void
pcercuei 0:03b5121a232e 4504 xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
pcercuei 0:03b5121a232e 4505 {
pcercuei 0:03b5121a232e 4506 if (output == NULL)
pcercuei 0:03b5121a232e 4507 return;
pcercuei 0:03b5121a232e 4508 if (schema == NULL) {
pcercuei 0:03b5121a232e 4509 fprintf(output, "Schemas: NULL\n");
pcercuei 0:03b5121a232e 4510 return;
pcercuei 0:03b5121a232e 4511 }
pcercuei 0:03b5121a232e 4512 fprintf(output, "Schemas: ");
pcercuei 0:03b5121a232e 4513 if (schema->name != NULL)
pcercuei 0:03b5121a232e 4514 fprintf(output, "%s, ", schema->name);
pcercuei 0:03b5121a232e 4515 else
pcercuei 0:03b5121a232e 4516 fprintf(output, "no name, ");
pcercuei 0:03b5121a232e 4517 if (schema->targetNamespace != NULL)
pcercuei 0:03b5121a232e 4518 fprintf(output, "%s", (const char *) schema->targetNamespace);
pcercuei 0:03b5121a232e 4519 else
pcercuei 0:03b5121a232e 4520 fprintf(output, "no target namespace");
pcercuei 0:03b5121a232e 4521 fprintf(output, "\n");
pcercuei 0:03b5121a232e 4522 if (schema->annot != NULL)
pcercuei 0:03b5121a232e 4523 xmlSchemaAnnotDump(output, schema->annot);
pcercuei 0:03b5121a232e 4524 xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
pcercuei 0:03b5121a232e 4525 output);
pcercuei 0:03b5121a232e 4526 xmlHashScanFull(schema->elemDecl,
pcercuei 0:03b5121a232e 4527 (xmlHashScannerFull) xmlSchemaElementDump, output);
pcercuei 0:03b5121a232e 4528 }
pcercuei 0:03b5121a232e 4529
pcercuei 0:03b5121a232e 4530 #ifdef DEBUG_IDC_NODE_TABLE
pcercuei 0:03b5121a232e 4531 /**
pcercuei 0:03b5121a232e 4532 * xmlSchemaDebugDumpIDCTable:
pcercuei 0:03b5121a232e 4533 * @vctxt: the WXS validation context
pcercuei 0:03b5121a232e 4534 *
pcercuei 0:03b5121a232e 4535 * Displays the current IDC table for debug purposes.
pcercuei 0:03b5121a232e 4536 */
pcercuei 0:03b5121a232e 4537 static void
pcercuei 0:03b5121a232e 4538 xmlSchemaDebugDumpIDCTable(FILE * output,
pcercuei 0:03b5121a232e 4539 const xmlChar *namespaceName,
pcercuei 0:03b5121a232e 4540 const xmlChar *localName,
pcercuei 0:03b5121a232e 4541 xmlSchemaPSVIIDCBindingPtr bind)
pcercuei 0:03b5121a232e 4542 {
pcercuei 0:03b5121a232e 4543 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 4544 const xmlChar *value;
pcercuei 0:03b5121a232e 4545 xmlSchemaPSVIIDCNodePtr tab;
pcercuei 0:03b5121a232e 4546 xmlSchemaPSVIIDCKeyPtr key;
pcercuei 0:03b5121a232e 4547 int i, j, res;
pcercuei 0:03b5121a232e 4548
pcercuei 0:03b5121a232e 4549 fprintf(output, "IDC: TABLES on '%s'\n",
pcercuei 0:03b5121a232e 4550 xmlSchemaFormatQName(&str, namespaceName, localName));
pcercuei 0:03b5121a232e 4551 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 4552
pcercuei 0:03b5121a232e 4553 if (bind == NULL)
pcercuei 0:03b5121a232e 4554 return;
pcercuei 0:03b5121a232e 4555 do {
pcercuei 0:03b5121a232e 4556 fprintf(output, "IDC: BINDING '%s' (%d)\n",
pcercuei 0:03b5121a232e 4557 xmlSchemaGetComponentQName(&str,
pcercuei 0:03b5121a232e 4558 bind->definition), bind->nbNodes);
pcercuei 0:03b5121a232e 4559 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 4560 for (i = 0; i < bind->nbNodes; i++) {
pcercuei 0:03b5121a232e 4561 tab = bind->nodeTable[i];
pcercuei 0:03b5121a232e 4562 fprintf(output, " ( ");
pcercuei 0:03b5121a232e 4563 for (j = 0; j < bind->definition->nbFields; j++) {
pcercuei 0:03b5121a232e 4564 key = tab->keys[j];
pcercuei 0:03b5121a232e 4565 if ((key != NULL) && (key->val != NULL)) {
pcercuei 0:03b5121a232e 4566 res = xmlSchemaGetCanonValue(key->val, &value);
pcercuei 0:03b5121a232e 4567 if (res >= 0)
pcercuei 0:03b5121a232e 4568 fprintf(output, "'%s' ", value);
pcercuei 0:03b5121a232e 4569 else
pcercuei 0:03b5121a232e 4570 fprintf(output, "CANON-VALUE-FAILED ");
pcercuei 0:03b5121a232e 4571 if (res == 0)
pcercuei 0:03b5121a232e 4572 FREE_AND_NULL(value)
pcercuei 0:03b5121a232e 4573 } else if (key != NULL)
pcercuei 0:03b5121a232e 4574 fprintf(output, "(no val), ");
pcercuei 0:03b5121a232e 4575 else
pcercuei 0:03b5121a232e 4576 fprintf(output, "(key missing), ");
pcercuei 0:03b5121a232e 4577 }
pcercuei 0:03b5121a232e 4578 fprintf(output, ")\n");
pcercuei 0:03b5121a232e 4579 }
pcercuei 0:03b5121a232e 4580 if (bind->dupls && bind->dupls->nbItems) {
pcercuei 0:03b5121a232e 4581 fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems);
pcercuei 0:03b5121a232e 4582 for (i = 0; i < bind->dupls->nbItems; i++) {
pcercuei 0:03b5121a232e 4583 tab = bind->dupls->items[i];
pcercuei 0:03b5121a232e 4584 fprintf(output, " ( ");
pcercuei 0:03b5121a232e 4585 for (j = 0; j < bind->definition->nbFields; j++) {
pcercuei 0:03b5121a232e 4586 key = tab->keys[j];
pcercuei 0:03b5121a232e 4587 if ((key != NULL) && (key->val != NULL)) {
pcercuei 0:03b5121a232e 4588 res = xmlSchemaGetCanonValue(key->val, &value);
pcercuei 0:03b5121a232e 4589 if (res >= 0)
pcercuei 0:03b5121a232e 4590 fprintf(output, "'%s' ", value);
pcercuei 0:03b5121a232e 4591 else
pcercuei 0:03b5121a232e 4592 fprintf(output, "CANON-VALUE-FAILED ");
pcercuei 0:03b5121a232e 4593 if (res == 0)
pcercuei 0:03b5121a232e 4594 FREE_AND_NULL(value)
pcercuei 0:03b5121a232e 4595 } else if (key != NULL)
pcercuei 0:03b5121a232e 4596 fprintf(output, "(no val), ");
pcercuei 0:03b5121a232e 4597 else
pcercuei 0:03b5121a232e 4598 fprintf(output, "(key missing), ");
pcercuei 0:03b5121a232e 4599 }
pcercuei 0:03b5121a232e 4600 fprintf(output, ")\n");
pcercuei 0:03b5121a232e 4601 }
pcercuei 0:03b5121a232e 4602 }
pcercuei 0:03b5121a232e 4603 bind = bind->next;
pcercuei 0:03b5121a232e 4604 } while (bind != NULL);
pcercuei 0:03b5121a232e 4605 }
pcercuei 0:03b5121a232e 4606 #endif /* DEBUG_IDC */
pcercuei 0:03b5121a232e 4607 #endif /* LIBXML_OUTPUT_ENABLED */
pcercuei 0:03b5121a232e 4608
pcercuei 0:03b5121a232e 4609 /************************************************************************
pcercuei 0:03b5121a232e 4610 * *
pcercuei 0:03b5121a232e 4611 * Utilities *
pcercuei 0:03b5121a232e 4612 * *
pcercuei 0:03b5121a232e 4613 ************************************************************************/
pcercuei 0:03b5121a232e 4614
pcercuei 0:03b5121a232e 4615 /**
pcercuei 0:03b5121a232e 4616 * xmlSchemaGetPropNode:
pcercuei 0:03b5121a232e 4617 * @node: the element node
pcercuei 0:03b5121a232e 4618 * @name: the name of the attribute
pcercuei 0:03b5121a232e 4619 *
pcercuei 0:03b5121a232e 4620 * Seeks an attribute with a name of @name in
pcercuei 0:03b5121a232e 4621 * no namespace.
pcercuei 0:03b5121a232e 4622 *
pcercuei 0:03b5121a232e 4623 * Returns the attribute or NULL if not present.
pcercuei 0:03b5121a232e 4624 */
pcercuei 0:03b5121a232e 4625 static xmlAttrPtr
pcercuei 0:03b5121a232e 4626 xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
pcercuei 0:03b5121a232e 4627 {
pcercuei 0:03b5121a232e 4628 xmlAttrPtr prop;
pcercuei 0:03b5121a232e 4629
pcercuei 0:03b5121a232e 4630 if ((node == NULL) || (name == NULL))
pcercuei 0:03b5121a232e 4631 return(NULL);
pcercuei 0:03b5121a232e 4632 prop = node->properties;
pcercuei 0:03b5121a232e 4633 while (prop != NULL) {
pcercuei 0:03b5121a232e 4634 if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
pcercuei 0:03b5121a232e 4635 return(prop);
pcercuei 0:03b5121a232e 4636 prop = prop->next;
pcercuei 0:03b5121a232e 4637 }
pcercuei 0:03b5121a232e 4638 return (NULL);
pcercuei 0:03b5121a232e 4639 }
pcercuei 0:03b5121a232e 4640
pcercuei 0:03b5121a232e 4641 /**
pcercuei 0:03b5121a232e 4642 * xmlSchemaGetPropNodeNs:
pcercuei 0:03b5121a232e 4643 * @node: the element node
pcercuei 0:03b5121a232e 4644 * @uri: the uri
pcercuei 0:03b5121a232e 4645 * @name: the name of the attribute
pcercuei 0:03b5121a232e 4646 *
pcercuei 0:03b5121a232e 4647 * Seeks an attribute with a local name of @name and
pcercuei 0:03b5121a232e 4648 * a namespace URI of @uri.
pcercuei 0:03b5121a232e 4649 *
pcercuei 0:03b5121a232e 4650 * Returns the attribute or NULL if not present.
pcercuei 0:03b5121a232e 4651 */
pcercuei 0:03b5121a232e 4652 static xmlAttrPtr
pcercuei 0:03b5121a232e 4653 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
pcercuei 0:03b5121a232e 4654 {
pcercuei 0:03b5121a232e 4655 xmlAttrPtr prop;
pcercuei 0:03b5121a232e 4656
pcercuei 0:03b5121a232e 4657 if ((node == NULL) || (name == NULL))
pcercuei 0:03b5121a232e 4658 return(NULL);
pcercuei 0:03b5121a232e 4659 prop = node->properties;
pcercuei 0:03b5121a232e 4660 while (prop != NULL) {
pcercuei 0:03b5121a232e 4661 if ((prop->ns != NULL) &&
pcercuei 0:03b5121a232e 4662 xmlStrEqual(prop->name, BAD_CAST name) &&
pcercuei 0:03b5121a232e 4663 xmlStrEqual(prop->ns->href, BAD_CAST uri))
pcercuei 0:03b5121a232e 4664 return(prop);
pcercuei 0:03b5121a232e 4665 prop = prop->next;
pcercuei 0:03b5121a232e 4666 }
pcercuei 0:03b5121a232e 4667 return (NULL);
pcercuei 0:03b5121a232e 4668 }
pcercuei 0:03b5121a232e 4669
pcercuei 0:03b5121a232e 4670 static const xmlChar *
pcercuei 0:03b5121a232e 4671 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
pcercuei 0:03b5121a232e 4672 {
pcercuei 0:03b5121a232e 4673 xmlChar *val;
pcercuei 0:03b5121a232e 4674 const xmlChar *ret;
pcercuei 0:03b5121a232e 4675
pcercuei 0:03b5121a232e 4676 val = xmlNodeGetContent(node);
pcercuei 0:03b5121a232e 4677 if (val == NULL)
pcercuei 0:03b5121a232e 4678 val = xmlStrdup((xmlChar *)"");
pcercuei 0:03b5121a232e 4679 ret = xmlDictLookup(ctxt->dict, val, -1);
pcercuei 0:03b5121a232e 4680 xmlFree(val);
pcercuei 0:03b5121a232e 4681 return(ret);
pcercuei 0:03b5121a232e 4682 }
pcercuei 0:03b5121a232e 4683
pcercuei 0:03b5121a232e 4684 static const xmlChar *
pcercuei 0:03b5121a232e 4685 xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
pcercuei 0:03b5121a232e 4686 {
pcercuei 0:03b5121a232e 4687 return((const xmlChar*) xmlNodeGetContent(node));
pcercuei 0:03b5121a232e 4688 }
pcercuei 0:03b5121a232e 4689
pcercuei 0:03b5121a232e 4690 /**
pcercuei 0:03b5121a232e 4691 * xmlSchemaGetProp:
pcercuei 0:03b5121a232e 4692 * @ctxt: the parser context
pcercuei 0:03b5121a232e 4693 * @node: the node
pcercuei 0:03b5121a232e 4694 * @name: the property name
pcercuei 0:03b5121a232e 4695 *
pcercuei 0:03b5121a232e 4696 * Read a attribute value and internalize the string
pcercuei 0:03b5121a232e 4697 *
pcercuei 0:03b5121a232e 4698 * Returns the string or NULL if not present.
pcercuei 0:03b5121a232e 4699 */
pcercuei 0:03b5121a232e 4700 static const xmlChar *
pcercuei 0:03b5121a232e 4701 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
pcercuei 0:03b5121a232e 4702 const char *name)
pcercuei 0:03b5121a232e 4703 {
pcercuei 0:03b5121a232e 4704 xmlChar *val;
pcercuei 0:03b5121a232e 4705 const xmlChar *ret;
pcercuei 0:03b5121a232e 4706
pcercuei 0:03b5121a232e 4707 val = xmlGetNoNsProp(node, BAD_CAST name);
pcercuei 0:03b5121a232e 4708 if (val == NULL)
pcercuei 0:03b5121a232e 4709 return(NULL);
pcercuei 0:03b5121a232e 4710 ret = xmlDictLookup(ctxt->dict, val, -1);
pcercuei 0:03b5121a232e 4711 xmlFree(val);
pcercuei 0:03b5121a232e 4712 return(ret);
pcercuei 0:03b5121a232e 4713 }
pcercuei 0:03b5121a232e 4714
pcercuei 0:03b5121a232e 4715 /************************************************************************
pcercuei 0:03b5121a232e 4716 * *
pcercuei 0:03b5121a232e 4717 * Parsing functions *
pcercuei 0:03b5121a232e 4718 * *
pcercuei 0:03b5121a232e 4719 ************************************************************************/
pcercuei 0:03b5121a232e 4720
pcercuei 0:03b5121a232e 4721 #define WXS_FIND_GLOBAL_ITEM(slot) \
pcercuei 0:03b5121a232e 4722 if (xmlStrEqual(nsName, schema->targetNamespace)) { \
pcercuei 0:03b5121a232e 4723 ret = xmlHashLookup(schema->slot, name); \
pcercuei 0:03b5121a232e 4724 if (ret != NULL) goto exit; \
pcercuei 0:03b5121a232e 4725 } \
pcercuei 0:03b5121a232e 4726 if (xmlHashSize(schema->schemasImports) > 1) { \
pcercuei 0:03b5121a232e 4727 xmlSchemaImportPtr import; \
pcercuei 0:03b5121a232e 4728 if (nsName == NULL) \
pcercuei 0:03b5121a232e 4729 import = xmlHashLookup(schema->schemasImports, \
pcercuei 0:03b5121a232e 4730 XML_SCHEMAS_NO_NAMESPACE); \
pcercuei 0:03b5121a232e 4731 else \
pcercuei 0:03b5121a232e 4732 import = xmlHashLookup(schema->schemasImports, nsName); \
pcercuei 0:03b5121a232e 4733 if (import == NULL) \
pcercuei 0:03b5121a232e 4734 goto exit; \
pcercuei 0:03b5121a232e 4735 ret = xmlHashLookup(import->schema->slot, name); \
pcercuei 0:03b5121a232e 4736 }
pcercuei 0:03b5121a232e 4737
pcercuei 0:03b5121a232e 4738 /**
pcercuei 0:03b5121a232e 4739 * xmlSchemaGetElem:
pcercuei 0:03b5121a232e 4740 * @schema: the schema context
pcercuei 0:03b5121a232e 4741 * @name: the element name
pcercuei 0:03b5121a232e 4742 * @ns: the element namespace
pcercuei 0:03b5121a232e 4743 *
pcercuei 0:03b5121a232e 4744 * Lookup a global element declaration in the schema.
pcercuei 0:03b5121a232e 4745 *
pcercuei 0:03b5121a232e 4746 * Returns the element declaration or NULL if not found.
pcercuei 0:03b5121a232e 4747 */
pcercuei 0:03b5121a232e 4748 static xmlSchemaElementPtr
pcercuei 0:03b5121a232e 4749 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
pcercuei 0:03b5121a232e 4750 const xmlChar * nsName)
pcercuei 0:03b5121a232e 4751 {
pcercuei 0:03b5121a232e 4752 xmlSchemaElementPtr ret = NULL;
pcercuei 0:03b5121a232e 4753
pcercuei 0:03b5121a232e 4754 if ((name == NULL) || (schema == NULL))
pcercuei 0:03b5121a232e 4755 return(NULL);
pcercuei 0:03b5121a232e 4756 if (schema != NULL) {
pcercuei 0:03b5121a232e 4757 WXS_FIND_GLOBAL_ITEM(elemDecl)
pcercuei 0:03b5121a232e 4758 }
pcercuei 0:03b5121a232e 4759 exit:
pcercuei 0:03b5121a232e 4760 #ifdef DEBUG
pcercuei 0:03b5121a232e 4761 if (ret == NULL) {
pcercuei 0:03b5121a232e 4762 if (nsName == NULL)
pcercuei 0:03b5121a232e 4763 fprintf(stderr, "Unable to lookup element decl. %s", name);
pcercuei 0:03b5121a232e 4764 else
pcercuei 0:03b5121a232e 4765 fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
pcercuei 0:03b5121a232e 4766 nsName);
pcercuei 0:03b5121a232e 4767 }
pcercuei 0:03b5121a232e 4768 #endif
pcercuei 0:03b5121a232e 4769 return (ret);
pcercuei 0:03b5121a232e 4770 }
pcercuei 0:03b5121a232e 4771
pcercuei 0:03b5121a232e 4772 /**
pcercuei 0:03b5121a232e 4773 * xmlSchemaGetType:
pcercuei 0:03b5121a232e 4774 * @schema: the main schema
pcercuei 0:03b5121a232e 4775 * @name: the type's name
pcercuei 0:03b5121a232e 4776 * nsName: the type's namespace
pcercuei 0:03b5121a232e 4777 *
pcercuei 0:03b5121a232e 4778 * Lookup a type in the schemas or the predefined types
pcercuei 0:03b5121a232e 4779 *
pcercuei 0:03b5121a232e 4780 * Returns the group definition or NULL if not found.
pcercuei 0:03b5121a232e 4781 */
pcercuei 0:03b5121a232e 4782 static xmlSchemaTypePtr
pcercuei 0:03b5121a232e 4783 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
pcercuei 0:03b5121a232e 4784 const xmlChar * nsName)
pcercuei 0:03b5121a232e 4785 {
pcercuei 0:03b5121a232e 4786 xmlSchemaTypePtr ret = NULL;
pcercuei 0:03b5121a232e 4787
pcercuei 0:03b5121a232e 4788 if (name == NULL)
pcercuei 0:03b5121a232e 4789 return (NULL);
pcercuei 0:03b5121a232e 4790 /* First try the built-in types. */
pcercuei 0:03b5121a232e 4791 if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 4792 ret = xmlSchemaGetPredefinedType(name, nsName);
pcercuei 0:03b5121a232e 4793 if (ret != NULL)
pcercuei 0:03b5121a232e 4794 goto exit;
pcercuei 0:03b5121a232e 4795 /*
pcercuei 0:03b5121a232e 4796 * Note that we try the parsed schemas as well here
pcercuei 0:03b5121a232e 4797 * since one might have parsed the S4S, which contain more
pcercuei 0:03b5121a232e 4798 * than the built-in types.
pcercuei 0:03b5121a232e 4799 * TODO: Can we optimize this?
pcercuei 0:03b5121a232e 4800 */
pcercuei 0:03b5121a232e 4801 }
pcercuei 0:03b5121a232e 4802 if (schema != NULL) {
pcercuei 0:03b5121a232e 4803 WXS_FIND_GLOBAL_ITEM(typeDecl)
pcercuei 0:03b5121a232e 4804 }
pcercuei 0:03b5121a232e 4805 exit:
pcercuei 0:03b5121a232e 4806
pcercuei 0:03b5121a232e 4807 #ifdef DEBUG
pcercuei 0:03b5121a232e 4808 if (ret == NULL) {
pcercuei 0:03b5121a232e 4809 if (nsName == NULL)
pcercuei 0:03b5121a232e 4810 fprintf(stderr, "Unable to lookup type %s", name);
pcercuei 0:03b5121a232e 4811 else
pcercuei 0:03b5121a232e 4812 fprintf(stderr, "Unable to lookup type %s:%s", name,
pcercuei 0:03b5121a232e 4813 nsName);
pcercuei 0:03b5121a232e 4814 }
pcercuei 0:03b5121a232e 4815 #endif
pcercuei 0:03b5121a232e 4816 return (ret);
pcercuei 0:03b5121a232e 4817 }
pcercuei 0:03b5121a232e 4818
pcercuei 0:03b5121a232e 4819 /**
pcercuei 0:03b5121a232e 4820 * xmlSchemaGetAttributeDecl:
pcercuei 0:03b5121a232e 4821 * @schema: the context of the schema
pcercuei 0:03b5121a232e 4822 * @name: the name of the attribute
pcercuei 0:03b5121a232e 4823 * @ns: the target namespace of the attribute
pcercuei 0:03b5121a232e 4824 *
pcercuei 0:03b5121a232e 4825 * Lookup a an attribute in the schema or imported schemas
pcercuei 0:03b5121a232e 4826 *
pcercuei 0:03b5121a232e 4827 * Returns the attribute declaration or NULL if not found.
pcercuei 0:03b5121a232e 4828 */
pcercuei 0:03b5121a232e 4829 static xmlSchemaAttributePtr
pcercuei 0:03b5121a232e 4830 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
pcercuei 0:03b5121a232e 4831 const xmlChar * nsName)
pcercuei 0:03b5121a232e 4832 {
pcercuei 0:03b5121a232e 4833 xmlSchemaAttributePtr ret = NULL;
pcercuei 0:03b5121a232e 4834
pcercuei 0:03b5121a232e 4835 if ((name == NULL) || (schema == NULL))
pcercuei 0:03b5121a232e 4836 return (NULL);
pcercuei 0:03b5121a232e 4837 if (schema != NULL) {
pcercuei 0:03b5121a232e 4838 WXS_FIND_GLOBAL_ITEM(attrDecl)
pcercuei 0:03b5121a232e 4839 }
pcercuei 0:03b5121a232e 4840 exit:
pcercuei 0:03b5121a232e 4841 #ifdef DEBUG
pcercuei 0:03b5121a232e 4842 if (ret == NULL) {
pcercuei 0:03b5121a232e 4843 if (nsName == NULL)
pcercuei 0:03b5121a232e 4844 fprintf(stderr, "Unable to lookup attribute %s", name);
pcercuei 0:03b5121a232e 4845 else
pcercuei 0:03b5121a232e 4846 fprintf(stderr, "Unable to lookup attribute %s:%s", name,
pcercuei 0:03b5121a232e 4847 nsName);
pcercuei 0:03b5121a232e 4848 }
pcercuei 0:03b5121a232e 4849 #endif
pcercuei 0:03b5121a232e 4850 return (ret);
pcercuei 0:03b5121a232e 4851 }
pcercuei 0:03b5121a232e 4852
pcercuei 0:03b5121a232e 4853 /**
pcercuei 0:03b5121a232e 4854 * xmlSchemaGetAttributeGroup:
pcercuei 0:03b5121a232e 4855 * @schema: the context of the schema
pcercuei 0:03b5121a232e 4856 * @name: the name of the attribute group
pcercuei 0:03b5121a232e 4857 * @ns: the target namespace of the attribute group
pcercuei 0:03b5121a232e 4858 *
pcercuei 0:03b5121a232e 4859 * Lookup a an attribute group in the schema or imported schemas
pcercuei 0:03b5121a232e 4860 *
pcercuei 0:03b5121a232e 4861 * Returns the attribute group definition or NULL if not found.
pcercuei 0:03b5121a232e 4862 */
pcercuei 0:03b5121a232e 4863 static xmlSchemaAttributeGroupPtr
pcercuei 0:03b5121a232e 4864 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
pcercuei 0:03b5121a232e 4865 const xmlChar * nsName)
pcercuei 0:03b5121a232e 4866 {
pcercuei 0:03b5121a232e 4867 xmlSchemaAttributeGroupPtr ret = NULL;
pcercuei 0:03b5121a232e 4868
pcercuei 0:03b5121a232e 4869 if ((name == NULL) || (schema == NULL))
pcercuei 0:03b5121a232e 4870 return (NULL);
pcercuei 0:03b5121a232e 4871 if (schema != NULL) {
pcercuei 0:03b5121a232e 4872 WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
pcercuei 0:03b5121a232e 4873 }
pcercuei 0:03b5121a232e 4874 exit:
pcercuei 0:03b5121a232e 4875 /* TODO:
pcercuei 0:03b5121a232e 4876 if ((ret != NULL) && (ret->redef != NULL)) {
pcercuei 0:03b5121a232e 4877 * Return the last redefinition. *
pcercuei 0:03b5121a232e 4878 ret = ret->redef;
pcercuei 0:03b5121a232e 4879 }
pcercuei 0:03b5121a232e 4880 */
pcercuei 0:03b5121a232e 4881 #ifdef DEBUG
pcercuei 0:03b5121a232e 4882 if (ret == NULL) {
pcercuei 0:03b5121a232e 4883 if (nsName == NULL)
pcercuei 0:03b5121a232e 4884 fprintf(stderr, "Unable to lookup attribute group %s", name);
pcercuei 0:03b5121a232e 4885 else
pcercuei 0:03b5121a232e 4886 fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
pcercuei 0:03b5121a232e 4887 nsName);
pcercuei 0:03b5121a232e 4888 }
pcercuei 0:03b5121a232e 4889 #endif
pcercuei 0:03b5121a232e 4890 return (ret);
pcercuei 0:03b5121a232e 4891 }
pcercuei 0:03b5121a232e 4892
pcercuei 0:03b5121a232e 4893 /**
pcercuei 0:03b5121a232e 4894 * xmlSchemaGetGroup:
pcercuei 0:03b5121a232e 4895 * @schema: the context of the schema
pcercuei 0:03b5121a232e 4896 * @name: the name of the group
pcercuei 0:03b5121a232e 4897 * @ns: the target namespace of the group
pcercuei 0:03b5121a232e 4898 *
pcercuei 0:03b5121a232e 4899 * Lookup a group in the schema or imported schemas
pcercuei 0:03b5121a232e 4900 *
pcercuei 0:03b5121a232e 4901 * Returns the group definition or NULL if not found.
pcercuei 0:03b5121a232e 4902 */
pcercuei 0:03b5121a232e 4903 static xmlSchemaModelGroupDefPtr
pcercuei 0:03b5121a232e 4904 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
pcercuei 0:03b5121a232e 4905 const xmlChar * nsName)
pcercuei 0:03b5121a232e 4906 {
pcercuei 0:03b5121a232e 4907 xmlSchemaModelGroupDefPtr ret = NULL;
pcercuei 0:03b5121a232e 4908
pcercuei 0:03b5121a232e 4909 if ((name == NULL) || (schema == NULL))
pcercuei 0:03b5121a232e 4910 return (NULL);
pcercuei 0:03b5121a232e 4911 if (schema != NULL) {
pcercuei 0:03b5121a232e 4912 WXS_FIND_GLOBAL_ITEM(groupDecl)
pcercuei 0:03b5121a232e 4913 }
pcercuei 0:03b5121a232e 4914 exit:
pcercuei 0:03b5121a232e 4915
pcercuei 0:03b5121a232e 4916 #ifdef DEBUG
pcercuei 0:03b5121a232e 4917 if (ret == NULL) {
pcercuei 0:03b5121a232e 4918 if (nsName == NULL)
pcercuei 0:03b5121a232e 4919 fprintf(stderr, "Unable to lookup group %s", name);
pcercuei 0:03b5121a232e 4920 else
pcercuei 0:03b5121a232e 4921 fprintf(stderr, "Unable to lookup group %s:%s", name,
pcercuei 0:03b5121a232e 4922 nsName);
pcercuei 0:03b5121a232e 4923 }
pcercuei 0:03b5121a232e 4924 #endif
pcercuei 0:03b5121a232e 4925 return (ret);
pcercuei 0:03b5121a232e 4926 }
pcercuei 0:03b5121a232e 4927
pcercuei 0:03b5121a232e 4928 static xmlSchemaNotationPtr
pcercuei 0:03b5121a232e 4929 xmlSchemaGetNotation(xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 4930 const xmlChar *name,
pcercuei 0:03b5121a232e 4931 const xmlChar *nsName)
pcercuei 0:03b5121a232e 4932 {
pcercuei 0:03b5121a232e 4933 xmlSchemaNotationPtr ret = NULL;
pcercuei 0:03b5121a232e 4934
pcercuei 0:03b5121a232e 4935 if ((name == NULL) || (schema == NULL))
pcercuei 0:03b5121a232e 4936 return (NULL);
pcercuei 0:03b5121a232e 4937 if (schema != NULL) {
pcercuei 0:03b5121a232e 4938 WXS_FIND_GLOBAL_ITEM(notaDecl)
pcercuei 0:03b5121a232e 4939 }
pcercuei 0:03b5121a232e 4940 exit:
pcercuei 0:03b5121a232e 4941 return (ret);
pcercuei 0:03b5121a232e 4942 }
pcercuei 0:03b5121a232e 4943
pcercuei 0:03b5121a232e 4944 static xmlSchemaIDCPtr
pcercuei 0:03b5121a232e 4945 xmlSchemaGetIDC(xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 4946 const xmlChar *name,
pcercuei 0:03b5121a232e 4947 const xmlChar *nsName)
pcercuei 0:03b5121a232e 4948 {
pcercuei 0:03b5121a232e 4949 xmlSchemaIDCPtr ret = NULL;
pcercuei 0:03b5121a232e 4950
pcercuei 0:03b5121a232e 4951 if ((name == NULL) || (schema == NULL))
pcercuei 0:03b5121a232e 4952 return (NULL);
pcercuei 0:03b5121a232e 4953 if (schema != NULL) {
pcercuei 0:03b5121a232e 4954 WXS_FIND_GLOBAL_ITEM(idcDef)
pcercuei 0:03b5121a232e 4955 }
pcercuei 0:03b5121a232e 4956 exit:
pcercuei 0:03b5121a232e 4957 return (ret);
pcercuei 0:03b5121a232e 4958 }
pcercuei 0:03b5121a232e 4959
pcercuei 0:03b5121a232e 4960 /**
pcercuei 0:03b5121a232e 4961 * xmlSchemaGetNamedComponent:
pcercuei 0:03b5121a232e 4962 * @schema: the schema
pcercuei 0:03b5121a232e 4963 * @name: the name of the group
pcercuei 0:03b5121a232e 4964 * @ns: the target namespace of the group
pcercuei 0:03b5121a232e 4965 *
pcercuei 0:03b5121a232e 4966 * Lookup a group in the schema or imported schemas
pcercuei 0:03b5121a232e 4967 *
pcercuei 0:03b5121a232e 4968 * Returns the group definition or NULL if not found.
pcercuei 0:03b5121a232e 4969 */
pcercuei 0:03b5121a232e 4970 static xmlSchemaBasicItemPtr
pcercuei 0:03b5121a232e 4971 xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 4972 xmlSchemaTypeType itemType,
pcercuei 0:03b5121a232e 4973 const xmlChar *name,
pcercuei 0:03b5121a232e 4974 const xmlChar *targetNs)
pcercuei 0:03b5121a232e 4975 {
pcercuei 0:03b5121a232e 4976 switch (itemType) {
pcercuei 0:03b5121a232e 4977 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 4978 return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
pcercuei 0:03b5121a232e 4979 name, targetNs));
pcercuei 0:03b5121a232e 4980 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 4981 return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
pcercuei 0:03b5121a232e 4982 name, targetNs));
pcercuei 0:03b5121a232e 4983 default:
pcercuei 0:03b5121a232e 4984 TODO
pcercuei 0:03b5121a232e 4985 return (NULL);
pcercuei 0:03b5121a232e 4986 }
pcercuei 0:03b5121a232e 4987 }
pcercuei 0:03b5121a232e 4988
pcercuei 0:03b5121a232e 4989 /************************************************************************
pcercuei 0:03b5121a232e 4990 * *
pcercuei 0:03b5121a232e 4991 * Parsing functions *
pcercuei 0:03b5121a232e 4992 * *
pcercuei 0:03b5121a232e 4993 ************************************************************************/
pcercuei 0:03b5121a232e 4994
pcercuei 0:03b5121a232e 4995 #define IS_BLANK_NODE(n) \
pcercuei 0:03b5121a232e 4996 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
pcercuei 0:03b5121a232e 4997
pcercuei 0:03b5121a232e 4998 /**
pcercuei 0:03b5121a232e 4999 * xmlSchemaIsBlank:
pcercuei 0:03b5121a232e 5000 * @str: a string
pcercuei 0:03b5121a232e 5001 * @len: the length of the string or -1
pcercuei 0:03b5121a232e 5002 *
pcercuei 0:03b5121a232e 5003 * Check if a string is ignorable
pcercuei 0:03b5121a232e 5004 *
pcercuei 0:03b5121a232e 5005 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
pcercuei 0:03b5121a232e 5006 */
pcercuei 0:03b5121a232e 5007 static int
pcercuei 0:03b5121a232e 5008 xmlSchemaIsBlank(xmlChar * str, int len)
pcercuei 0:03b5121a232e 5009 {
pcercuei 0:03b5121a232e 5010 if (str == NULL)
pcercuei 0:03b5121a232e 5011 return (1);
pcercuei 0:03b5121a232e 5012 if (len < 0) {
pcercuei 0:03b5121a232e 5013 while (*str != 0) {
pcercuei 0:03b5121a232e 5014 if (!(IS_BLANK_CH(*str)))
pcercuei 0:03b5121a232e 5015 return (0);
pcercuei 0:03b5121a232e 5016 str++;
pcercuei 0:03b5121a232e 5017 }
pcercuei 0:03b5121a232e 5018 } else while ((*str != 0) && (len != 0)) {
pcercuei 0:03b5121a232e 5019 if (!(IS_BLANK_CH(*str)))
pcercuei 0:03b5121a232e 5020 return (0);
pcercuei 0:03b5121a232e 5021 str++;
pcercuei 0:03b5121a232e 5022 len--;
pcercuei 0:03b5121a232e 5023 }
pcercuei 0:03b5121a232e 5024
pcercuei 0:03b5121a232e 5025 return (1);
pcercuei 0:03b5121a232e 5026 }
pcercuei 0:03b5121a232e 5027
pcercuei 0:03b5121a232e 5028 #define WXS_COMP_NAME(c, t) ((t) (c))->name
pcercuei 0:03b5121a232e 5029 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
pcercuei 0:03b5121a232e 5030 /*
pcercuei 0:03b5121a232e 5031 * xmlSchemaFindRedefCompInGraph:
pcercuei 0:03b5121a232e 5032 * ATTENTION TODO: This uses pointer comp. for strings.
pcercuei 0:03b5121a232e 5033 */
pcercuei 0:03b5121a232e 5034 static xmlSchemaBasicItemPtr
pcercuei 0:03b5121a232e 5035 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
pcercuei 0:03b5121a232e 5036 xmlSchemaTypeType type,
pcercuei 0:03b5121a232e 5037 const xmlChar *name,
pcercuei 0:03b5121a232e 5038 const xmlChar *nsName)
pcercuei 0:03b5121a232e 5039 {
pcercuei 0:03b5121a232e 5040 xmlSchemaBasicItemPtr ret;
pcercuei 0:03b5121a232e 5041 int i;
pcercuei 0:03b5121a232e 5042
pcercuei 0:03b5121a232e 5043 if ((bucket == NULL) || (name == NULL))
pcercuei 0:03b5121a232e 5044 return(NULL);
pcercuei 0:03b5121a232e 5045 if ((bucket->globals == NULL) ||
pcercuei 0:03b5121a232e 5046 (bucket->globals->nbItems == 0))
pcercuei 0:03b5121a232e 5047 goto subschemas;
pcercuei 0:03b5121a232e 5048 /*
pcercuei 0:03b5121a232e 5049 * Search in global components.
pcercuei 0:03b5121a232e 5050 */
pcercuei 0:03b5121a232e 5051 for (i = 0; i < bucket->globals->nbItems; i++) {
pcercuei 0:03b5121a232e 5052 ret = bucket->globals->items[i];
pcercuei 0:03b5121a232e 5053 if (ret->type == type) {
pcercuei 0:03b5121a232e 5054 switch (type) {
pcercuei 0:03b5121a232e 5055 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 5056 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 5057 if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
pcercuei 0:03b5121a232e 5058 (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
pcercuei 0:03b5121a232e 5059 nsName))
pcercuei 0:03b5121a232e 5060 {
pcercuei 0:03b5121a232e 5061 return(ret);
pcercuei 0:03b5121a232e 5062 }
pcercuei 0:03b5121a232e 5063 break;
pcercuei 0:03b5121a232e 5064 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 5065 if ((WXS_COMP_NAME(ret,
pcercuei 0:03b5121a232e 5066 xmlSchemaModelGroupDefPtr) == name) &&
pcercuei 0:03b5121a232e 5067 (WXS_COMP_TNS(ret,
pcercuei 0:03b5121a232e 5068 xmlSchemaModelGroupDefPtr) == nsName))
pcercuei 0:03b5121a232e 5069 {
pcercuei 0:03b5121a232e 5070 return(ret);
pcercuei 0:03b5121a232e 5071 }
pcercuei 0:03b5121a232e 5072 break;
pcercuei 0:03b5121a232e 5073 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 5074 if ((WXS_COMP_NAME(ret,
pcercuei 0:03b5121a232e 5075 xmlSchemaAttributeGroupPtr) == name) &&
pcercuei 0:03b5121a232e 5076 (WXS_COMP_TNS(ret,
pcercuei 0:03b5121a232e 5077 xmlSchemaAttributeGroupPtr) == nsName))
pcercuei 0:03b5121a232e 5078 {
pcercuei 0:03b5121a232e 5079 return(ret);
pcercuei 0:03b5121a232e 5080 }
pcercuei 0:03b5121a232e 5081 break;
pcercuei 0:03b5121a232e 5082 default:
pcercuei 0:03b5121a232e 5083 /* Should not be hit. */
pcercuei 0:03b5121a232e 5084 return(NULL);
pcercuei 0:03b5121a232e 5085 }
pcercuei 0:03b5121a232e 5086 }
pcercuei 0:03b5121a232e 5087 }
pcercuei 0:03b5121a232e 5088 subschemas:
pcercuei 0:03b5121a232e 5089 /*
pcercuei 0:03b5121a232e 5090 * Process imported/included schemas.
pcercuei 0:03b5121a232e 5091 */
pcercuei 0:03b5121a232e 5092 if (bucket->relations != NULL) {
pcercuei 0:03b5121a232e 5093 xmlSchemaSchemaRelationPtr rel = bucket->relations;
pcercuei 0:03b5121a232e 5094
pcercuei 0:03b5121a232e 5095 /*
pcercuei 0:03b5121a232e 5096 * TODO: Marking the bucket will not avoid multiple searches
pcercuei 0:03b5121a232e 5097 * in the same schema, but avoids at least circularity.
pcercuei 0:03b5121a232e 5098 */
pcercuei 0:03b5121a232e 5099 bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
pcercuei 0:03b5121a232e 5100 do {
pcercuei 0:03b5121a232e 5101 if ((rel->bucket != NULL) &&
pcercuei 0:03b5121a232e 5102 ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
pcercuei 0:03b5121a232e 5103 ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
pcercuei 0:03b5121a232e 5104 type, name, nsName);
pcercuei 0:03b5121a232e 5105 if (ret != NULL)
pcercuei 0:03b5121a232e 5106 return(ret);
pcercuei 0:03b5121a232e 5107 }
pcercuei 0:03b5121a232e 5108 rel = rel->next;
pcercuei 0:03b5121a232e 5109 } while (rel != NULL);
pcercuei 0:03b5121a232e 5110 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
pcercuei 0:03b5121a232e 5111 }
pcercuei 0:03b5121a232e 5112 return(NULL);
pcercuei 0:03b5121a232e 5113 }
pcercuei 0:03b5121a232e 5114
pcercuei 0:03b5121a232e 5115 /**
pcercuei 0:03b5121a232e 5116 * xmlSchemaAddNotation:
pcercuei 0:03b5121a232e 5117 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 5118 * @schema: the schema being built
pcercuei 0:03b5121a232e 5119 * @name: the item name
pcercuei 0:03b5121a232e 5120 *
pcercuei 0:03b5121a232e 5121 * Add an XML schema annotation declaration
pcercuei 0:03b5121a232e 5122 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 5123 *
pcercuei 0:03b5121a232e 5124 * Returns the new struture or NULL in case of error
pcercuei 0:03b5121a232e 5125 */
pcercuei 0:03b5121a232e 5126 static xmlSchemaNotationPtr
pcercuei 0:03b5121a232e 5127 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 5128 const xmlChar *name, const xmlChar *nsName,
pcercuei 0:03b5121a232e 5129 xmlNodePtr node ATTRIBUTE_UNUSED)
pcercuei 0:03b5121a232e 5130 {
pcercuei 0:03b5121a232e 5131 xmlSchemaNotationPtr ret = NULL;
pcercuei 0:03b5121a232e 5132
pcercuei 0:03b5121a232e 5133 if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
pcercuei 0:03b5121a232e 5134 return (NULL);
pcercuei 0:03b5121a232e 5135
pcercuei 0:03b5121a232e 5136 ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
pcercuei 0:03b5121a232e 5137 if (ret == NULL) {
pcercuei 0:03b5121a232e 5138 xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
pcercuei 0:03b5121a232e 5139 return (NULL);
pcercuei 0:03b5121a232e 5140 }
pcercuei 0:03b5121a232e 5141 memset(ret, 0, sizeof(xmlSchemaNotation));
pcercuei 0:03b5121a232e 5142 ret->type = XML_SCHEMA_TYPE_NOTATION;
pcercuei 0:03b5121a232e 5143 ret->name = name;
pcercuei 0:03b5121a232e 5144 ret->targetNamespace = nsName;
pcercuei 0:03b5121a232e 5145 /* TODO: do we need the node to be set?
pcercuei 0:03b5121a232e 5146 * ret->node = node;*/
pcercuei 0:03b5121a232e 5147 WXS_ADD_GLOBAL(ctxt, ret);
pcercuei 0:03b5121a232e 5148 return (ret);
pcercuei 0:03b5121a232e 5149 }
pcercuei 0:03b5121a232e 5150
pcercuei 0:03b5121a232e 5151 /**
pcercuei 0:03b5121a232e 5152 * xmlSchemaAddAttribute:
pcercuei 0:03b5121a232e 5153 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 5154 * @schema: the schema being built
pcercuei 0:03b5121a232e 5155 * @name: the item name
pcercuei 0:03b5121a232e 5156 * @namespace: the namespace
pcercuei 0:03b5121a232e 5157 *
pcercuei 0:03b5121a232e 5158 * Add an XML schema Attrribute declaration
pcercuei 0:03b5121a232e 5159 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 5160 *
pcercuei 0:03b5121a232e 5161 * Returns the new struture or NULL in case of error
pcercuei 0:03b5121a232e 5162 */
pcercuei 0:03b5121a232e 5163 static xmlSchemaAttributePtr
pcercuei 0:03b5121a232e 5164 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 5165 const xmlChar * name, const xmlChar * nsName,
pcercuei 0:03b5121a232e 5166 xmlNodePtr node, int topLevel)
pcercuei 0:03b5121a232e 5167 {
pcercuei 0:03b5121a232e 5168 xmlSchemaAttributePtr ret = NULL;
pcercuei 0:03b5121a232e 5169
pcercuei 0:03b5121a232e 5170 if ((ctxt == NULL) || (schema == NULL))
pcercuei 0:03b5121a232e 5171 return (NULL);
pcercuei 0:03b5121a232e 5172
pcercuei 0:03b5121a232e 5173 ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
pcercuei 0:03b5121a232e 5174 if (ret == NULL) {
pcercuei 0:03b5121a232e 5175 xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
pcercuei 0:03b5121a232e 5176 return (NULL);
pcercuei 0:03b5121a232e 5177 }
pcercuei 0:03b5121a232e 5178 memset(ret, 0, sizeof(xmlSchemaAttribute));
pcercuei 0:03b5121a232e 5179 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
pcercuei 0:03b5121a232e 5180 ret->node = node;
pcercuei 0:03b5121a232e 5181 ret->name = name;
pcercuei 0:03b5121a232e 5182 ret->targetNamespace = nsName;
pcercuei 0:03b5121a232e 5183
pcercuei 0:03b5121a232e 5184 if (topLevel)
pcercuei 0:03b5121a232e 5185 WXS_ADD_GLOBAL(ctxt, ret);
pcercuei 0:03b5121a232e 5186 else
pcercuei 0:03b5121a232e 5187 WXS_ADD_LOCAL(ctxt, ret);
pcercuei 0:03b5121a232e 5188 WXS_ADD_PENDING(ctxt, ret);
pcercuei 0:03b5121a232e 5189 return (ret);
pcercuei 0:03b5121a232e 5190 }
pcercuei 0:03b5121a232e 5191
pcercuei 0:03b5121a232e 5192 /**
pcercuei 0:03b5121a232e 5193 * xmlSchemaAddAttributeUse:
pcercuei 0:03b5121a232e 5194 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 5195 * @schema: the schema being built
pcercuei 0:03b5121a232e 5196 * @name: the item name
pcercuei 0:03b5121a232e 5197 * @namespace: the namespace
pcercuei 0:03b5121a232e 5198 *
pcercuei 0:03b5121a232e 5199 * Add an XML schema Attrribute declaration
pcercuei 0:03b5121a232e 5200 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 5201 *
pcercuei 0:03b5121a232e 5202 * Returns the new struture or NULL in case of error
pcercuei 0:03b5121a232e 5203 */
pcercuei 0:03b5121a232e 5204 static xmlSchemaAttributeUsePtr
pcercuei 0:03b5121a232e 5205 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 5206 xmlNodePtr node)
pcercuei 0:03b5121a232e 5207 {
pcercuei 0:03b5121a232e 5208 xmlSchemaAttributeUsePtr ret = NULL;
pcercuei 0:03b5121a232e 5209
pcercuei 0:03b5121a232e 5210 if (pctxt == NULL)
pcercuei 0:03b5121a232e 5211 return (NULL);
pcercuei 0:03b5121a232e 5212
pcercuei 0:03b5121a232e 5213 ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
pcercuei 0:03b5121a232e 5214 if (ret == NULL) {
pcercuei 0:03b5121a232e 5215 xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
pcercuei 0:03b5121a232e 5216 return (NULL);
pcercuei 0:03b5121a232e 5217 }
pcercuei 0:03b5121a232e 5218 memset(ret, 0, sizeof(xmlSchemaAttributeUse));
pcercuei 0:03b5121a232e 5219 ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
pcercuei 0:03b5121a232e 5220 ret->node = node;
pcercuei 0:03b5121a232e 5221
pcercuei 0:03b5121a232e 5222 WXS_ADD_LOCAL(pctxt, ret);
pcercuei 0:03b5121a232e 5223 return (ret);
pcercuei 0:03b5121a232e 5224 }
pcercuei 0:03b5121a232e 5225
pcercuei 0:03b5121a232e 5226 /*
pcercuei 0:03b5121a232e 5227 * xmlSchemaAddRedef:
pcercuei 0:03b5121a232e 5228 *
pcercuei 0:03b5121a232e 5229 * Adds a redefinition information. This is used at a later stage to:
pcercuei 0:03b5121a232e 5230 * resolve references to the redefined components and to check constraints.
pcercuei 0:03b5121a232e 5231 */
pcercuei 0:03b5121a232e 5232 static xmlSchemaRedefPtr
pcercuei 0:03b5121a232e 5233 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 5234 xmlSchemaBucketPtr targetBucket,
pcercuei 0:03b5121a232e 5235 void *item,
pcercuei 0:03b5121a232e 5236 const xmlChar *refName,
pcercuei 0:03b5121a232e 5237 const xmlChar *refTargetNs)
pcercuei 0:03b5121a232e 5238 {
pcercuei 0:03b5121a232e 5239 xmlSchemaRedefPtr ret;
pcercuei 0:03b5121a232e 5240
pcercuei 0:03b5121a232e 5241 ret = (xmlSchemaRedefPtr)
pcercuei 0:03b5121a232e 5242 xmlMalloc(sizeof(xmlSchemaRedef));
pcercuei 0:03b5121a232e 5243 if (ret == NULL) {
pcercuei 0:03b5121a232e 5244 xmlSchemaPErrMemory(pctxt,
pcercuei 0:03b5121a232e 5245 "allocating redefinition info", NULL);
pcercuei 0:03b5121a232e 5246 return (NULL);
pcercuei 0:03b5121a232e 5247 }
pcercuei 0:03b5121a232e 5248 memset(ret, 0, sizeof(xmlSchemaRedef));
pcercuei 0:03b5121a232e 5249 ret->item = item;
pcercuei 0:03b5121a232e 5250 ret->targetBucket = targetBucket;
pcercuei 0:03b5121a232e 5251 ret->refName = refName;
pcercuei 0:03b5121a232e 5252 ret->refTargetNs = refTargetNs;
pcercuei 0:03b5121a232e 5253 if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
pcercuei 0:03b5121a232e 5254 WXS_CONSTRUCTOR(pctxt)->redefs = ret;
pcercuei 0:03b5121a232e 5255 else
pcercuei 0:03b5121a232e 5256 WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
pcercuei 0:03b5121a232e 5257 WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
pcercuei 0:03b5121a232e 5258
pcercuei 0:03b5121a232e 5259 return (ret);
pcercuei 0:03b5121a232e 5260 }
pcercuei 0:03b5121a232e 5261
pcercuei 0:03b5121a232e 5262 /**
pcercuei 0:03b5121a232e 5263 * xmlSchemaAddAttributeGroupDefinition:
pcercuei 0:03b5121a232e 5264 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 5265 * @schema: the schema being built
pcercuei 0:03b5121a232e 5266 * @name: the item name
pcercuei 0:03b5121a232e 5267 * @nsName: the target namespace
pcercuei 0:03b5121a232e 5268 * @node: the corresponding node
pcercuei 0:03b5121a232e 5269 *
pcercuei 0:03b5121a232e 5270 * Add an XML schema Attrribute Group definition.
pcercuei 0:03b5121a232e 5271 *
pcercuei 0:03b5121a232e 5272 * Returns the new struture or NULL in case of error
pcercuei 0:03b5121a232e 5273 */
pcercuei 0:03b5121a232e 5274 static xmlSchemaAttributeGroupPtr
pcercuei 0:03b5121a232e 5275 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 5276 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 5277 const xmlChar *name,
pcercuei 0:03b5121a232e 5278 const xmlChar *nsName,
pcercuei 0:03b5121a232e 5279 xmlNodePtr node)
pcercuei 0:03b5121a232e 5280 {
pcercuei 0:03b5121a232e 5281 xmlSchemaAttributeGroupPtr ret = NULL;
pcercuei 0:03b5121a232e 5282
pcercuei 0:03b5121a232e 5283 if ((pctxt == NULL) || (name == NULL))
pcercuei 0:03b5121a232e 5284 return (NULL);
pcercuei 0:03b5121a232e 5285
pcercuei 0:03b5121a232e 5286 ret = (xmlSchemaAttributeGroupPtr)
pcercuei 0:03b5121a232e 5287 xmlMalloc(sizeof(xmlSchemaAttributeGroup));
pcercuei 0:03b5121a232e 5288 if (ret == NULL) {
pcercuei 0:03b5121a232e 5289 xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
pcercuei 0:03b5121a232e 5290 return (NULL);
pcercuei 0:03b5121a232e 5291 }
pcercuei 0:03b5121a232e 5292 memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
pcercuei 0:03b5121a232e 5293 ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
pcercuei 0:03b5121a232e 5294 ret->name = name;
pcercuei 0:03b5121a232e 5295 ret->targetNamespace = nsName;
pcercuei 0:03b5121a232e 5296 ret->node = node;
pcercuei 0:03b5121a232e 5297
pcercuei 0:03b5121a232e 5298 /* TODO: Remove the flag. */
pcercuei 0:03b5121a232e 5299 ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
pcercuei 0:03b5121a232e 5300 if (pctxt->isRedefine) {
pcercuei 0:03b5121a232e 5301 pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
pcercuei 0:03b5121a232e 5302 ret, name, nsName);
pcercuei 0:03b5121a232e 5303 if (pctxt->redef == NULL) {
pcercuei 0:03b5121a232e 5304 xmlFree(ret);
pcercuei 0:03b5121a232e 5305 return(NULL);
pcercuei 0:03b5121a232e 5306 }
pcercuei 0:03b5121a232e 5307 pctxt->redefCounter = 0;
pcercuei 0:03b5121a232e 5308 }
pcercuei 0:03b5121a232e 5309 WXS_ADD_GLOBAL(pctxt, ret);
pcercuei 0:03b5121a232e 5310 WXS_ADD_PENDING(pctxt, ret);
pcercuei 0:03b5121a232e 5311 return (ret);
pcercuei 0:03b5121a232e 5312 }
pcercuei 0:03b5121a232e 5313
pcercuei 0:03b5121a232e 5314 /**
pcercuei 0:03b5121a232e 5315 * xmlSchemaAddElement:
pcercuei 0:03b5121a232e 5316 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 5317 * @schema: the schema being built
pcercuei 0:03b5121a232e 5318 * @name: the type name
pcercuei 0:03b5121a232e 5319 * @namespace: the type namespace
pcercuei 0:03b5121a232e 5320 *
pcercuei 0:03b5121a232e 5321 * Add an XML schema Element declaration
pcercuei 0:03b5121a232e 5322 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 5323 *
pcercuei 0:03b5121a232e 5324 * Returns the new struture or NULL in case of error
pcercuei 0:03b5121a232e 5325 */
pcercuei 0:03b5121a232e 5326 static xmlSchemaElementPtr
pcercuei 0:03b5121a232e 5327 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 5328 const xmlChar * name, const xmlChar * nsName,
pcercuei 0:03b5121a232e 5329 xmlNodePtr node, int topLevel)
pcercuei 0:03b5121a232e 5330 {
pcercuei 0:03b5121a232e 5331 xmlSchemaElementPtr ret = NULL;
pcercuei 0:03b5121a232e 5332
pcercuei 0:03b5121a232e 5333 if ((ctxt == NULL) || (name == NULL))
pcercuei 0:03b5121a232e 5334 return (NULL);
pcercuei 0:03b5121a232e 5335
pcercuei 0:03b5121a232e 5336 ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
pcercuei 0:03b5121a232e 5337 if (ret == NULL) {
pcercuei 0:03b5121a232e 5338 xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
pcercuei 0:03b5121a232e 5339 return (NULL);
pcercuei 0:03b5121a232e 5340 }
pcercuei 0:03b5121a232e 5341 memset(ret, 0, sizeof(xmlSchemaElement));
pcercuei 0:03b5121a232e 5342 ret->type = XML_SCHEMA_TYPE_ELEMENT;
pcercuei 0:03b5121a232e 5343 ret->name = name;
pcercuei 0:03b5121a232e 5344 ret->targetNamespace = nsName;
pcercuei 0:03b5121a232e 5345 ret->node = node;
pcercuei 0:03b5121a232e 5346
pcercuei 0:03b5121a232e 5347 if (topLevel)
pcercuei 0:03b5121a232e 5348 WXS_ADD_GLOBAL(ctxt, ret);
pcercuei 0:03b5121a232e 5349 else
pcercuei 0:03b5121a232e 5350 WXS_ADD_LOCAL(ctxt, ret);
pcercuei 0:03b5121a232e 5351 WXS_ADD_PENDING(ctxt, ret);
pcercuei 0:03b5121a232e 5352 return (ret);
pcercuei 0:03b5121a232e 5353 }
pcercuei 0:03b5121a232e 5354
pcercuei 0:03b5121a232e 5355 /**
pcercuei 0:03b5121a232e 5356 * xmlSchemaAddType:
pcercuei 0:03b5121a232e 5357 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 5358 * @schema: the schema being built
pcercuei 0:03b5121a232e 5359 * @name: the item name
pcercuei 0:03b5121a232e 5360 * @namespace: the namespace
pcercuei 0:03b5121a232e 5361 *
pcercuei 0:03b5121a232e 5362 * Add an XML schema item
pcercuei 0:03b5121a232e 5363 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 5364 *
pcercuei 0:03b5121a232e 5365 * Returns the new struture or NULL in case of error
pcercuei 0:03b5121a232e 5366 */
pcercuei 0:03b5121a232e 5367 static xmlSchemaTypePtr
pcercuei 0:03b5121a232e 5368 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 5369 xmlSchemaTypeType type,
pcercuei 0:03b5121a232e 5370 const xmlChar * name, const xmlChar * nsName,
pcercuei 0:03b5121a232e 5371 xmlNodePtr node, int topLevel)
pcercuei 0:03b5121a232e 5372 {
pcercuei 0:03b5121a232e 5373 xmlSchemaTypePtr ret = NULL;
pcercuei 0:03b5121a232e 5374
pcercuei 0:03b5121a232e 5375 if ((ctxt == NULL) || (schema == NULL))
pcercuei 0:03b5121a232e 5376 return (NULL);
pcercuei 0:03b5121a232e 5377
pcercuei 0:03b5121a232e 5378 ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
pcercuei 0:03b5121a232e 5379 if (ret == NULL) {
pcercuei 0:03b5121a232e 5380 xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
pcercuei 0:03b5121a232e 5381 return (NULL);
pcercuei 0:03b5121a232e 5382 }
pcercuei 0:03b5121a232e 5383 memset(ret, 0, sizeof(xmlSchemaType));
pcercuei 0:03b5121a232e 5384 ret->type = type;
pcercuei 0:03b5121a232e 5385 ret->name = name;
pcercuei 0:03b5121a232e 5386 ret->targetNamespace = nsName;
pcercuei 0:03b5121a232e 5387 ret->node = node;
pcercuei 0:03b5121a232e 5388 if (topLevel) {
pcercuei 0:03b5121a232e 5389 if (ctxt->isRedefine) {
pcercuei 0:03b5121a232e 5390 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
pcercuei 0:03b5121a232e 5391 ret, name, nsName);
pcercuei 0:03b5121a232e 5392 if (ctxt->redef == NULL) {
pcercuei 0:03b5121a232e 5393 xmlFree(ret);
pcercuei 0:03b5121a232e 5394 return(NULL);
pcercuei 0:03b5121a232e 5395 }
pcercuei 0:03b5121a232e 5396 ctxt->redefCounter = 0;
pcercuei 0:03b5121a232e 5397 }
pcercuei 0:03b5121a232e 5398 WXS_ADD_GLOBAL(ctxt, ret);
pcercuei 0:03b5121a232e 5399 } else
pcercuei 0:03b5121a232e 5400 WXS_ADD_LOCAL(ctxt, ret);
pcercuei 0:03b5121a232e 5401 WXS_ADD_PENDING(ctxt, ret);
pcercuei 0:03b5121a232e 5402 return (ret);
pcercuei 0:03b5121a232e 5403 }
pcercuei 0:03b5121a232e 5404
pcercuei 0:03b5121a232e 5405 static xmlSchemaQNameRefPtr
pcercuei 0:03b5121a232e 5406 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 5407 xmlSchemaTypeType refType,
pcercuei 0:03b5121a232e 5408 const xmlChar *refName,
pcercuei 0:03b5121a232e 5409 const xmlChar *refNs)
pcercuei 0:03b5121a232e 5410 {
pcercuei 0:03b5121a232e 5411 xmlSchemaQNameRefPtr ret;
pcercuei 0:03b5121a232e 5412
pcercuei 0:03b5121a232e 5413 ret = (xmlSchemaQNameRefPtr)
pcercuei 0:03b5121a232e 5414 xmlMalloc(sizeof(xmlSchemaQNameRef));
pcercuei 0:03b5121a232e 5415 if (ret == NULL) {
pcercuei 0:03b5121a232e 5416 xmlSchemaPErrMemory(pctxt,
pcercuei 0:03b5121a232e 5417 "allocating QName reference item", NULL);
pcercuei 0:03b5121a232e 5418 return (NULL);
pcercuei 0:03b5121a232e 5419 }
pcercuei 0:03b5121a232e 5420 ret->node = NULL;
pcercuei 0:03b5121a232e 5421 ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
pcercuei 0:03b5121a232e 5422 ret->name = refName;
pcercuei 0:03b5121a232e 5423 ret->targetNamespace = refNs;
pcercuei 0:03b5121a232e 5424 ret->item = NULL;
pcercuei 0:03b5121a232e 5425 ret->itemType = refType;
pcercuei 0:03b5121a232e 5426 /*
pcercuei 0:03b5121a232e 5427 * Store the reference item in the schema.
pcercuei 0:03b5121a232e 5428 */
pcercuei 0:03b5121a232e 5429 WXS_ADD_LOCAL(pctxt, ret);
pcercuei 0:03b5121a232e 5430 return (ret);
pcercuei 0:03b5121a232e 5431 }
pcercuei 0:03b5121a232e 5432
pcercuei 0:03b5121a232e 5433 static xmlSchemaAttributeUseProhibPtr
pcercuei 0:03b5121a232e 5434 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
pcercuei 0:03b5121a232e 5435 {
pcercuei 0:03b5121a232e 5436 xmlSchemaAttributeUseProhibPtr ret;
pcercuei 0:03b5121a232e 5437
pcercuei 0:03b5121a232e 5438 ret = (xmlSchemaAttributeUseProhibPtr)
pcercuei 0:03b5121a232e 5439 xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
pcercuei 0:03b5121a232e 5440 if (ret == NULL) {
pcercuei 0:03b5121a232e 5441 xmlSchemaPErrMemory(pctxt,
pcercuei 0:03b5121a232e 5442 "allocating attribute use prohibition", NULL);
pcercuei 0:03b5121a232e 5443 return (NULL);
pcercuei 0:03b5121a232e 5444 }
pcercuei 0:03b5121a232e 5445 memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
pcercuei 0:03b5121a232e 5446 ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
pcercuei 0:03b5121a232e 5447 WXS_ADD_LOCAL(pctxt, ret);
pcercuei 0:03b5121a232e 5448 return (ret);
pcercuei 0:03b5121a232e 5449 }
pcercuei 0:03b5121a232e 5450
pcercuei 0:03b5121a232e 5451
pcercuei 0:03b5121a232e 5452 /**
pcercuei 0:03b5121a232e 5453 * xmlSchemaAddModelGroup:
pcercuei 0:03b5121a232e 5454 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 5455 * @schema: the schema being built
pcercuei 0:03b5121a232e 5456 * @type: the "compositor" type of the model group
pcercuei 0:03b5121a232e 5457 * @node: the node in the schema doc
pcercuei 0:03b5121a232e 5458 *
pcercuei 0:03b5121a232e 5459 * Adds a schema model group
pcercuei 0:03b5121a232e 5460 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 5461 *
pcercuei 0:03b5121a232e 5462 * Returns the new struture or NULL in case of error
pcercuei 0:03b5121a232e 5463 */
pcercuei 0:03b5121a232e 5464 static xmlSchemaModelGroupPtr
pcercuei 0:03b5121a232e 5465 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 5466 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 5467 xmlSchemaTypeType type,
pcercuei 0:03b5121a232e 5468 xmlNodePtr node)
pcercuei 0:03b5121a232e 5469 {
pcercuei 0:03b5121a232e 5470 xmlSchemaModelGroupPtr ret = NULL;
pcercuei 0:03b5121a232e 5471
pcercuei 0:03b5121a232e 5472 if ((ctxt == NULL) || (schema == NULL))
pcercuei 0:03b5121a232e 5473 return (NULL);
pcercuei 0:03b5121a232e 5474
pcercuei 0:03b5121a232e 5475 ret = (xmlSchemaModelGroupPtr)
pcercuei 0:03b5121a232e 5476 xmlMalloc(sizeof(xmlSchemaModelGroup));
pcercuei 0:03b5121a232e 5477 if (ret == NULL) {
pcercuei 0:03b5121a232e 5478 xmlSchemaPErrMemory(ctxt, "allocating model group component",
pcercuei 0:03b5121a232e 5479 NULL);
pcercuei 0:03b5121a232e 5480 return (NULL);
pcercuei 0:03b5121a232e 5481 }
pcercuei 0:03b5121a232e 5482 memset(ret, 0, sizeof(xmlSchemaModelGroup));
pcercuei 0:03b5121a232e 5483 ret->type = type;
pcercuei 0:03b5121a232e 5484 ret->node = node;
pcercuei 0:03b5121a232e 5485 WXS_ADD_LOCAL(ctxt, ret);
pcercuei 0:03b5121a232e 5486 if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
pcercuei 0:03b5121a232e 5487 (type == XML_SCHEMA_TYPE_CHOICE))
pcercuei 0:03b5121a232e 5488 WXS_ADD_PENDING(ctxt, ret);
pcercuei 0:03b5121a232e 5489 return (ret);
pcercuei 0:03b5121a232e 5490 }
pcercuei 0:03b5121a232e 5491
pcercuei 0:03b5121a232e 5492
pcercuei 0:03b5121a232e 5493 /**
pcercuei 0:03b5121a232e 5494 * xmlSchemaAddParticle:
pcercuei 0:03b5121a232e 5495 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 5496 * @schema: the schema being built
pcercuei 0:03b5121a232e 5497 * @node: the corresponding node in the schema doc
pcercuei 0:03b5121a232e 5498 * @min: the minOccurs
pcercuei 0:03b5121a232e 5499 * @max: the maxOccurs
pcercuei 0:03b5121a232e 5500 *
pcercuei 0:03b5121a232e 5501 * Adds an XML schema particle component.
pcercuei 0:03b5121a232e 5502 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 5503 *
pcercuei 0:03b5121a232e 5504 * Returns the new struture or NULL in case of error
pcercuei 0:03b5121a232e 5505 */
pcercuei 0:03b5121a232e 5506 static xmlSchemaParticlePtr
pcercuei 0:03b5121a232e 5507 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 5508 xmlNodePtr node, int min, int max)
pcercuei 0:03b5121a232e 5509 {
pcercuei 0:03b5121a232e 5510 xmlSchemaParticlePtr ret = NULL;
pcercuei 0:03b5121a232e 5511 if (ctxt == NULL)
pcercuei 0:03b5121a232e 5512 return (NULL);
pcercuei 0:03b5121a232e 5513
pcercuei 0:03b5121a232e 5514 #ifdef DEBUG
pcercuei 0:03b5121a232e 5515 fprintf(stderr, "Adding particle component\n");
pcercuei 0:03b5121a232e 5516 #endif
pcercuei 0:03b5121a232e 5517 ret = (xmlSchemaParticlePtr)
pcercuei 0:03b5121a232e 5518 xmlMalloc(sizeof(xmlSchemaParticle));
pcercuei 0:03b5121a232e 5519 if (ret == NULL) {
pcercuei 0:03b5121a232e 5520 xmlSchemaPErrMemory(ctxt, "allocating particle component",
pcercuei 0:03b5121a232e 5521 NULL);
pcercuei 0:03b5121a232e 5522 return (NULL);
pcercuei 0:03b5121a232e 5523 }
pcercuei 0:03b5121a232e 5524 ret->type = XML_SCHEMA_TYPE_PARTICLE;
pcercuei 0:03b5121a232e 5525 ret->annot = NULL;
pcercuei 0:03b5121a232e 5526 ret->node = node;
pcercuei 0:03b5121a232e 5527 ret->minOccurs = min;
pcercuei 0:03b5121a232e 5528 ret->maxOccurs = max;
pcercuei 0:03b5121a232e 5529 ret->next = NULL;
pcercuei 0:03b5121a232e 5530 ret->children = NULL;
pcercuei 0:03b5121a232e 5531
pcercuei 0:03b5121a232e 5532 WXS_ADD_LOCAL(ctxt, ret);
pcercuei 0:03b5121a232e 5533 /*
pcercuei 0:03b5121a232e 5534 * Note that addition to pending components will be done locally
pcercuei 0:03b5121a232e 5535 * to the specific parsing function, since the most particles
pcercuei 0:03b5121a232e 5536 * need not to be fixed up (i.e. the reference to be resolved).
pcercuei 0:03b5121a232e 5537 * REMOVED: WXS_ADD_PENDING(ctxt, ret);
pcercuei 0:03b5121a232e 5538 */
pcercuei 0:03b5121a232e 5539 return (ret);
pcercuei 0:03b5121a232e 5540 }
pcercuei 0:03b5121a232e 5541
pcercuei 0:03b5121a232e 5542 /**
pcercuei 0:03b5121a232e 5543 * xmlSchemaAddModelGroupDefinition:
pcercuei 0:03b5121a232e 5544 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 5545 * @schema: the schema being built
pcercuei 0:03b5121a232e 5546 * @name: the group name
pcercuei 0:03b5121a232e 5547 *
pcercuei 0:03b5121a232e 5548 * Add an XML schema Group definition
pcercuei 0:03b5121a232e 5549 *
pcercuei 0:03b5121a232e 5550 * Returns the new struture or NULL in case of error
pcercuei 0:03b5121a232e 5551 */
pcercuei 0:03b5121a232e 5552 static xmlSchemaModelGroupDefPtr
pcercuei 0:03b5121a232e 5553 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 5554 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 5555 const xmlChar *name,
pcercuei 0:03b5121a232e 5556 const xmlChar *nsName,
pcercuei 0:03b5121a232e 5557 xmlNodePtr node)
pcercuei 0:03b5121a232e 5558 {
pcercuei 0:03b5121a232e 5559 xmlSchemaModelGroupDefPtr ret = NULL;
pcercuei 0:03b5121a232e 5560
pcercuei 0:03b5121a232e 5561 if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
pcercuei 0:03b5121a232e 5562 return (NULL);
pcercuei 0:03b5121a232e 5563
pcercuei 0:03b5121a232e 5564 ret = (xmlSchemaModelGroupDefPtr)
pcercuei 0:03b5121a232e 5565 xmlMalloc(sizeof(xmlSchemaModelGroupDef));
pcercuei 0:03b5121a232e 5566 if (ret == NULL) {
pcercuei 0:03b5121a232e 5567 xmlSchemaPErrMemory(ctxt, "adding group", NULL);
pcercuei 0:03b5121a232e 5568 return (NULL);
pcercuei 0:03b5121a232e 5569 }
pcercuei 0:03b5121a232e 5570 memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
pcercuei 0:03b5121a232e 5571 ret->name = name;
pcercuei 0:03b5121a232e 5572 ret->type = XML_SCHEMA_TYPE_GROUP;
pcercuei 0:03b5121a232e 5573 ret->node = node;
pcercuei 0:03b5121a232e 5574 ret->targetNamespace = nsName;
pcercuei 0:03b5121a232e 5575
pcercuei 0:03b5121a232e 5576 if (ctxt->isRedefine) {
pcercuei 0:03b5121a232e 5577 ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
pcercuei 0:03b5121a232e 5578 ret, name, nsName);
pcercuei 0:03b5121a232e 5579 if (ctxt->redef == NULL) {
pcercuei 0:03b5121a232e 5580 xmlFree(ret);
pcercuei 0:03b5121a232e 5581 return(NULL);
pcercuei 0:03b5121a232e 5582 }
pcercuei 0:03b5121a232e 5583 ctxt->redefCounter = 0;
pcercuei 0:03b5121a232e 5584 }
pcercuei 0:03b5121a232e 5585 WXS_ADD_GLOBAL(ctxt, ret);
pcercuei 0:03b5121a232e 5586 WXS_ADD_PENDING(ctxt, ret);
pcercuei 0:03b5121a232e 5587 return (ret);
pcercuei 0:03b5121a232e 5588 }
pcercuei 0:03b5121a232e 5589
pcercuei 0:03b5121a232e 5590 /**
pcercuei 0:03b5121a232e 5591 * xmlSchemaNewWildcardNs:
pcercuei 0:03b5121a232e 5592 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 5593 *
pcercuei 0:03b5121a232e 5594 * Creates a new wildcard namespace constraint.
pcercuei 0:03b5121a232e 5595 *
pcercuei 0:03b5121a232e 5596 * Returns the new struture or NULL in case of error
pcercuei 0:03b5121a232e 5597 */
pcercuei 0:03b5121a232e 5598 static xmlSchemaWildcardNsPtr
pcercuei 0:03b5121a232e 5599 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 5600 {
pcercuei 0:03b5121a232e 5601 xmlSchemaWildcardNsPtr ret;
pcercuei 0:03b5121a232e 5602
pcercuei 0:03b5121a232e 5603 ret = (xmlSchemaWildcardNsPtr)
pcercuei 0:03b5121a232e 5604 xmlMalloc(sizeof(xmlSchemaWildcardNs));
pcercuei 0:03b5121a232e 5605 if (ret == NULL) {
pcercuei 0:03b5121a232e 5606 xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
pcercuei 0:03b5121a232e 5607 return (NULL);
pcercuei 0:03b5121a232e 5608 }
pcercuei 0:03b5121a232e 5609 ret->value = NULL;
pcercuei 0:03b5121a232e 5610 ret->next = NULL;
pcercuei 0:03b5121a232e 5611 return (ret);
pcercuei 0:03b5121a232e 5612 }
pcercuei 0:03b5121a232e 5613
pcercuei 0:03b5121a232e 5614 static xmlSchemaIDCPtr
pcercuei 0:03b5121a232e 5615 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 5616 const xmlChar *name, const xmlChar *nsName,
pcercuei 0:03b5121a232e 5617 int category, xmlNodePtr node)
pcercuei 0:03b5121a232e 5618 {
pcercuei 0:03b5121a232e 5619 xmlSchemaIDCPtr ret = NULL;
pcercuei 0:03b5121a232e 5620
pcercuei 0:03b5121a232e 5621 if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
pcercuei 0:03b5121a232e 5622 return (NULL);
pcercuei 0:03b5121a232e 5623
pcercuei 0:03b5121a232e 5624 ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
pcercuei 0:03b5121a232e 5625 if (ret == NULL) {
pcercuei 0:03b5121a232e 5626 xmlSchemaPErrMemory(ctxt,
pcercuei 0:03b5121a232e 5627 "allocating an identity-constraint definition", NULL);
pcercuei 0:03b5121a232e 5628 return (NULL);
pcercuei 0:03b5121a232e 5629 }
pcercuei 0:03b5121a232e 5630 memset(ret, 0, sizeof(xmlSchemaIDC));
pcercuei 0:03b5121a232e 5631 /* The target namespace of the parent element declaration. */
pcercuei 0:03b5121a232e 5632 ret->targetNamespace = nsName;
pcercuei 0:03b5121a232e 5633 ret->name = name;
pcercuei 0:03b5121a232e 5634 ret->type = category;
pcercuei 0:03b5121a232e 5635 ret->node = node;
pcercuei 0:03b5121a232e 5636
pcercuei 0:03b5121a232e 5637 WXS_ADD_GLOBAL(ctxt, ret);
pcercuei 0:03b5121a232e 5638 /*
pcercuei 0:03b5121a232e 5639 * Only keyrefs need to be fixup up.
pcercuei 0:03b5121a232e 5640 */
pcercuei 0:03b5121a232e 5641 if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
pcercuei 0:03b5121a232e 5642 WXS_ADD_PENDING(ctxt, ret);
pcercuei 0:03b5121a232e 5643 return (ret);
pcercuei 0:03b5121a232e 5644 }
pcercuei 0:03b5121a232e 5645
pcercuei 0:03b5121a232e 5646 /**
pcercuei 0:03b5121a232e 5647 * xmlSchemaAddWildcard:
pcercuei 0:03b5121a232e 5648 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 5649 * @schema: a schema
pcercuei 0:03b5121a232e 5650 *
pcercuei 0:03b5121a232e 5651 * Adds a wildcard.
pcercuei 0:03b5121a232e 5652 * It corresponds to a xsd:anyAttribute and xsd:any.
pcercuei 0:03b5121a232e 5653 *
pcercuei 0:03b5121a232e 5654 * Returns the new struture or NULL in case of error
pcercuei 0:03b5121a232e 5655 */
pcercuei 0:03b5121a232e 5656 static xmlSchemaWildcardPtr
pcercuei 0:03b5121a232e 5657 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 5658 xmlSchemaTypeType type, xmlNodePtr node)
pcercuei 0:03b5121a232e 5659 {
pcercuei 0:03b5121a232e 5660 xmlSchemaWildcardPtr ret = NULL;
pcercuei 0:03b5121a232e 5661
pcercuei 0:03b5121a232e 5662 if ((ctxt == NULL) || (schema == NULL))
pcercuei 0:03b5121a232e 5663 return (NULL);
pcercuei 0:03b5121a232e 5664
pcercuei 0:03b5121a232e 5665 ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
pcercuei 0:03b5121a232e 5666 if (ret == NULL) {
pcercuei 0:03b5121a232e 5667 xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
pcercuei 0:03b5121a232e 5668 return (NULL);
pcercuei 0:03b5121a232e 5669 }
pcercuei 0:03b5121a232e 5670 memset(ret, 0, sizeof(xmlSchemaWildcard));
pcercuei 0:03b5121a232e 5671 ret->type = type;
pcercuei 0:03b5121a232e 5672 ret->node = node;
pcercuei 0:03b5121a232e 5673 WXS_ADD_LOCAL(ctxt, ret);
pcercuei 0:03b5121a232e 5674 return (ret);
pcercuei 0:03b5121a232e 5675 }
pcercuei 0:03b5121a232e 5676
pcercuei 0:03b5121a232e 5677 static void
pcercuei 0:03b5121a232e 5678 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
pcercuei 0:03b5121a232e 5679 {
pcercuei 0:03b5121a232e 5680 if (group == NULL)
pcercuei 0:03b5121a232e 5681 return;
pcercuei 0:03b5121a232e 5682 if (group->members != NULL)
pcercuei 0:03b5121a232e 5683 xmlSchemaItemListFree(group->members);
pcercuei 0:03b5121a232e 5684 xmlFree(group);
pcercuei 0:03b5121a232e 5685 }
pcercuei 0:03b5121a232e 5686
pcercuei 0:03b5121a232e 5687 static xmlSchemaSubstGroupPtr
pcercuei 0:03b5121a232e 5688 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 5689 xmlSchemaElementPtr head)
pcercuei 0:03b5121a232e 5690 {
pcercuei 0:03b5121a232e 5691 xmlSchemaSubstGroupPtr ret;
pcercuei 0:03b5121a232e 5692
pcercuei 0:03b5121a232e 5693 /* Init subst group hash. */
pcercuei 0:03b5121a232e 5694 if (WXS_SUBST_GROUPS(pctxt) == NULL) {
pcercuei 0:03b5121a232e 5695 WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
pcercuei 0:03b5121a232e 5696 if (WXS_SUBST_GROUPS(pctxt) == NULL)
pcercuei 0:03b5121a232e 5697 return(NULL);
pcercuei 0:03b5121a232e 5698 }
pcercuei 0:03b5121a232e 5699 /* Create a new substitution group. */
pcercuei 0:03b5121a232e 5700 ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
pcercuei 0:03b5121a232e 5701 if (ret == NULL) {
pcercuei 0:03b5121a232e 5702 xmlSchemaPErrMemory(NULL,
pcercuei 0:03b5121a232e 5703 "allocating a substitution group container", NULL);
pcercuei 0:03b5121a232e 5704 return(NULL);
pcercuei 0:03b5121a232e 5705 }
pcercuei 0:03b5121a232e 5706 memset(ret, 0, sizeof(xmlSchemaSubstGroup));
pcercuei 0:03b5121a232e 5707 ret->head = head;
pcercuei 0:03b5121a232e 5708 /* Create list of members. */
pcercuei 0:03b5121a232e 5709 ret->members = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 5710 if (ret->members == NULL) {
pcercuei 0:03b5121a232e 5711 xmlSchemaSubstGroupFree(ret);
pcercuei 0:03b5121a232e 5712 return(NULL);
pcercuei 0:03b5121a232e 5713 }
pcercuei 0:03b5121a232e 5714 /* Add subst group to hash. */
pcercuei 0:03b5121a232e 5715 if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
pcercuei 0:03b5121a232e 5716 head->name, head->targetNamespace, ret) != 0) {
pcercuei 0:03b5121a232e 5717 PERROR_INT("xmlSchemaSubstGroupAdd",
pcercuei 0:03b5121a232e 5718 "failed to add a new substitution container");
pcercuei 0:03b5121a232e 5719 xmlSchemaSubstGroupFree(ret);
pcercuei 0:03b5121a232e 5720 return(NULL);
pcercuei 0:03b5121a232e 5721 }
pcercuei 0:03b5121a232e 5722 return(ret);
pcercuei 0:03b5121a232e 5723 }
pcercuei 0:03b5121a232e 5724
pcercuei 0:03b5121a232e 5725 static xmlSchemaSubstGroupPtr
pcercuei 0:03b5121a232e 5726 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 5727 xmlSchemaElementPtr head)
pcercuei 0:03b5121a232e 5728 {
pcercuei 0:03b5121a232e 5729 if (WXS_SUBST_GROUPS(pctxt) == NULL)
pcercuei 0:03b5121a232e 5730 return(NULL);
pcercuei 0:03b5121a232e 5731 return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
pcercuei 0:03b5121a232e 5732 head->name, head->targetNamespace));
pcercuei 0:03b5121a232e 5733
pcercuei 0:03b5121a232e 5734 }
pcercuei 0:03b5121a232e 5735
pcercuei 0:03b5121a232e 5736 /**
pcercuei 0:03b5121a232e 5737 * xmlSchemaAddElementSubstitutionMember:
pcercuei 0:03b5121a232e 5738 * @pctxt: a schema parser context
pcercuei 0:03b5121a232e 5739 * @head: the head of the substitution group
pcercuei 0:03b5121a232e 5740 * @member: the new member of the substitution group
pcercuei 0:03b5121a232e 5741 *
pcercuei 0:03b5121a232e 5742 * Allocate a new annotation structure.
pcercuei 0:03b5121a232e 5743 *
pcercuei 0:03b5121a232e 5744 * Returns the newly allocated structure or NULL in case or error
pcercuei 0:03b5121a232e 5745 */
pcercuei 0:03b5121a232e 5746 static int
pcercuei 0:03b5121a232e 5747 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 5748 xmlSchemaElementPtr head,
pcercuei 0:03b5121a232e 5749 xmlSchemaElementPtr member)
pcercuei 0:03b5121a232e 5750 {
pcercuei 0:03b5121a232e 5751 xmlSchemaSubstGroupPtr substGroup = NULL;
pcercuei 0:03b5121a232e 5752
pcercuei 0:03b5121a232e 5753 if ((pctxt == NULL) || (head == NULL) || (member == NULL))
pcercuei 0:03b5121a232e 5754 return (-1);
pcercuei 0:03b5121a232e 5755
pcercuei 0:03b5121a232e 5756 substGroup = xmlSchemaSubstGroupGet(pctxt, head);
pcercuei 0:03b5121a232e 5757 if (substGroup == NULL)
pcercuei 0:03b5121a232e 5758 substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
pcercuei 0:03b5121a232e 5759 if (substGroup == NULL)
pcercuei 0:03b5121a232e 5760 return(-1);
pcercuei 0:03b5121a232e 5761 if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
pcercuei 0:03b5121a232e 5762 return(-1);
pcercuei 0:03b5121a232e 5763 return(0);
pcercuei 0:03b5121a232e 5764 }
pcercuei 0:03b5121a232e 5765
pcercuei 0:03b5121a232e 5766 /************************************************************************
pcercuei 0:03b5121a232e 5767 * *
pcercuei 0:03b5121a232e 5768 * Utilities for parsing *
pcercuei 0:03b5121a232e 5769 * *
pcercuei 0:03b5121a232e 5770 ************************************************************************/
pcercuei 0:03b5121a232e 5771
pcercuei 0:03b5121a232e 5772 /**
pcercuei 0:03b5121a232e 5773 * xmlSchemaPValAttrNodeQNameValue:
pcercuei 0:03b5121a232e 5774 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 5775 * @schema: the schema context
pcercuei 0:03b5121a232e 5776 * @ownerDes: the designation of the parent element
pcercuei 0:03b5121a232e 5777 * @ownerItem: the parent as a schema object
pcercuei 0:03b5121a232e 5778 * @value: the QName value
pcercuei 0:03b5121a232e 5779 * @local: the resulting local part if found, the attribute value otherwise
pcercuei 0:03b5121a232e 5780 * @uri: the resulting namespace URI if found
pcercuei 0:03b5121a232e 5781 *
pcercuei 0:03b5121a232e 5782 * Extracts the local name and the URI of a QName value and validates it.
pcercuei 0:03b5121a232e 5783 * This one is intended to be used on attribute values that
pcercuei 0:03b5121a232e 5784 * should resolve to schema components.
pcercuei 0:03b5121a232e 5785 *
pcercuei 0:03b5121a232e 5786 * Returns 0, in case the QName is valid, a positive error code
pcercuei 0:03b5121a232e 5787 * if not valid and -1 if an internal error occurs.
pcercuei 0:03b5121a232e 5788 */
pcercuei 0:03b5121a232e 5789 static int
pcercuei 0:03b5121a232e 5790 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 5791 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 5792 xmlSchemaBasicItemPtr ownerItem,
pcercuei 0:03b5121a232e 5793 xmlAttrPtr attr,
pcercuei 0:03b5121a232e 5794 const xmlChar *value,
pcercuei 0:03b5121a232e 5795 const xmlChar **uri,
pcercuei 0:03b5121a232e 5796 const xmlChar **local)
pcercuei 0:03b5121a232e 5797 {
pcercuei 0:03b5121a232e 5798 const xmlChar *pref;
pcercuei 0:03b5121a232e 5799 xmlNsPtr ns;
pcercuei 0:03b5121a232e 5800 int len, ret;
pcercuei 0:03b5121a232e 5801
pcercuei 0:03b5121a232e 5802 *uri = NULL;
pcercuei 0:03b5121a232e 5803 *local = NULL;
pcercuei 0:03b5121a232e 5804 ret = xmlValidateQName(value, 1);
pcercuei 0:03b5121a232e 5805 if (ret > 0) {
pcercuei 0:03b5121a232e 5806 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 5807 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 5808 ownerItem, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 5809 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
pcercuei 0:03b5121a232e 5810 NULL, value, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 5811 *local = value;
pcercuei 0:03b5121a232e 5812 return (ctxt->err);
pcercuei 0:03b5121a232e 5813 } else if (ret < 0)
pcercuei 0:03b5121a232e 5814 return (-1);
pcercuei 0:03b5121a232e 5815
pcercuei 0:03b5121a232e 5816 if (!strchr((char *) value, ':')) {
pcercuei 0:03b5121a232e 5817 ns = xmlSearchNs(attr->doc, attr->parent, NULL);
pcercuei 0:03b5121a232e 5818 if (ns)
pcercuei 0:03b5121a232e 5819 *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
pcercuei 0:03b5121a232e 5820 else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
pcercuei 0:03b5121a232e 5821 /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
pcercuei 0:03b5121a232e 5822 * parser context. */
pcercuei 0:03b5121a232e 5823 /*
pcercuei 0:03b5121a232e 5824 * This one takes care of included schemas with no
pcercuei 0:03b5121a232e 5825 * target namespace.
pcercuei 0:03b5121a232e 5826 */
pcercuei 0:03b5121a232e 5827 *uri = ctxt->targetNamespace;
pcercuei 0:03b5121a232e 5828 }
pcercuei 0:03b5121a232e 5829 *local = xmlDictLookup(ctxt->dict, value, -1);
pcercuei 0:03b5121a232e 5830 return (0);
pcercuei 0:03b5121a232e 5831 }
pcercuei 0:03b5121a232e 5832 /*
pcercuei 0:03b5121a232e 5833 * At this point xmlSplitQName3 has to return a local name.
pcercuei 0:03b5121a232e 5834 */
pcercuei 0:03b5121a232e 5835 *local = xmlSplitQName3(value, &len);
pcercuei 0:03b5121a232e 5836 *local = xmlDictLookup(ctxt->dict, *local, -1);
pcercuei 0:03b5121a232e 5837 pref = xmlDictLookup(ctxt->dict, value, len);
pcercuei 0:03b5121a232e 5838 ns = xmlSearchNs(attr->doc, attr->parent, pref);
pcercuei 0:03b5121a232e 5839 if (ns == NULL) {
pcercuei 0:03b5121a232e 5840 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 5841 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 5842 ownerItem, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 5843 xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
pcercuei 0:03b5121a232e 5844 "The value '%s' of simple type 'xs:QName' has no "
pcercuei 0:03b5121a232e 5845 "corresponding namespace declaration in scope", value, NULL);
pcercuei 0:03b5121a232e 5846 return (ctxt->err);
pcercuei 0:03b5121a232e 5847 } else {
pcercuei 0:03b5121a232e 5848 *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
pcercuei 0:03b5121a232e 5849 }
pcercuei 0:03b5121a232e 5850 return (0);
pcercuei 0:03b5121a232e 5851 }
pcercuei 0:03b5121a232e 5852
pcercuei 0:03b5121a232e 5853 /**
pcercuei 0:03b5121a232e 5854 * xmlSchemaPValAttrNodeQName:
pcercuei 0:03b5121a232e 5855 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 5856 * @schema: the schema context
pcercuei 0:03b5121a232e 5857 * @ownerDes: the designation of the owner element
pcercuei 0:03b5121a232e 5858 * @ownerItem: the owner as a schema object
pcercuei 0:03b5121a232e 5859 * @attr: the attribute node
pcercuei 0:03b5121a232e 5860 * @local: the resulting local part if found, the attribute value otherwise
pcercuei 0:03b5121a232e 5861 * @uri: the resulting namespace URI if found
pcercuei 0:03b5121a232e 5862 *
pcercuei 0:03b5121a232e 5863 * Extracts and validates the QName of an attribute value.
pcercuei 0:03b5121a232e 5864 * This one is intended to be used on attribute values that
pcercuei 0:03b5121a232e 5865 * should resolve to schema components.
pcercuei 0:03b5121a232e 5866 *
pcercuei 0:03b5121a232e 5867 * Returns 0, in case the QName is valid, a positive error code
pcercuei 0:03b5121a232e 5868 * if not valid and -1 if an internal error occurs.
pcercuei 0:03b5121a232e 5869 */
pcercuei 0:03b5121a232e 5870 static int
pcercuei 0:03b5121a232e 5871 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 5872 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 5873 xmlSchemaBasicItemPtr ownerItem,
pcercuei 0:03b5121a232e 5874 xmlAttrPtr attr,
pcercuei 0:03b5121a232e 5875 const xmlChar **uri,
pcercuei 0:03b5121a232e 5876 const xmlChar **local)
pcercuei 0:03b5121a232e 5877 {
pcercuei 0:03b5121a232e 5878 const xmlChar *value;
pcercuei 0:03b5121a232e 5879
pcercuei 0:03b5121a232e 5880 value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 5881 return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
pcercuei 0:03b5121a232e 5882 ownerItem, attr, value, uri, local));
pcercuei 0:03b5121a232e 5883 }
pcercuei 0:03b5121a232e 5884
pcercuei 0:03b5121a232e 5885 /**
pcercuei 0:03b5121a232e 5886 * xmlSchemaPValAttrQName:
pcercuei 0:03b5121a232e 5887 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 5888 * @schema: the schema context
pcercuei 0:03b5121a232e 5889 * @ownerDes: the designation of the parent element
pcercuei 0:03b5121a232e 5890 * @ownerItem: the owner as a schema object
pcercuei 0:03b5121a232e 5891 * @ownerElem: the parent node of the attribute
pcercuei 0:03b5121a232e 5892 * @name: the name of the attribute
pcercuei 0:03b5121a232e 5893 * @local: the resulting local part if found, the attribute value otherwise
pcercuei 0:03b5121a232e 5894 * @uri: the resulting namespace URI if found
pcercuei 0:03b5121a232e 5895 *
pcercuei 0:03b5121a232e 5896 * Extracts and validates the QName of an attribute value.
pcercuei 0:03b5121a232e 5897 *
pcercuei 0:03b5121a232e 5898 * Returns 0, in case the QName is valid, a positive error code
pcercuei 0:03b5121a232e 5899 * if not valid and -1 if an internal error occurs.
pcercuei 0:03b5121a232e 5900 */
pcercuei 0:03b5121a232e 5901 static int
pcercuei 0:03b5121a232e 5902 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 5903 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 5904 xmlSchemaBasicItemPtr ownerItem,
pcercuei 0:03b5121a232e 5905 xmlNodePtr ownerElem,
pcercuei 0:03b5121a232e 5906 const char *name,
pcercuei 0:03b5121a232e 5907 const xmlChar **uri,
pcercuei 0:03b5121a232e 5908 const xmlChar **local)
pcercuei 0:03b5121a232e 5909 {
pcercuei 0:03b5121a232e 5910 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 5911
pcercuei 0:03b5121a232e 5912 attr = xmlSchemaGetPropNode(ownerElem, name);
pcercuei 0:03b5121a232e 5913 if (attr == NULL) {
pcercuei 0:03b5121a232e 5914 *local = NULL;
pcercuei 0:03b5121a232e 5915 *uri = NULL;
pcercuei 0:03b5121a232e 5916 return (0);
pcercuei 0:03b5121a232e 5917 }
pcercuei 0:03b5121a232e 5918 return (xmlSchemaPValAttrNodeQName(ctxt, schema,
pcercuei 0:03b5121a232e 5919 ownerItem, attr, uri, local));
pcercuei 0:03b5121a232e 5920 }
pcercuei 0:03b5121a232e 5921
pcercuei 0:03b5121a232e 5922 /**
pcercuei 0:03b5121a232e 5923 * xmlSchemaPValAttrID:
pcercuei 0:03b5121a232e 5924 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 5925 * @schema: the schema context
pcercuei 0:03b5121a232e 5926 * @ownerDes: the designation of the parent element
pcercuei 0:03b5121a232e 5927 * @ownerItem: the owner as a schema object
pcercuei 0:03b5121a232e 5928 * @ownerElem: the parent node of the attribute
pcercuei 0:03b5121a232e 5929 * @name: the name of the attribute
pcercuei 0:03b5121a232e 5930 *
pcercuei 0:03b5121a232e 5931 * Extracts and validates the ID of an attribute value.
pcercuei 0:03b5121a232e 5932 *
pcercuei 0:03b5121a232e 5933 * Returns 0, in case the ID is valid, a positive error code
pcercuei 0:03b5121a232e 5934 * if not valid and -1 if an internal error occurs.
pcercuei 0:03b5121a232e 5935 */
pcercuei 0:03b5121a232e 5936 static int
pcercuei 0:03b5121a232e 5937 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
pcercuei 0:03b5121a232e 5938 {
pcercuei 0:03b5121a232e 5939 int ret;
pcercuei 0:03b5121a232e 5940 const xmlChar *value;
pcercuei 0:03b5121a232e 5941
pcercuei 0:03b5121a232e 5942 if (attr == NULL)
pcercuei 0:03b5121a232e 5943 return(0);
pcercuei 0:03b5121a232e 5944 value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
pcercuei 0:03b5121a232e 5945 ret = xmlValidateNCName(value, 1);
pcercuei 0:03b5121a232e 5946 if (ret == 0) {
pcercuei 0:03b5121a232e 5947 /*
pcercuei 0:03b5121a232e 5948 * NOTE: the IDness might have already be declared in the DTD
pcercuei 0:03b5121a232e 5949 */
pcercuei 0:03b5121a232e 5950 if (attr->atype != XML_ATTRIBUTE_ID) {
pcercuei 0:03b5121a232e 5951 xmlIDPtr res;
pcercuei 0:03b5121a232e 5952 xmlChar *strip;
pcercuei 0:03b5121a232e 5953
pcercuei 0:03b5121a232e 5954 /*
pcercuei 0:03b5121a232e 5955 * TODO: Use xmlSchemaStrip here; it's not exported at this
pcercuei 0:03b5121a232e 5956 * moment.
pcercuei 0:03b5121a232e 5957 */
pcercuei 0:03b5121a232e 5958 strip = xmlSchemaCollapseString(value);
pcercuei 0:03b5121a232e 5959 if (strip != NULL) {
pcercuei 0:03b5121a232e 5960 xmlFree((xmlChar *) value);
pcercuei 0:03b5121a232e 5961 value = strip;
pcercuei 0:03b5121a232e 5962 }
pcercuei 0:03b5121a232e 5963 res = xmlAddID(NULL, attr->doc, value, attr);
pcercuei 0:03b5121a232e 5964 if (res == NULL) {
pcercuei 0:03b5121a232e 5965 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
pcercuei 0:03b5121a232e 5966 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 5967 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 5968 NULL, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 5969 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
pcercuei 0:03b5121a232e 5970 NULL, NULL, "Duplicate value '%s' of simple "
pcercuei 0:03b5121a232e 5971 "type 'xs:ID'", value, NULL);
pcercuei 0:03b5121a232e 5972 } else
pcercuei 0:03b5121a232e 5973 attr->atype = XML_ATTRIBUTE_ID;
pcercuei 0:03b5121a232e 5974 }
pcercuei 0:03b5121a232e 5975 } else if (ret > 0) {
pcercuei 0:03b5121a232e 5976 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
pcercuei 0:03b5121a232e 5977 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 5978 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 5979 NULL, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 5980 xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
pcercuei 0:03b5121a232e 5981 NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
pcercuei 0:03b5121a232e 5982 "not a valid 'xs:NCName'",
pcercuei 0:03b5121a232e 5983 value, NULL);
pcercuei 0:03b5121a232e 5984 }
pcercuei 0:03b5121a232e 5985 if (value != NULL)
pcercuei 0:03b5121a232e 5986 xmlFree((xmlChar *)value);
pcercuei 0:03b5121a232e 5987
pcercuei 0:03b5121a232e 5988 return (ret);
pcercuei 0:03b5121a232e 5989 }
pcercuei 0:03b5121a232e 5990
pcercuei 0:03b5121a232e 5991 static int
pcercuei 0:03b5121a232e 5992 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 5993 xmlNodePtr ownerElem,
pcercuei 0:03b5121a232e 5994 const xmlChar *name)
pcercuei 0:03b5121a232e 5995 {
pcercuei 0:03b5121a232e 5996 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 5997
pcercuei 0:03b5121a232e 5998 attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
pcercuei 0:03b5121a232e 5999 if (attr == NULL)
pcercuei 0:03b5121a232e 6000 return(0);
pcercuei 0:03b5121a232e 6001 return(xmlSchemaPValAttrNodeID(ctxt, attr));
pcercuei 0:03b5121a232e 6002
pcercuei 0:03b5121a232e 6003 }
pcercuei 0:03b5121a232e 6004
pcercuei 0:03b5121a232e 6005 /**
pcercuei 0:03b5121a232e 6006 * xmlGetMaxOccurs:
pcercuei 0:03b5121a232e 6007 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 6008 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 6009 *
pcercuei 0:03b5121a232e 6010 * Get the maxOccurs property
pcercuei 0:03b5121a232e 6011 *
pcercuei 0:03b5121a232e 6012 * Returns the default if not found, or the value
pcercuei 0:03b5121a232e 6013 */
pcercuei 0:03b5121a232e 6014 static int
pcercuei 0:03b5121a232e 6015 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
pcercuei 0:03b5121a232e 6016 int min, int max, int def, const char *expected)
pcercuei 0:03b5121a232e 6017 {
pcercuei 0:03b5121a232e 6018 const xmlChar *val, *cur;
pcercuei 0:03b5121a232e 6019 int ret = 0;
pcercuei 0:03b5121a232e 6020 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 6021
pcercuei 0:03b5121a232e 6022 attr = xmlSchemaGetPropNode(node, "maxOccurs");
pcercuei 0:03b5121a232e 6023 if (attr == NULL)
pcercuei 0:03b5121a232e 6024 return (def);
pcercuei 0:03b5121a232e 6025 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 6026
pcercuei 0:03b5121a232e 6027 if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
pcercuei 0:03b5121a232e 6028 if (max != UNBOUNDED) {
pcercuei 0:03b5121a232e 6029 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 6030 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 6031 /* XML_SCHEMAP_INVALID_MINOCCURS, */
pcercuei 0:03b5121a232e 6032 NULL, (xmlNodePtr) attr, NULL, expected,
pcercuei 0:03b5121a232e 6033 val, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 6034 return (def);
pcercuei 0:03b5121a232e 6035 } else
pcercuei 0:03b5121a232e 6036 return (UNBOUNDED); /* encoding it with -1 might be another option */
pcercuei 0:03b5121a232e 6037 }
pcercuei 0:03b5121a232e 6038
pcercuei 0:03b5121a232e 6039 cur = val;
pcercuei 0:03b5121a232e 6040 while (IS_BLANK_CH(*cur))
pcercuei 0:03b5121a232e 6041 cur++;
pcercuei 0:03b5121a232e 6042 if (*cur == 0) {
pcercuei 0:03b5121a232e 6043 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 6044 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 6045 /* XML_SCHEMAP_INVALID_MINOCCURS, */
pcercuei 0:03b5121a232e 6046 NULL, (xmlNodePtr) attr, NULL, expected,
pcercuei 0:03b5121a232e 6047 val, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 6048 return (def);
pcercuei 0:03b5121a232e 6049 }
pcercuei 0:03b5121a232e 6050 while ((*cur >= '0') && (*cur <= '9')) {
pcercuei 0:03b5121a232e 6051 ret = ret * 10 + (*cur - '0');
pcercuei 0:03b5121a232e 6052 cur++;
pcercuei 0:03b5121a232e 6053 }
pcercuei 0:03b5121a232e 6054 while (IS_BLANK_CH(*cur))
pcercuei 0:03b5121a232e 6055 cur++;
pcercuei 0:03b5121a232e 6056 /*
pcercuei 0:03b5121a232e 6057 * TODO: Restrict the maximal value to Integer.
pcercuei 0:03b5121a232e 6058 */
pcercuei 0:03b5121a232e 6059 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
pcercuei 0:03b5121a232e 6060 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 6061 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 6062 /* XML_SCHEMAP_INVALID_MINOCCURS, */
pcercuei 0:03b5121a232e 6063 NULL, (xmlNodePtr) attr, NULL, expected,
pcercuei 0:03b5121a232e 6064 val, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 6065 return (def);
pcercuei 0:03b5121a232e 6066 }
pcercuei 0:03b5121a232e 6067 return (ret);
pcercuei 0:03b5121a232e 6068 }
pcercuei 0:03b5121a232e 6069
pcercuei 0:03b5121a232e 6070 /**
pcercuei 0:03b5121a232e 6071 * xmlGetMinOccurs:
pcercuei 0:03b5121a232e 6072 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 6073 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 6074 *
pcercuei 0:03b5121a232e 6075 * Get the minOccurs property
pcercuei 0:03b5121a232e 6076 *
pcercuei 0:03b5121a232e 6077 * Returns the default if not found, or the value
pcercuei 0:03b5121a232e 6078 */
pcercuei 0:03b5121a232e 6079 static int
pcercuei 0:03b5121a232e 6080 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
pcercuei 0:03b5121a232e 6081 int min, int max, int def, const char *expected)
pcercuei 0:03b5121a232e 6082 {
pcercuei 0:03b5121a232e 6083 const xmlChar *val, *cur;
pcercuei 0:03b5121a232e 6084 int ret = 0;
pcercuei 0:03b5121a232e 6085 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 6086
pcercuei 0:03b5121a232e 6087 attr = xmlSchemaGetPropNode(node, "minOccurs");
pcercuei 0:03b5121a232e 6088 if (attr == NULL)
pcercuei 0:03b5121a232e 6089 return (def);
pcercuei 0:03b5121a232e 6090 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 6091 cur = val;
pcercuei 0:03b5121a232e 6092 while (IS_BLANK_CH(*cur))
pcercuei 0:03b5121a232e 6093 cur++;
pcercuei 0:03b5121a232e 6094 if (*cur == 0) {
pcercuei 0:03b5121a232e 6095 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 6096 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 6097 /* XML_SCHEMAP_INVALID_MINOCCURS, */
pcercuei 0:03b5121a232e 6098 NULL, (xmlNodePtr) attr, NULL, expected,
pcercuei 0:03b5121a232e 6099 val, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 6100 return (def);
pcercuei 0:03b5121a232e 6101 }
pcercuei 0:03b5121a232e 6102 while ((*cur >= '0') && (*cur <= '9')) {
pcercuei 0:03b5121a232e 6103 ret = ret * 10 + (*cur - '0');
pcercuei 0:03b5121a232e 6104 cur++;
pcercuei 0:03b5121a232e 6105 }
pcercuei 0:03b5121a232e 6106 while (IS_BLANK_CH(*cur))
pcercuei 0:03b5121a232e 6107 cur++;
pcercuei 0:03b5121a232e 6108 /*
pcercuei 0:03b5121a232e 6109 * TODO: Restrict the maximal value to Integer.
pcercuei 0:03b5121a232e 6110 */
pcercuei 0:03b5121a232e 6111 if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
pcercuei 0:03b5121a232e 6112 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 6113 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 6114 /* XML_SCHEMAP_INVALID_MINOCCURS, */
pcercuei 0:03b5121a232e 6115 NULL, (xmlNodePtr) attr, NULL, expected,
pcercuei 0:03b5121a232e 6116 val, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 6117 return (def);
pcercuei 0:03b5121a232e 6118 }
pcercuei 0:03b5121a232e 6119 return (ret);
pcercuei 0:03b5121a232e 6120 }
pcercuei 0:03b5121a232e 6121
pcercuei 0:03b5121a232e 6122 /**
pcercuei 0:03b5121a232e 6123 * xmlSchemaPGetBoolNodeValue:
pcercuei 0:03b5121a232e 6124 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 6125 * @ownerDes: owner designation
pcercuei 0:03b5121a232e 6126 * @ownerItem: the owner as a schema item
pcercuei 0:03b5121a232e 6127 * @node: the node holding the value
pcercuei 0:03b5121a232e 6128 *
pcercuei 0:03b5121a232e 6129 * Converts a boolean string value into 1 or 0.
pcercuei 0:03b5121a232e 6130 *
pcercuei 0:03b5121a232e 6131 * Returns 0 or 1.
pcercuei 0:03b5121a232e 6132 */
pcercuei 0:03b5121a232e 6133 static int
pcercuei 0:03b5121a232e 6134 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 6135 xmlSchemaBasicItemPtr ownerItem,
pcercuei 0:03b5121a232e 6136 xmlNodePtr node)
pcercuei 0:03b5121a232e 6137 {
pcercuei 0:03b5121a232e 6138 xmlChar *value = NULL;
pcercuei 0:03b5121a232e 6139 int res = 0;
pcercuei 0:03b5121a232e 6140
pcercuei 0:03b5121a232e 6141 value = xmlNodeGetContent(node);
pcercuei 0:03b5121a232e 6142 /*
pcercuei 0:03b5121a232e 6143 * 3.2.2.1 Lexical representation
pcercuei 0:03b5121a232e 6144 * An instance of a datatype that is defined as `boolean`
pcercuei 0:03b5121a232e 6145 * can have the following legal literals {true, false, 1, 0}.
pcercuei 0:03b5121a232e 6146 */
pcercuei 0:03b5121a232e 6147 if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
pcercuei 0:03b5121a232e 6148 res = 1;
pcercuei 0:03b5121a232e 6149 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
pcercuei 0:03b5121a232e 6150 res = 0;
pcercuei 0:03b5121a232e 6151 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
pcercuei 0:03b5121a232e 6152 res = 1;
pcercuei 0:03b5121a232e 6153 else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
pcercuei 0:03b5121a232e 6154 res = 0;
pcercuei 0:03b5121a232e 6155 else {
pcercuei 0:03b5121a232e 6156 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 6157 XML_SCHEMAP_INVALID_BOOLEAN,
pcercuei 0:03b5121a232e 6158 ownerItem, node,
pcercuei 0:03b5121a232e 6159 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
pcercuei 0:03b5121a232e 6160 NULL, BAD_CAST value,
pcercuei 0:03b5121a232e 6161 NULL, NULL, NULL);
pcercuei 0:03b5121a232e 6162 }
pcercuei 0:03b5121a232e 6163 if (value != NULL)
pcercuei 0:03b5121a232e 6164 xmlFree(value);
pcercuei 0:03b5121a232e 6165 return (res);
pcercuei 0:03b5121a232e 6166 }
pcercuei 0:03b5121a232e 6167
pcercuei 0:03b5121a232e 6168 /**
pcercuei 0:03b5121a232e 6169 * xmlGetBooleanProp:
pcercuei 0:03b5121a232e 6170 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 6171 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 6172 * @name: the attribute name
pcercuei 0:03b5121a232e 6173 * @def: the default value
pcercuei 0:03b5121a232e 6174 *
pcercuei 0:03b5121a232e 6175 * Evaluate if a boolean property is set
pcercuei 0:03b5121a232e 6176 *
pcercuei 0:03b5121a232e 6177 * Returns the default if not found, 0 if found to be false,
pcercuei 0:03b5121a232e 6178 * 1 if found to be true
pcercuei 0:03b5121a232e 6179 */
pcercuei 0:03b5121a232e 6180 static int
pcercuei 0:03b5121a232e 6181 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 6182 xmlNodePtr node,
pcercuei 0:03b5121a232e 6183 const char *name, int def)
pcercuei 0:03b5121a232e 6184 {
pcercuei 0:03b5121a232e 6185 const xmlChar *val;
pcercuei 0:03b5121a232e 6186
pcercuei 0:03b5121a232e 6187 val = xmlSchemaGetProp(ctxt, node, name);
pcercuei 0:03b5121a232e 6188 if (val == NULL)
pcercuei 0:03b5121a232e 6189 return (def);
pcercuei 0:03b5121a232e 6190 /*
pcercuei 0:03b5121a232e 6191 * 3.2.2.1 Lexical representation
pcercuei 0:03b5121a232e 6192 * An instance of a datatype that is defined as `boolean`
pcercuei 0:03b5121a232e 6193 * can have the following legal literals {true, false, 1, 0}.
pcercuei 0:03b5121a232e 6194 */
pcercuei 0:03b5121a232e 6195 if (xmlStrEqual(val, BAD_CAST "true"))
pcercuei 0:03b5121a232e 6196 def = 1;
pcercuei 0:03b5121a232e 6197 else if (xmlStrEqual(val, BAD_CAST "false"))
pcercuei 0:03b5121a232e 6198 def = 0;
pcercuei 0:03b5121a232e 6199 else if (xmlStrEqual(val, BAD_CAST "1"))
pcercuei 0:03b5121a232e 6200 def = 1;
pcercuei 0:03b5121a232e 6201 else if (xmlStrEqual(val, BAD_CAST "0"))
pcercuei 0:03b5121a232e 6202 def = 0;
pcercuei 0:03b5121a232e 6203 else {
pcercuei 0:03b5121a232e 6204 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 6205 XML_SCHEMAP_INVALID_BOOLEAN,
pcercuei 0:03b5121a232e 6206 NULL,
pcercuei 0:03b5121a232e 6207 (xmlNodePtr) xmlSchemaGetPropNode(node, name),
pcercuei 0:03b5121a232e 6208 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
pcercuei 0:03b5121a232e 6209 NULL, val, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 6210 }
pcercuei 0:03b5121a232e 6211 return (def);
pcercuei 0:03b5121a232e 6212 }
pcercuei 0:03b5121a232e 6213
pcercuei 0:03b5121a232e 6214 /************************************************************************
pcercuei 0:03b5121a232e 6215 * *
pcercuei 0:03b5121a232e 6216 * Shema extraction from an Infoset *
pcercuei 0:03b5121a232e 6217 * *
pcercuei 0:03b5121a232e 6218 ************************************************************************/
pcercuei 0:03b5121a232e 6219 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
pcercuei 0:03b5121a232e 6220 ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 6221 xmlNodePtr node,
pcercuei 0:03b5121a232e 6222 int topLevel);
pcercuei 0:03b5121a232e 6223 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
pcercuei 0:03b5121a232e 6224 ctxt,
pcercuei 0:03b5121a232e 6225 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 6226 xmlNodePtr node,
pcercuei 0:03b5121a232e 6227 int topLevel);
pcercuei 0:03b5121a232e 6228 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
pcercuei 0:03b5121a232e 6229 ctxt,
pcercuei 0:03b5121a232e 6230 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 6231 xmlNodePtr node,
pcercuei 0:03b5121a232e 6232 xmlSchemaTypeType parentType);
pcercuei 0:03b5121a232e 6233 static xmlSchemaBasicItemPtr
pcercuei 0:03b5121a232e 6234 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 6235 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 6236 xmlNodePtr node,
pcercuei 0:03b5121a232e 6237 xmlSchemaItemListPtr uses,
pcercuei 0:03b5121a232e 6238 int parentType);
pcercuei 0:03b5121a232e 6239 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 6240 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 6241 xmlNodePtr node);
pcercuei 0:03b5121a232e 6242 static xmlSchemaWildcardPtr
pcercuei 0:03b5121a232e 6243 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 6244 xmlSchemaPtr schema, xmlNodePtr node);
pcercuei 0:03b5121a232e 6245
pcercuei 0:03b5121a232e 6246 /**
pcercuei 0:03b5121a232e 6247 * xmlSchemaPValAttrNodeValue:
pcercuei 0:03b5121a232e 6248 *
pcercuei 0:03b5121a232e 6249 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 6250 * @ownerDes: the designation of the parent element
pcercuei 0:03b5121a232e 6251 * @ownerItem: the schema object owner if existent
pcercuei 0:03b5121a232e 6252 * @attr: the schema attribute node being validated
pcercuei 0:03b5121a232e 6253 * @value: the value
pcercuei 0:03b5121a232e 6254 * @type: the built-in type to be validated against
pcercuei 0:03b5121a232e 6255 *
pcercuei 0:03b5121a232e 6256 * Validates a value against the given built-in type.
pcercuei 0:03b5121a232e 6257 * This one is intended to be used internally for validation
pcercuei 0:03b5121a232e 6258 * of schema attribute values during parsing of the schema.
pcercuei 0:03b5121a232e 6259 *
pcercuei 0:03b5121a232e 6260 * Returns 0 if the value is valid, a positive error code
pcercuei 0:03b5121a232e 6261 * number otherwise and -1 in case of an internal or API error.
pcercuei 0:03b5121a232e 6262 */
pcercuei 0:03b5121a232e 6263 static int
pcercuei 0:03b5121a232e 6264 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 6265 xmlSchemaBasicItemPtr ownerItem,
pcercuei 0:03b5121a232e 6266 xmlAttrPtr attr,
pcercuei 0:03b5121a232e 6267 const xmlChar *value,
pcercuei 0:03b5121a232e 6268 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 6269 {
pcercuei 0:03b5121a232e 6270
pcercuei 0:03b5121a232e 6271 int ret = 0;
pcercuei 0:03b5121a232e 6272
pcercuei 0:03b5121a232e 6273 /*
pcercuei 0:03b5121a232e 6274 * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
pcercuei 0:03b5121a232e 6275 * one is really meant to be used internally, so better not.
pcercuei 0:03b5121a232e 6276 */
pcercuei 0:03b5121a232e 6277 if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
pcercuei 0:03b5121a232e 6278 return (-1);
pcercuei 0:03b5121a232e 6279 if (type->type != XML_SCHEMA_TYPE_BASIC) {
pcercuei 0:03b5121a232e 6280 PERROR_INT("xmlSchemaPValAttrNodeValue",
pcercuei 0:03b5121a232e 6281 "the given type is not a built-in type");
pcercuei 0:03b5121a232e 6282 return (-1);
pcercuei 0:03b5121a232e 6283 }
pcercuei 0:03b5121a232e 6284 switch (type->builtInType) {
pcercuei 0:03b5121a232e 6285 case XML_SCHEMAS_NCNAME:
pcercuei 0:03b5121a232e 6286 case XML_SCHEMAS_QNAME:
pcercuei 0:03b5121a232e 6287 case XML_SCHEMAS_ANYURI:
pcercuei 0:03b5121a232e 6288 case XML_SCHEMAS_TOKEN:
pcercuei 0:03b5121a232e 6289 case XML_SCHEMAS_LANGUAGE:
pcercuei 0:03b5121a232e 6290 ret = xmlSchemaValPredefTypeNode(type, value, NULL,
pcercuei 0:03b5121a232e 6291 (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 6292 break;
pcercuei 0:03b5121a232e 6293 default: {
pcercuei 0:03b5121a232e 6294 PERROR_INT("xmlSchemaPValAttrNodeValue",
pcercuei 0:03b5121a232e 6295 "validation using the given type is not supported while "
pcercuei 0:03b5121a232e 6296 "parsing a schema");
pcercuei 0:03b5121a232e 6297 return (-1);
pcercuei 0:03b5121a232e 6298 }
pcercuei 0:03b5121a232e 6299 }
pcercuei 0:03b5121a232e 6300 /*
pcercuei 0:03b5121a232e 6301 * TODO: Should we use the S4S error codes instead?
pcercuei 0:03b5121a232e 6302 */
pcercuei 0:03b5121a232e 6303 if (ret < 0) {
pcercuei 0:03b5121a232e 6304 PERROR_INT("xmlSchemaPValAttrNodeValue",
pcercuei 0:03b5121a232e 6305 "failed to validate a schema attribute value");
pcercuei 0:03b5121a232e 6306 return (-1);
pcercuei 0:03b5121a232e 6307 } else if (ret > 0) {
pcercuei 0:03b5121a232e 6308 if (WXS_IS_LIST(type))
pcercuei 0:03b5121a232e 6309 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
pcercuei 0:03b5121a232e 6310 else
pcercuei 0:03b5121a232e 6311 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
pcercuei 0:03b5121a232e 6312 xmlSchemaPSimpleTypeErr(pctxt,
pcercuei 0:03b5121a232e 6313 ret, ownerItem, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 6314 type, NULL, value, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 6315 }
pcercuei 0:03b5121a232e 6316 return (ret);
pcercuei 0:03b5121a232e 6317 }
pcercuei 0:03b5121a232e 6318
pcercuei 0:03b5121a232e 6319 /**
pcercuei 0:03b5121a232e 6320 * xmlSchemaPValAttrNode:
pcercuei 0:03b5121a232e 6321 *
pcercuei 0:03b5121a232e 6322 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 6323 * @ownerDes: the designation of the parent element
pcercuei 0:03b5121a232e 6324 * @ownerItem: the schema object owner if existent
pcercuei 0:03b5121a232e 6325 * @attr: the schema attribute node being validated
pcercuei 0:03b5121a232e 6326 * @type: the built-in type to be validated against
pcercuei 0:03b5121a232e 6327 * @value: the resulting value if any
pcercuei 0:03b5121a232e 6328 *
pcercuei 0:03b5121a232e 6329 * Extracts and validates a value against the given built-in type.
pcercuei 0:03b5121a232e 6330 * This one is intended to be used internally for validation
pcercuei 0:03b5121a232e 6331 * of schema attribute values during parsing of the schema.
pcercuei 0:03b5121a232e 6332 *
pcercuei 0:03b5121a232e 6333 * Returns 0 if the value is valid, a positive error code
pcercuei 0:03b5121a232e 6334 * number otherwise and -1 in case of an internal or API error.
pcercuei 0:03b5121a232e 6335 */
pcercuei 0:03b5121a232e 6336 static int
pcercuei 0:03b5121a232e 6337 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 6338 xmlSchemaBasicItemPtr ownerItem,
pcercuei 0:03b5121a232e 6339 xmlAttrPtr attr,
pcercuei 0:03b5121a232e 6340 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 6341 const xmlChar **value)
pcercuei 0:03b5121a232e 6342 {
pcercuei 0:03b5121a232e 6343 const xmlChar *val;
pcercuei 0:03b5121a232e 6344
pcercuei 0:03b5121a232e 6345 if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
pcercuei 0:03b5121a232e 6346 return (-1);
pcercuei 0:03b5121a232e 6347
pcercuei 0:03b5121a232e 6348 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 6349 if (value != NULL)
pcercuei 0:03b5121a232e 6350 *value = val;
pcercuei 0:03b5121a232e 6351
pcercuei 0:03b5121a232e 6352 return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
pcercuei 0:03b5121a232e 6353 val, type));
pcercuei 0:03b5121a232e 6354 }
pcercuei 0:03b5121a232e 6355
pcercuei 0:03b5121a232e 6356 /**
pcercuei 0:03b5121a232e 6357 * xmlSchemaPValAttr:
pcercuei 0:03b5121a232e 6358 *
pcercuei 0:03b5121a232e 6359 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 6360 * @node: the element node of the attribute
pcercuei 0:03b5121a232e 6361 * @ownerDes: the designation of the parent element
pcercuei 0:03b5121a232e 6362 * @ownerItem: the schema object owner if existent
pcercuei 0:03b5121a232e 6363 * @ownerElem: the owner element node
pcercuei 0:03b5121a232e 6364 * @name: the name of the schema attribute node
pcercuei 0:03b5121a232e 6365 * @type: the built-in type to be validated against
pcercuei 0:03b5121a232e 6366 * @value: the resulting value if any
pcercuei 0:03b5121a232e 6367 *
pcercuei 0:03b5121a232e 6368 * Extracts and validates a value against the given built-in type.
pcercuei 0:03b5121a232e 6369 * This one is intended to be used internally for validation
pcercuei 0:03b5121a232e 6370 * of schema attribute values during parsing of the schema.
pcercuei 0:03b5121a232e 6371 *
pcercuei 0:03b5121a232e 6372 * Returns 0 if the value is valid, a positive error code
pcercuei 0:03b5121a232e 6373 * number otherwise and -1 in case of an internal or API error.
pcercuei 0:03b5121a232e 6374 */
pcercuei 0:03b5121a232e 6375 static int
pcercuei 0:03b5121a232e 6376 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 6377 xmlSchemaBasicItemPtr ownerItem,
pcercuei 0:03b5121a232e 6378 xmlNodePtr ownerElem,
pcercuei 0:03b5121a232e 6379 const char *name,
pcercuei 0:03b5121a232e 6380 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 6381 const xmlChar **value)
pcercuei 0:03b5121a232e 6382 {
pcercuei 0:03b5121a232e 6383 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 6384
pcercuei 0:03b5121a232e 6385 if ((ctxt == NULL) || (type == NULL)) {
pcercuei 0:03b5121a232e 6386 if (value != NULL)
pcercuei 0:03b5121a232e 6387 *value = NULL;
pcercuei 0:03b5121a232e 6388 return (-1);
pcercuei 0:03b5121a232e 6389 }
pcercuei 0:03b5121a232e 6390 if (type->type != XML_SCHEMA_TYPE_BASIC) {
pcercuei 0:03b5121a232e 6391 if (value != NULL)
pcercuei 0:03b5121a232e 6392 *value = NULL;
pcercuei 0:03b5121a232e 6393 xmlSchemaPErr(ctxt, ownerElem,
pcercuei 0:03b5121a232e 6394 XML_SCHEMAP_INTERNAL,
pcercuei 0:03b5121a232e 6395 "Internal error: xmlSchemaPValAttr, the given "
pcercuei 0:03b5121a232e 6396 "type '%s' is not a built-in type.\n",
pcercuei 0:03b5121a232e 6397 type->name, NULL);
pcercuei 0:03b5121a232e 6398 return (-1);
pcercuei 0:03b5121a232e 6399 }
pcercuei 0:03b5121a232e 6400 attr = xmlSchemaGetPropNode(ownerElem, name);
pcercuei 0:03b5121a232e 6401 if (attr == NULL) {
pcercuei 0:03b5121a232e 6402 if (value != NULL)
pcercuei 0:03b5121a232e 6403 *value = NULL;
pcercuei 0:03b5121a232e 6404 return (0);
pcercuei 0:03b5121a232e 6405 }
pcercuei 0:03b5121a232e 6406 return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
pcercuei 0:03b5121a232e 6407 type, value));
pcercuei 0:03b5121a232e 6408 }
pcercuei 0:03b5121a232e 6409
pcercuei 0:03b5121a232e 6410 static int
pcercuei 0:03b5121a232e 6411 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 6412 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 6413 xmlNodePtr node,
pcercuei 0:03b5121a232e 6414 xmlAttrPtr attr,
pcercuei 0:03b5121a232e 6415 const xmlChar *namespaceName)
pcercuei 0:03b5121a232e 6416 {
pcercuei 0:03b5121a232e 6417 /* TODO: Pointer comparison instead? */
pcercuei 0:03b5121a232e 6418 if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
pcercuei 0:03b5121a232e 6419 return (0);
pcercuei 0:03b5121a232e 6420 if (xmlStrEqual(xmlSchemaNs, namespaceName))
pcercuei 0:03b5121a232e 6421 return (0);
pcercuei 0:03b5121a232e 6422 /*
pcercuei 0:03b5121a232e 6423 * Check if the referenced namespace was <import>ed.
pcercuei 0:03b5121a232e 6424 */
pcercuei 0:03b5121a232e 6425 if (WXS_BUCKET(pctxt)->relations != NULL) {
pcercuei 0:03b5121a232e 6426 xmlSchemaSchemaRelationPtr rel;
pcercuei 0:03b5121a232e 6427
pcercuei 0:03b5121a232e 6428 rel = WXS_BUCKET(pctxt)->relations;
pcercuei 0:03b5121a232e 6429 do {
pcercuei 0:03b5121a232e 6430 if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
pcercuei 0:03b5121a232e 6431 xmlStrEqual(namespaceName, rel->importNamespace))
pcercuei 0:03b5121a232e 6432 return (0);
pcercuei 0:03b5121a232e 6433 rel = rel->next;
pcercuei 0:03b5121a232e 6434 } while (rel != NULL);
pcercuei 0:03b5121a232e 6435 }
pcercuei 0:03b5121a232e 6436 /*
pcercuei 0:03b5121a232e 6437 * No matching <import>ed namespace found.
pcercuei 0:03b5121a232e 6438 */
pcercuei 0:03b5121a232e 6439 {
pcercuei 0:03b5121a232e 6440 xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
pcercuei 0:03b5121a232e 6441
pcercuei 0:03b5121a232e 6442 if (namespaceName == NULL)
pcercuei 0:03b5121a232e 6443 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 6444 XML_SCHEMAP_SRC_RESOLVE, n, NULL,
pcercuei 0:03b5121a232e 6445 "References from this schema to components in no "
pcercuei 0:03b5121a232e 6446 "namespace are not allowed, since not indicated by an "
pcercuei 0:03b5121a232e 6447 "import statement", NULL, NULL);
pcercuei 0:03b5121a232e 6448 else
pcercuei 0:03b5121a232e 6449 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 6450 XML_SCHEMAP_SRC_RESOLVE, n, NULL,
pcercuei 0:03b5121a232e 6451 "References from this schema to components in the "
pcercuei 0:03b5121a232e 6452 "namespace '%s' are not allowed, since not indicated by an "
pcercuei 0:03b5121a232e 6453 "import statement", namespaceName, NULL);
pcercuei 0:03b5121a232e 6454 }
pcercuei 0:03b5121a232e 6455 return (XML_SCHEMAP_SRC_RESOLVE);
pcercuei 0:03b5121a232e 6456 }
pcercuei 0:03b5121a232e 6457
pcercuei 0:03b5121a232e 6458 /**
pcercuei 0:03b5121a232e 6459 * xmlSchemaParseLocalAttributes:
pcercuei 0:03b5121a232e 6460 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 6461 * @schema: the schema being built
pcercuei 0:03b5121a232e 6462 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 6463 * @type: the hosting type where the attributes will be anchored
pcercuei 0:03b5121a232e 6464 *
pcercuei 0:03b5121a232e 6465 * Parses attribute uses and attribute declarations and
pcercuei 0:03b5121a232e 6466 * attribute group references.
pcercuei 0:03b5121a232e 6467 */
pcercuei 0:03b5121a232e 6468 static int
pcercuei 0:03b5121a232e 6469 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 6470 xmlNodePtr *child, xmlSchemaItemListPtr *list,
pcercuei 0:03b5121a232e 6471 int parentType, int *hasRefs)
pcercuei 0:03b5121a232e 6472 {
pcercuei 0:03b5121a232e 6473 void *item;
pcercuei 0:03b5121a232e 6474
pcercuei 0:03b5121a232e 6475 while ((IS_SCHEMA((*child), "attribute")) ||
pcercuei 0:03b5121a232e 6476 (IS_SCHEMA((*child), "attributeGroup"))) {
pcercuei 0:03b5121a232e 6477 if (IS_SCHEMA((*child), "attribute")) {
pcercuei 0:03b5121a232e 6478 item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
pcercuei 0:03b5121a232e 6479 *list, parentType);
pcercuei 0:03b5121a232e 6480 } else {
pcercuei 0:03b5121a232e 6481 item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
pcercuei 0:03b5121a232e 6482 if ((item != NULL) && (hasRefs != NULL))
pcercuei 0:03b5121a232e 6483 *hasRefs = 1;
pcercuei 0:03b5121a232e 6484 }
pcercuei 0:03b5121a232e 6485 if (item != NULL) {
pcercuei 0:03b5121a232e 6486 if (*list == NULL) {
pcercuei 0:03b5121a232e 6487 /* TODO: Customize grow factor. */
pcercuei 0:03b5121a232e 6488 *list = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 6489 if (*list == NULL)
pcercuei 0:03b5121a232e 6490 return(-1);
pcercuei 0:03b5121a232e 6491 }
pcercuei 0:03b5121a232e 6492 if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
pcercuei 0:03b5121a232e 6493 return(-1);
pcercuei 0:03b5121a232e 6494 }
pcercuei 0:03b5121a232e 6495 *child = (*child)->next;
pcercuei 0:03b5121a232e 6496 }
pcercuei 0:03b5121a232e 6497 return (0);
pcercuei 0:03b5121a232e 6498 }
pcercuei 0:03b5121a232e 6499
pcercuei 0:03b5121a232e 6500 /**
pcercuei 0:03b5121a232e 6501 * xmlSchemaParseAnnotation:
pcercuei 0:03b5121a232e 6502 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 6503 * @schema: the schema being built
pcercuei 0:03b5121a232e 6504 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 6505 *
pcercuei 0:03b5121a232e 6506 * parse a XML schema Attrribute declaration
pcercuei 0:03b5121a232e 6507 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 6508 *
pcercuei 0:03b5121a232e 6509 * Returns -1 in case of error, 0 if the declaration is improper and
pcercuei 0:03b5121a232e 6510 * 1 in case of success.
pcercuei 0:03b5121a232e 6511 */
pcercuei 0:03b5121a232e 6512 static xmlSchemaAnnotPtr
pcercuei 0:03b5121a232e 6513 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
pcercuei 0:03b5121a232e 6514 {
pcercuei 0:03b5121a232e 6515 xmlSchemaAnnotPtr ret;
pcercuei 0:03b5121a232e 6516 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 6517 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 6518 int barked = 0;
pcercuei 0:03b5121a232e 6519
pcercuei 0:03b5121a232e 6520 /*
pcercuei 0:03b5121a232e 6521 * INFO: S4S completed.
pcercuei 0:03b5121a232e 6522 */
pcercuei 0:03b5121a232e 6523 /*
pcercuei 0:03b5121a232e 6524 * id = ID
pcercuei 0:03b5121a232e 6525 * {any attributes with non-schema namespace . . .}>
pcercuei 0:03b5121a232e 6526 * Content: (appinfo | documentation)*
pcercuei 0:03b5121a232e 6527 */
pcercuei 0:03b5121a232e 6528 if ((ctxt == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 6529 return (NULL);
pcercuei 0:03b5121a232e 6530 if (needed)
pcercuei 0:03b5121a232e 6531 ret = xmlSchemaNewAnnot(ctxt, node);
pcercuei 0:03b5121a232e 6532 else
pcercuei 0:03b5121a232e 6533 ret = NULL;
pcercuei 0:03b5121a232e 6534 attr = node->properties;
pcercuei 0:03b5121a232e 6535 while (attr != NULL) {
pcercuei 0:03b5121a232e 6536 if (((attr->ns == NULL) &&
pcercuei 0:03b5121a232e 6537 (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
pcercuei 0:03b5121a232e 6538 ((attr->ns != NULL) &&
pcercuei 0:03b5121a232e 6539 xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
pcercuei 0:03b5121a232e 6540
pcercuei 0:03b5121a232e 6541 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 6542 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 6543 }
pcercuei 0:03b5121a232e 6544 attr = attr->next;
pcercuei 0:03b5121a232e 6545 }
pcercuei 0:03b5121a232e 6546 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 6547 /*
pcercuei 0:03b5121a232e 6548 * And now for the children...
pcercuei 0:03b5121a232e 6549 */
pcercuei 0:03b5121a232e 6550 child = node->children;
pcercuei 0:03b5121a232e 6551 while (child != NULL) {
pcercuei 0:03b5121a232e 6552 if (IS_SCHEMA(child, "appinfo")) {
pcercuei 0:03b5121a232e 6553 /* TODO: make available the content of "appinfo". */
pcercuei 0:03b5121a232e 6554 /*
pcercuei 0:03b5121a232e 6555 * source = anyURI
pcercuei 0:03b5121a232e 6556 * {any attributes with non-schema namespace . . .}>
pcercuei 0:03b5121a232e 6557 * Content: ({any})*
pcercuei 0:03b5121a232e 6558 */
pcercuei 0:03b5121a232e 6559 attr = child->properties;
pcercuei 0:03b5121a232e 6560 while (attr != NULL) {
pcercuei 0:03b5121a232e 6561 if (((attr->ns == NULL) &&
pcercuei 0:03b5121a232e 6562 (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
pcercuei 0:03b5121a232e 6563 ((attr->ns != NULL) &&
pcercuei 0:03b5121a232e 6564 xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
pcercuei 0:03b5121a232e 6565
pcercuei 0:03b5121a232e 6566 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 6567 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 6568 }
pcercuei 0:03b5121a232e 6569 attr = attr->next;
pcercuei 0:03b5121a232e 6570 }
pcercuei 0:03b5121a232e 6571 xmlSchemaPValAttr(ctxt, NULL, child, "source",
pcercuei 0:03b5121a232e 6572 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
pcercuei 0:03b5121a232e 6573 child = child->next;
pcercuei 0:03b5121a232e 6574 } else if (IS_SCHEMA(child, "documentation")) {
pcercuei 0:03b5121a232e 6575 /* TODO: make available the content of "documentation". */
pcercuei 0:03b5121a232e 6576 /*
pcercuei 0:03b5121a232e 6577 * source = anyURI
pcercuei 0:03b5121a232e 6578 * {any attributes with non-schema namespace . . .}>
pcercuei 0:03b5121a232e 6579 * Content: ({any})*
pcercuei 0:03b5121a232e 6580 */
pcercuei 0:03b5121a232e 6581 attr = child->properties;
pcercuei 0:03b5121a232e 6582 while (attr != NULL) {
pcercuei 0:03b5121a232e 6583 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 6584 if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
pcercuei 0:03b5121a232e 6585 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 6586 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 6587 }
pcercuei 0:03b5121a232e 6588 } else {
pcercuei 0:03b5121a232e 6589 if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
pcercuei 0:03b5121a232e 6590 (xmlStrEqual(attr->name, BAD_CAST "lang") &&
pcercuei 0:03b5121a232e 6591 (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
pcercuei 0:03b5121a232e 6592
pcercuei 0:03b5121a232e 6593 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 6594 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 6595 }
pcercuei 0:03b5121a232e 6596 }
pcercuei 0:03b5121a232e 6597 attr = attr->next;
pcercuei 0:03b5121a232e 6598 }
pcercuei 0:03b5121a232e 6599 /*
pcercuei 0:03b5121a232e 6600 * Attribute "xml:lang".
pcercuei 0:03b5121a232e 6601 */
pcercuei 0:03b5121a232e 6602 attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
pcercuei 0:03b5121a232e 6603 if (attr != NULL)
pcercuei 0:03b5121a232e 6604 xmlSchemaPValAttrNode(ctxt, NULL, attr,
pcercuei 0:03b5121a232e 6605 xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
pcercuei 0:03b5121a232e 6606 child = child->next;
pcercuei 0:03b5121a232e 6607 } else {
pcercuei 0:03b5121a232e 6608 if (!barked)
pcercuei 0:03b5121a232e 6609 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 6610 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 6611 NULL, node, child, NULL, "(appinfo | documentation)*");
pcercuei 0:03b5121a232e 6612 barked = 1;
pcercuei 0:03b5121a232e 6613 child = child->next;
pcercuei 0:03b5121a232e 6614 }
pcercuei 0:03b5121a232e 6615 }
pcercuei 0:03b5121a232e 6616
pcercuei 0:03b5121a232e 6617 return (ret);
pcercuei 0:03b5121a232e 6618 }
pcercuei 0:03b5121a232e 6619
pcercuei 0:03b5121a232e 6620 /**
pcercuei 0:03b5121a232e 6621 * xmlSchemaParseFacet:
pcercuei 0:03b5121a232e 6622 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 6623 * @schema: the schema being built
pcercuei 0:03b5121a232e 6624 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 6625 *
pcercuei 0:03b5121a232e 6626 * parse a XML schema Facet declaration
pcercuei 0:03b5121a232e 6627 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 6628 *
pcercuei 0:03b5121a232e 6629 * Returns the new type structure or NULL in case of error
pcercuei 0:03b5121a232e 6630 */
pcercuei 0:03b5121a232e 6631 static xmlSchemaFacetPtr
pcercuei 0:03b5121a232e 6632 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 6633 xmlNodePtr node)
pcercuei 0:03b5121a232e 6634 {
pcercuei 0:03b5121a232e 6635 xmlSchemaFacetPtr facet;
pcercuei 0:03b5121a232e 6636 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 6637 const xmlChar *value;
pcercuei 0:03b5121a232e 6638
pcercuei 0:03b5121a232e 6639 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 6640 return (NULL);
pcercuei 0:03b5121a232e 6641
pcercuei 0:03b5121a232e 6642 facet = xmlSchemaNewFacet();
pcercuei 0:03b5121a232e 6643 if (facet == NULL) {
pcercuei 0:03b5121a232e 6644 xmlSchemaPErrMemory(ctxt, "allocating facet", node);
pcercuei 0:03b5121a232e 6645 return (NULL);
pcercuei 0:03b5121a232e 6646 }
pcercuei 0:03b5121a232e 6647 facet->node = node;
pcercuei 0:03b5121a232e 6648 value = xmlSchemaGetProp(ctxt, node, "value");
pcercuei 0:03b5121a232e 6649 if (value == NULL) {
pcercuei 0:03b5121a232e 6650 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
pcercuei 0:03b5121a232e 6651 "Facet %s has no value\n", node->name, NULL);
pcercuei 0:03b5121a232e 6652 xmlSchemaFreeFacet(facet);
pcercuei 0:03b5121a232e 6653 return (NULL);
pcercuei 0:03b5121a232e 6654 }
pcercuei 0:03b5121a232e 6655 if (IS_SCHEMA(node, "minInclusive")) {
pcercuei 0:03b5121a232e 6656 facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
pcercuei 0:03b5121a232e 6657 } else if (IS_SCHEMA(node, "minExclusive")) {
pcercuei 0:03b5121a232e 6658 facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
pcercuei 0:03b5121a232e 6659 } else if (IS_SCHEMA(node, "maxInclusive")) {
pcercuei 0:03b5121a232e 6660 facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
pcercuei 0:03b5121a232e 6661 } else if (IS_SCHEMA(node, "maxExclusive")) {
pcercuei 0:03b5121a232e 6662 facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
pcercuei 0:03b5121a232e 6663 } else if (IS_SCHEMA(node, "totalDigits")) {
pcercuei 0:03b5121a232e 6664 facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
pcercuei 0:03b5121a232e 6665 } else if (IS_SCHEMA(node, "fractionDigits")) {
pcercuei 0:03b5121a232e 6666 facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
pcercuei 0:03b5121a232e 6667 } else if (IS_SCHEMA(node, "pattern")) {
pcercuei 0:03b5121a232e 6668 facet->type = XML_SCHEMA_FACET_PATTERN;
pcercuei 0:03b5121a232e 6669 } else if (IS_SCHEMA(node, "enumeration")) {
pcercuei 0:03b5121a232e 6670 facet->type = XML_SCHEMA_FACET_ENUMERATION;
pcercuei 0:03b5121a232e 6671 } else if (IS_SCHEMA(node, "whiteSpace")) {
pcercuei 0:03b5121a232e 6672 facet->type = XML_SCHEMA_FACET_WHITESPACE;
pcercuei 0:03b5121a232e 6673 } else if (IS_SCHEMA(node, "length")) {
pcercuei 0:03b5121a232e 6674 facet->type = XML_SCHEMA_FACET_LENGTH;
pcercuei 0:03b5121a232e 6675 } else if (IS_SCHEMA(node, "maxLength")) {
pcercuei 0:03b5121a232e 6676 facet->type = XML_SCHEMA_FACET_MAXLENGTH;
pcercuei 0:03b5121a232e 6677 } else if (IS_SCHEMA(node, "minLength")) {
pcercuei 0:03b5121a232e 6678 facet->type = XML_SCHEMA_FACET_MINLENGTH;
pcercuei 0:03b5121a232e 6679 } else {
pcercuei 0:03b5121a232e 6680 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
pcercuei 0:03b5121a232e 6681 "Unknown facet type %s\n", node->name, NULL);
pcercuei 0:03b5121a232e 6682 xmlSchemaFreeFacet(facet);
pcercuei 0:03b5121a232e 6683 return (NULL);
pcercuei 0:03b5121a232e 6684 }
pcercuei 0:03b5121a232e 6685 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 6686 facet->value = value;
pcercuei 0:03b5121a232e 6687 if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
pcercuei 0:03b5121a232e 6688 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
pcercuei 0:03b5121a232e 6689 const xmlChar *fixed;
pcercuei 0:03b5121a232e 6690
pcercuei 0:03b5121a232e 6691 fixed = xmlSchemaGetProp(ctxt, node, "fixed");
pcercuei 0:03b5121a232e 6692 if (fixed != NULL) {
pcercuei 0:03b5121a232e 6693 if (xmlStrEqual(fixed, BAD_CAST "true"))
pcercuei 0:03b5121a232e 6694 facet->fixed = 1;
pcercuei 0:03b5121a232e 6695 }
pcercuei 0:03b5121a232e 6696 }
pcercuei 0:03b5121a232e 6697 child = node->children;
pcercuei 0:03b5121a232e 6698
pcercuei 0:03b5121a232e 6699 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 6700 facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
pcercuei 0:03b5121a232e 6701 child = child->next;
pcercuei 0:03b5121a232e 6702 }
pcercuei 0:03b5121a232e 6703 if (child != NULL) {
pcercuei 0:03b5121a232e 6704 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
pcercuei 0:03b5121a232e 6705 "Facet %s has unexpected child content\n",
pcercuei 0:03b5121a232e 6706 node->name, NULL);
pcercuei 0:03b5121a232e 6707 }
pcercuei 0:03b5121a232e 6708 return (facet);
pcercuei 0:03b5121a232e 6709 }
pcercuei 0:03b5121a232e 6710
pcercuei 0:03b5121a232e 6711 /**
pcercuei 0:03b5121a232e 6712 * xmlSchemaParseWildcardNs:
pcercuei 0:03b5121a232e 6713 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 6714 * @wildc: the wildcard, already created
pcercuei 0:03b5121a232e 6715 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 6716 *
pcercuei 0:03b5121a232e 6717 * Parses the attribute "processContents" and "namespace"
pcercuei 0:03b5121a232e 6718 * of a xsd:anyAttribute and xsd:any.
pcercuei 0:03b5121a232e 6719 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 6720 *
pcercuei 0:03b5121a232e 6721 * Returns 0 if everything goes fine, a positive error code
pcercuei 0:03b5121a232e 6722 * if something is not valid and -1 if an internal error occurs.
pcercuei 0:03b5121a232e 6723 */
pcercuei 0:03b5121a232e 6724 static int
pcercuei 0:03b5121a232e 6725 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 6726 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 6727 xmlSchemaWildcardPtr wildc,
pcercuei 0:03b5121a232e 6728 xmlNodePtr node)
pcercuei 0:03b5121a232e 6729 {
pcercuei 0:03b5121a232e 6730 const xmlChar *pc, *ns, *dictnsItem;
pcercuei 0:03b5121a232e 6731 int ret = 0;
pcercuei 0:03b5121a232e 6732 xmlChar *nsItem;
pcercuei 0:03b5121a232e 6733 xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
pcercuei 0:03b5121a232e 6734 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 6735
pcercuei 0:03b5121a232e 6736 pc = xmlSchemaGetProp(ctxt, node, "processContents");
pcercuei 0:03b5121a232e 6737 if ((pc == NULL)
pcercuei 0:03b5121a232e 6738 || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
pcercuei 0:03b5121a232e 6739 wildc->processContents = XML_SCHEMAS_ANY_STRICT;
pcercuei 0:03b5121a232e 6740 } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
pcercuei 0:03b5121a232e 6741 wildc->processContents = XML_SCHEMAS_ANY_SKIP;
pcercuei 0:03b5121a232e 6742 } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
pcercuei 0:03b5121a232e 6743 wildc->processContents = XML_SCHEMAS_ANY_LAX;
pcercuei 0:03b5121a232e 6744 } else {
pcercuei 0:03b5121a232e 6745 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 6746 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 6747 NULL, node,
pcercuei 0:03b5121a232e 6748 NULL, "(strict | skip | lax)", pc,
pcercuei 0:03b5121a232e 6749 NULL, NULL, NULL);
pcercuei 0:03b5121a232e 6750 wildc->processContents = XML_SCHEMAS_ANY_STRICT;
pcercuei 0:03b5121a232e 6751 ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
pcercuei 0:03b5121a232e 6752 }
pcercuei 0:03b5121a232e 6753 /*
pcercuei 0:03b5121a232e 6754 * Build the namespace constraints.
pcercuei 0:03b5121a232e 6755 */
pcercuei 0:03b5121a232e 6756 attr = xmlSchemaGetPropNode(node, "namespace");
pcercuei 0:03b5121a232e 6757 ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 6758 if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
pcercuei 0:03b5121a232e 6759 wildc->any = 1;
pcercuei 0:03b5121a232e 6760 else if (xmlStrEqual(ns, BAD_CAST "##other")) {
pcercuei 0:03b5121a232e 6761 wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
pcercuei 0:03b5121a232e 6762 if (wildc->negNsSet == NULL) {
pcercuei 0:03b5121a232e 6763 return (-1);
pcercuei 0:03b5121a232e 6764 }
pcercuei 0:03b5121a232e 6765 wildc->negNsSet->value = ctxt->targetNamespace;
pcercuei 0:03b5121a232e 6766 } else {
pcercuei 0:03b5121a232e 6767 const xmlChar *end, *cur;
pcercuei 0:03b5121a232e 6768
pcercuei 0:03b5121a232e 6769 cur = ns;
pcercuei 0:03b5121a232e 6770 do {
pcercuei 0:03b5121a232e 6771 while (IS_BLANK_CH(*cur))
pcercuei 0:03b5121a232e 6772 cur++;
pcercuei 0:03b5121a232e 6773 end = cur;
pcercuei 0:03b5121a232e 6774 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
pcercuei 0:03b5121a232e 6775 end++;
pcercuei 0:03b5121a232e 6776 if (end == cur)
pcercuei 0:03b5121a232e 6777 break;
pcercuei 0:03b5121a232e 6778 nsItem = xmlStrndup(cur, end - cur);
pcercuei 0:03b5121a232e 6779 if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
pcercuei 0:03b5121a232e 6780 (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
pcercuei 0:03b5121a232e 6781 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 6782 XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
pcercuei 0:03b5121a232e 6783 NULL, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 6784 NULL,
pcercuei 0:03b5121a232e 6785 "((##any | ##other) | List of (xs:anyURI | "
pcercuei 0:03b5121a232e 6786 "(##targetNamespace | ##local)))",
pcercuei 0:03b5121a232e 6787 nsItem, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 6788 ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
pcercuei 0:03b5121a232e 6789 } else {
pcercuei 0:03b5121a232e 6790 if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
pcercuei 0:03b5121a232e 6791 dictnsItem = ctxt->targetNamespace;
pcercuei 0:03b5121a232e 6792 } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
pcercuei 0:03b5121a232e 6793 dictnsItem = NULL;
pcercuei 0:03b5121a232e 6794 } else {
pcercuei 0:03b5121a232e 6795 /*
pcercuei 0:03b5121a232e 6796 * Validate the item (anyURI).
pcercuei 0:03b5121a232e 6797 */
pcercuei 0:03b5121a232e 6798 xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
pcercuei 0:03b5121a232e 6799 nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
pcercuei 0:03b5121a232e 6800 dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
pcercuei 0:03b5121a232e 6801 }
pcercuei 0:03b5121a232e 6802 /*
pcercuei 0:03b5121a232e 6803 * Avoid dublicate namespaces.
pcercuei 0:03b5121a232e 6804 */
pcercuei 0:03b5121a232e 6805 tmp = wildc->nsSet;
pcercuei 0:03b5121a232e 6806 while (tmp != NULL) {
pcercuei 0:03b5121a232e 6807 if (dictnsItem == tmp->value)
pcercuei 0:03b5121a232e 6808 break;
pcercuei 0:03b5121a232e 6809 tmp = tmp->next;
pcercuei 0:03b5121a232e 6810 }
pcercuei 0:03b5121a232e 6811 if (tmp == NULL) {
pcercuei 0:03b5121a232e 6812 tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
pcercuei 0:03b5121a232e 6813 if (tmp == NULL) {
pcercuei 0:03b5121a232e 6814 xmlFree(nsItem);
pcercuei 0:03b5121a232e 6815 return (-1);
pcercuei 0:03b5121a232e 6816 }
pcercuei 0:03b5121a232e 6817 tmp->value = dictnsItem;
pcercuei 0:03b5121a232e 6818 tmp->next = NULL;
pcercuei 0:03b5121a232e 6819 if (wildc->nsSet == NULL)
pcercuei 0:03b5121a232e 6820 wildc->nsSet = tmp;
pcercuei 0:03b5121a232e 6821 else if (lastNs != NULL)
pcercuei 0:03b5121a232e 6822 lastNs->next = tmp;
pcercuei 0:03b5121a232e 6823 lastNs = tmp;
pcercuei 0:03b5121a232e 6824 }
pcercuei 0:03b5121a232e 6825
pcercuei 0:03b5121a232e 6826 }
pcercuei 0:03b5121a232e 6827 xmlFree(nsItem);
pcercuei 0:03b5121a232e 6828 cur = end;
pcercuei 0:03b5121a232e 6829 } while (*cur != 0);
pcercuei 0:03b5121a232e 6830 }
pcercuei 0:03b5121a232e 6831 return (ret);
pcercuei 0:03b5121a232e 6832 }
pcercuei 0:03b5121a232e 6833
pcercuei 0:03b5121a232e 6834 static int
pcercuei 0:03b5121a232e 6835 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 6836 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 6837 xmlNodePtr node,
pcercuei 0:03b5121a232e 6838 int minOccurs,
pcercuei 0:03b5121a232e 6839 int maxOccurs) {
pcercuei 0:03b5121a232e 6840
pcercuei 0:03b5121a232e 6841 if ((maxOccurs == 0) && ( minOccurs == 0))
pcercuei 0:03b5121a232e 6842 return (0);
pcercuei 0:03b5121a232e 6843 if (maxOccurs != UNBOUNDED) {
pcercuei 0:03b5121a232e 6844 /*
pcercuei 0:03b5121a232e 6845 * TODO: Maybe we should better not create the particle,
pcercuei 0:03b5121a232e 6846 * if min/max is invalid, since it could confuse the build of the
pcercuei 0:03b5121a232e 6847 * content model.
pcercuei 0:03b5121a232e 6848 */
pcercuei 0:03b5121a232e 6849 /*
pcercuei 0:03b5121a232e 6850 * 3.9.6 Schema Component Constraint: Particle Correct
pcercuei 0:03b5121a232e 6851 *
pcercuei 0:03b5121a232e 6852 */
pcercuei 0:03b5121a232e 6853 if (maxOccurs < 1) {
pcercuei 0:03b5121a232e 6854 /*
pcercuei 0:03b5121a232e 6855 * 2.2 {max occurs} must be greater than or equal to 1.
pcercuei 0:03b5121a232e 6856 */
pcercuei 0:03b5121a232e 6857 xmlSchemaPCustomAttrErr(ctxt,
pcercuei 0:03b5121a232e 6858 XML_SCHEMAP_P_PROPS_CORRECT_2_2,
pcercuei 0:03b5121a232e 6859 NULL, NULL,
pcercuei 0:03b5121a232e 6860 xmlSchemaGetPropNode(node, "maxOccurs"),
pcercuei 0:03b5121a232e 6861 "The value must be greater than or equal to 1");
pcercuei 0:03b5121a232e 6862 return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
pcercuei 0:03b5121a232e 6863 } else if (minOccurs > maxOccurs) {
pcercuei 0:03b5121a232e 6864 /*
pcercuei 0:03b5121a232e 6865 * 2.1 {min occurs} must not be greater than {max occurs}.
pcercuei 0:03b5121a232e 6866 */
pcercuei 0:03b5121a232e 6867 xmlSchemaPCustomAttrErr(ctxt,
pcercuei 0:03b5121a232e 6868 XML_SCHEMAP_P_PROPS_CORRECT_2_1,
pcercuei 0:03b5121a232e 6869 NULL, NULL,
pcercuei 0:03b5121a232e 6870 xmlSchemaGetPropNode(node, "minOccurs"),
pcercuei 0:03b5121a232e 6871 "The value must not be greater than the value of 'maxOccurs'");
pcercuei 0:03b5121a232e 6872 return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
pcercuei 0:03b5121a232e 6873 }
pcercuei 0:03b5121a232e 6874 }
pcercuei 0:03b5121a232e 6875 return (0);
pcercuei 0:03b5121a232e 6876 }
pcercuei 0:03b5121a232e 6877
pcercuei 0:03b5121a232e 6878 /**
pcercuei 0:03b5121a232e 6879 * xmlSchemaParseAny:
pcercuei 0:03b5121a232e 6880 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 6881 * @schema: the schema being built
pcercuei 0:03b5121a232e 6882 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 6883 *
pcercuei 0:03b5121a232e 6884 * Parsea a XML schema <any> element. A particle and wildcard
pcercuei 0:03b5121a232e 6885 * will be created (except if minOccurs==maxOccurs==0, in this case
pcercuei 0:03b5121a232e 6886 * nothing will be created).
pcercuei 0:03b5121a232e 6887 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 6888 *
pcercuei 0:03b5121a232e 6889 * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
pcercuei 0:03b5121a232e 6890 */
pcercuei 0:03b5121a232e 6891 static xmlSchemaParticlePtr
pcercuei 0:03b5121a232e 6892 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 6893 xmlNodePtr node)
pcercuei 0:03b5121a232e 6894 {
pcercuei 0:03b5121a232e 6895 xmlSchemaParticlePtr particle;
pcercuei 0:03b5121a232e 6896 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 6897 xmlSchemaWildcardPtr wild;
pcercuei 0:03b5121a232e 6898 int min, max;
pcercuei 0:03b5121a232e 6899 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 6900 xmlSchemaAnnotPtr annot = NULL;
pcercuei 0:03b5121a232e 6901
pcercuei 0:03b5121a232e 6902 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 6903 return (NULL);
pcercuei 0:03b5121a232e 6904 /*
pcercuei 0:03b5121a232e 6905 * Check for illegal attributes.
pcercuei 0:03b5121a232e 6906 */
pcercuei 0:03b5121a232e 6907 attr = node->properties;
pcercuei 0:03b5121a232e 6908 while (attr != NULL) {
pcercuei 0:03b5121a232e 6909 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 6910 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 6911 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
pcercuei 0:03b5121a232e 6912 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
pcercuei 0:03b5121a232e 6913 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
pcercuei 0:03b5121a232e 6914 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
pcercuei 0:03b5121a232e 6915 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 6916 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 6917 }
pcercuei 0:03b5121a232e 6918 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 6919 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 6920 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 6921 }
pcercuei 0:03b5121a232e 6922 attr = attr->next;
pcercuei 0:03b5121a232e 6923 }
pcercuei 0:03b5121a232e 6924 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 6925 /*
pcercuei 0:03b5121a232e 6926 * minOccurs/maxOccurs.
pcercuei 0:03b5121a232e 6927 */
pcercuei 0:03b5121a232e 6928 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
pcercuei 0:03b5121a232e 6929 "(xs:nonNegativeInteger | unbounded)");
pcercuei 0:03b5121a232e 6930 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
pcercuei 0:03b5121a232e 6931 "xs:nonNegativeInteger");
pcercuei 0:03b5121a232e 6932 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
pcercuei 0:03b5121a232e 6933 /*
pcercuei 0:03b5121a232e 6934 * Create & parse the wildcard.
pcercuei 0:03b5121a232e 6935 */
pcercuei 0:03b5121a232e 6936 wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
pcercuei 0:03b5121a232e 6937 if (wild == NULL)
pcercuei 0:03b5121a232e 6938 return (NULL);
pcercuei 0:03b5121a232e 6939 xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
pcercuei 0:03b5121a232e 6940 /*
pcercuei 0:03b5121a232e 6941 * And now for the children...
pcercuei 0:03b5121a232e 6942 */
pcercuei 0:03b5121a232e 6943 child = node->children;
pcercuei 0:03b5121a232e 6944 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 6945 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
pcercuei 0:03b5121a232e 6946 child = child->next;
pcercuei 0:03b5121a232e 6947 }
pcercuei 0:03b5121a232e 6948 if (child != NULL) {
pcercuei 0:03b5121a232e 6949 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 6950 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 6951 NULL, node, child,
pcercuei 0:03b5121a232e 6952 NULL, "(annotation?)");
pcercuei 0:03b5121a232e 6953 }
pcercuei 0:03b5121a232e 6954 /*
pcercuei 0:03b5121a232e 6955 * No component if minOccurs==maxOccurs==0.
pcercuei 0:03b5121a232e 6956 */
pcercuei 0:03b5121a232e 6957 if ((min == 0) && (max == 0)) {
pcercuei 0:03b5121a232e 6958 /* Don't free the wildcard, since it's already on the list. */
pcercuei 0:03b5121a232e 6959 return (NULL);
pcercuei 0:03b5121a232e 6960 }
pcercuei 0:03b5121a232e 6961 /*
pcercuei 0:03b5121a232e 6962 * Create the particle.
pcercuei 0:03b5121a232e 6963 */
pcercuei 0:03b5121a232e 6964 particle = xmlSchemaAddParticle(ctxt, node, min, max);
pcercuei 0:03b5121a232e 6965 if (particle == NULL)
pcercuei 0:03b5121a232e 6966 return (NULL);
pcercuei 0:03b5121a232e 6967 particle->annot = annot;
pcercuei 0:03b5121a232e 6968 particle->children = (xmlSchemaTreeItemPtr) wild;
pcercuei 0:03b5121a232e 6969
pcercuei 0:03b5121a232e 6970 return (particle);
pcercuei 0:03b5121a232e 6971 }
pcercuei 0:03b5121a232e 6972
pcercuei 0:03b5121a232e 6973 /**
pcercuei 0:03b5121a232e 6974 * xmlSchemaParseNotation:
pcercuei 0:03b5121a232e 6975 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 6976 * @schema: the schema being built
pcercuei 0:03b5121a232e 6977 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 6978 *
pcercuei 0:03b5121a232e 6979 * parse a XML schema Notation declaration
pcercuei 0:03b5121a232e 6980 *
pcercuei 0:03b5121a232e 6981 * Returns the new structure or NULL in case of error
pcercuei 0:03b5121a232e 6982 */
pcercuei 0:03b5121a232e 6983 static xmlSchemaNotationPtr
pcercuei 0:03b5121a232e 6984 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 6985 xmlNodePtr node)
pcercuei 0:03b5121a232e 6986 {
pcercuei 0:03b5121a232e 6987 const xmlChar *name;
pcercuei 0:03b5121a232e 6988 xmlSchemaNotationPtr ret;
pcercuei 0:03b5121a232e 6989 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 6990
pcercuei 0:03b5121a232e 6991 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 6992 return (NULL);
pcercuei 0:03b5121a232e 6993 name = xmlSchemaGetProp(ctxt, node, "name");
pcercuei 0:03b5121a232e 6994 if (name == NULL) {
pcercuei 0:03b5121a232e 6995 xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
pcercuei 0:03b5121a232e 6996 "Notation has no name\n", NULL, NULL);
pcercuei 0:03b5121a232e 6997 return (NULL);
pcercuei 0:03b5121a232e 6998 }
pcercuei 0:03b5121a232e 6999 ret = xmlSchemaAddNotation(ctxt, schema, name,
pcercuei 0:03b5121a232e 7000 ctxt->targetNamespace, node);
pcercuei 0:03b5121a232e 7001 if (ret == NULL)
pcercuei 0:03b5121a232e 7002 return (NULL);
pcercuei 0:03b5121a232e 7003 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 7004
pcercuei 0:03b5121a232e 7005 child = node->children;
pcercuei 0:03b5121a232e 7006 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 7007 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
pcercuei 0:03b5121a232e 7008 child = child->next;
pcercuei 0:03b5121a232e 7009 }
pcercuei 0:03b5121a232e 7010 if (child != NULL) {
pcercuei 0:03b5121a232e 7011 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 7012 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 7013 NULL, node, child,
pcercuei 0:03b5121a232e 7014 NULL, "(annotation?)");
pcercuei 0:03b5121a232e 7015 }
pcercuei 0:03b5121a232e 7016
pcercuei 0:03b5121a232e 7017 return (ret);
pcercuei 0:03b5121a232e 7018 }
pcercuei 0:03b5121a232e 7019
pcercuei 0:03b5121a232e 7020 /**
pcercuei 0:03b5121a232e 7021 * xmlSchemaParseAnyAttribute:
pcercuei 0:03b5121a232e 7022 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 7023 * @schema: the schema being built
pcercuei 0:03b5121a232e 7024 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 7025 *
pcercuei 0:03b5121a232e 7026 * parse a XML schema AnyAttrribute declaration
pcercuei 0:03b5121a232e 7027 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 7028 *
pcercuei 0:03b5121a232e 7029 * Returns a wildcard or NULL.
pcercuei 0:03b5121a232e 7030 */
pcercuei 0:03b5121a232e 7031 static xmlSchemaWildcardPtr
pcercuei 0:03b5121a232e 7032 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 7033 xmlSchemaPtr schema, xmlNodePtr node)
pcercuei 0:03b5121a232e 7034 {
pcercuei 0:03b5121a232e 7035 xmlSchemaWildcardPtr ret;
pcercuei 0:03b5121a232e 7036 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 7037 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 7038
pcercuei 0:03b5121a232e 7039 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 7040 return (NULL);
pcercuei 0:03b5121a232e 7041
pcercuei 0:03b5121a232e 7042 ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
pcercuei 0:03b5121a232e 7043 node);
pcercuei 0:03b5121a232e 7044 if (ret == NULL) {
pcercuei 0:03b5121a232e 7045 return (NULL);
pcercuei 0:03b5121a232e 7046 }
pcercuei 0:03b5121a232e 7047 /*
pcercuei 0:03b5121a232e 7048 * Check for illegal attributes.
pcercuei 0:03b5121a232e 7049 */
pcercuei 0:03b5121a232e 7050 attr = node->properties;
pcercuei 0:03b5121a232e 7051 while (attr != NULL) {
pcercuei 0:03b5121a232e 7052 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 7053 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 7054 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
pcercuei 0:03b5121a232e 7055 (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
pcercuei 0:03b5121a232e 7056 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 7057 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 7058 }
pcercuei 0:03b5121a232e 7059 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 7060 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 7061 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 7062 }
pcercuei 0:03b5121a232e 7063 attr = attr->next;
pcercuei 0:03b5121a232e 7064 }
pcercuei 0:03b5121a232e 7065 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 7066 /*
pcercuei 0:03b5121a232e 7067 * Parse the namespace list.
pcercuei 0:03b5121a232e 7068 */
pcercuei 0:03b5121a232e 7069 if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
pcercuei 0:03b5121a232e 7070 return (NULL);
pcercuei 0:03b5121a232e 7071 /*
pcercuei 0:03b5121a232e 7072 * And now for the children...
pcercuei 0:03b5121a232e 7073 */
pcercuei 0:03b5121a232e 7074 child = node->children;
pcercuei 0:03b5121a232e 7075 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 7076 ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
pcercuei 0:03b5121a232e 7077 child = child->next;
pcercuei 0:03b5121a232e 7078 }
pcercuei 0:03b5121a232e 7079 if (child != NULL) {
pcercuei 0:03b5121a232e 7080 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 7081 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 7082 NULL, node, child,
pcercuei 0:03b5121a232e 7083 NULL, "(annotation?)");
pcercuei 0:03b5121a232e 7084 }
pcercuei 0:03b5121a232e 7085
pcercuei 0:03b5121a232e 7086 return (ret);
pcercuei 0:03b5121a232e 7087 }
pcercuei 0:03b5121a232e 7088
pcercuei 0:03b5121a232e 7089
pcercuei 0:03b5121a232e 7090 /**
pcercuei 0:03b5121a232e 7091 * xmlSchemaParseAttribute:
pcercuei 0:03b5121a232e 7092 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 7093 * @schema: the schema being built
pcercuei 0:03b5121a232e 7094 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 7095 *
pcercuei 0:03b5121a232e 7096 * parse a XML schema Attrribute declaration
pcercuei 0:03b5121a232e 7097 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 7098 *
pcercuei 0:03b5121a232e 7099 * Returns the attribute declaration.
pcercuei 0:03b5121a232e 7100 */
pcercuei 0:03b5121a232e 7101 static xmlSchemaBasicItemPtr
pcercuei 0:03b5121a232e 7102 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 7103 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 7104 xmlNodePtr node,
pcercuei 0:03b5121a232e 7105 xmlSchemaItemListPtr uses,
pcercuei 0:03b5121a232e 7106 int parentType)
pcercuei 0:03b5121a232e 7107 {
pcercuei 0:03b5121a232e 7108 const xmlChar *attrValue, *name = NULL, *ns = NULL;
pcercuei 0:03b5121a232e 7109 xmlSchemaAttributeUsePtr use = NULL;
pcercuei 0:03b5121a232e 7110 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 7111 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 7112 const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
pcercuei 0:03b5121a232e 7113 int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
pcercuei 0:03b5121a232e 7114 int nberrors, hasForm = 0, defValueType = 0;
pcercuei 0:03b5121a232e 7115
pcercuei 0:03b5121a232e 7116 #define WXS_ATTR_DEF_VAL_DEFAULT 1
pcercuei 0:03b5121a232e 7117 #define WXS_ATTR_DEF_VAL_FIXED 2
pcercuei 0:03b5121a232e 7118
pcercuei 0:03b5121a232e 7119 /*
pcercuei 0:03b5121a232e 7120 * 3.2.3 Constraints on XML Representations of Attribute Declarations
pcercuei 0:03b5121a232e 7121 */
pcercuei 0:03b5121a232e 7122
pcercuei 0:03b5121a232e 7123 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 7124 return (NULL);
pcercuei 0:03b5121a232e 7125 attr = xmlSchemaGetPropNode(node, "ref");
pcercuei 0:03b5121a232e 7126 if (attr != NULL) {
pcercuei 0:03b5121a232e 7127 if (xmlSchemaPValAttrNodeQName(pctxt, schema,
pcercuei 0:03b5121a232e 7128 NULL, attr, &tmpNs, &tmpName) != 0) {
pcercuei 0:03b5121a232e 7129 return (NULL);
pcercuei 0:03b5121a232e 7130 }
pcercuei 0:03b5121a232e 7131 if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
pcercuei 0:03b5121a232e 7132 return(NULL);
pcercuei 0:03b5121a232e 7133 isRef = 1;
pcercuei 0:03b5121a232e 7134 }
pcercuei 0:03b5121a232e 7135 nberrors = pctxt->nberrors;
pcercuei 0:03b5121a232e 7136 /*
pcercuei 0:03b5121a232e 7137 * Check for illegal attributes.
pcercuei 0:03b5121a232e 7138 */
pcercuei 0:03b5121a232e 7139 attr = node->properties;
pcercuei 0:03b5121a232e 7140 while (attr != NULL) {
pcercuei 0:03b5121a232e 7141 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 7142 if (isRef) {
pcercuei 0:03b5121a232e 7143 if (xmlStrEqual(attr->name, BAD_CAST "id")) {
pcercuei 0:03b5121a232e 7144 xmlSchemaPValAttrNodeID(pctxt, attr);
pcercuei 0:03b5121a232e 7145 goto attr_next;
pcercuei 0:03b5121a232e 7146 } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
pcercuei 0:03b5121a232e 7147 goto attr_next;
pcercuei 0:03b5121a232e 7148 }
pcercuei 0:03b5121a232e 7149 } else {
pcercuei 0:03b5121a232e 7150 if (xmlStrEqual(attr->name, BAD_CAST "name")) {
pcercuei 0:03b5121a232e 7151 goto attr_next;
pcercuei 0:03b5121a232e 7152 } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
pcercuei 0:03b5121a232e 7153 xmlSchemaPValAttrNodeID(pctxt, attr);
pcercuei 0:03b5121a232e 7154 goto attr_next;
pcercuei 0:03b5121a232e 7155 } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
pcercuei 0:03b5121a232e 7156 xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
pcercuei 0:03b5121a232e 7157 attr, &tmpNs, &tmpName);
pcercuei 0:03b5121a232e 7158 goto attr_next;
pcercuei 0:03b5121a232e 7159 } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
pcercuei 0:03b5121a232e 7160 /*
pcercuei 0:03b5121a232e 7161 * Evaluate the target namespace
pcercuei 0:03b5121a232e 7162 */
pcercuei 0:03b5121a232e 7163 hasForm = 1;
pcercuei 0:03b5121a232e 7164 attrValue = xmlSchemaGetNodeContent(pctxt,
pcercuei 0:03b5121a232e 7165 (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 7166 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
pcercuei 0:03b5121a232e 7167 ns = pctxt->targetNamespace;
pcercuei 0:03b5121a232e 7168 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
pcercuei 0:03b5121a232e 7169 {
pcercuei 0:03b5121a232e 7170 xmlSchemaPSimpleTypeErr(pctxt,
pcercuei 0:03b5121a232e 7171 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 7172 NULL, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 7173 NULL, "(qualified | unqualified)",
pcercuei 0:03b5121a232e 7174 attrValue, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 7175 }
pcercuei 0:03b5121a232e 7176 goto attr_next;
pcercuei 0:03b5121a232e 7177 }
pcercuei 0:03b5121a232e 7178 }
pcercuei 0:03b5121a232e 7179 if (xmlStrEqual(attr->name, BAD_CAST "use")) {
pcercuei 0:03b5121a232e 7180
pcercuei 0:03b5121a232e 7181 attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 7182 /* TODO: Maybe we need to normalize the value beforehand. */
pcercuei 0:03b5121a232e 7183 if (xmlStrEqual(attrValue, BAD_CAST "optional"))
pcercuei 0:03b5121a232e 7184 occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
pcercuei 0:03b5121a232e 7185 else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
pcercuei 0:03b5121a232e 7186 occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
pcercuei 0:03b5121a232e 7187 else if (xmlStrEqual(attrValue, BAD_CAST "required"))
pcercuei 0:03b5121a232e 7188 occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
pcercuei 0:03b5121a232e 7189 else {
pcercuei 0:03b5121a232e 7190 xmlSchemaPSimpleTypeErr(pctxt,
pcercuei 0:03b5121a232e 7191 XML_SCHEMAP_INVALID_ATTR_USE,
pcercuei 0:03b5121a232e 7192 NULL, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 7193 NULL, "(optional | prohibited | required)",
pcercuei 0:03b5121a232e 7194 attrValue, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 7195 }
pcercuei 0:03b5121a232e 7196 goto attr_next;
pcercuei 0:03b5121a232e 7197 } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
pcercuei 0:03b5121a232e 7198 /*
pcercuei 0:03b5121a232e 7199 * 3.2.3 : 1
pcercuei 0:03b5121a232e 7200 * default and fixed must not both be present.
pcercuei 0:03b5121a232e 7201 */
pcercuei 0:03b5121a232e 7202 if (defValue) {
pcercuei 0:03b5121a232e 7203 xmlSchemaPMutualExclAttrErr(pctxt,
pcercuei 0:03b5121a232e 7204 XML_SCHEMAP_SRC_ATTRIBUTE_1,
pcercuei 0:03b5121a232e 7205 NULL, attr, "default", "fixed");
pcercuei 0:03b5121a232e 7206 } else {
pcercuei 0:03b5121a232e 7207 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 7208 defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
pcercuei 0:03b5121a232e 7209 }
pcercuei 0:03b5121a232e 7210 goto attr_next;
pcercuei 0:03b5121a232e 7211 } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
pcercuei 0:03b5121a232e 7212 /*
pcercuei 0:03b5121a232e 7213 * 3.2.3 : 1
pcercuei 0:03b5121a232e 7214 * default and fixed must not both be present.
pcercuei 0:03b5121a232e 7215 */
pcercuei 0:03b5121a232e 7216 if (defValue) {
pcercuei 0:03b5121a232e 7217 xmlSchemaPMutualExclAttrErr(pctxt,
pcercuei 0:03b5121a232e 7218 XML_SCHEMAP_SRC_ATTRIBUTE_1,
pcercuei 0:03b5121a232e 7219 NULL, attr, "default", "fixed");
pcercuei 0:03b5121a232e 7220 } else {
pcercuei 0:03b5121a232e 7221 defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 7222 defValueType = WXS_ATTR_DEF_VAL_FIXED;
pcercuei 0:03b5121a232e 7223 }
pcercuei 0:03b5121a232e 7224 goto attr_next;
pcercuei 0:03b5121a232e 7225 }
pcercuei 0:03b5121a232e 7226 } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
pcercuei 0:03b5121a232e 7227 goto attr_next;
pcercuei 0:03b5121a232e 7228
pcercuei 0:03b5121a232e 7229 xmlSchemaPIllegalAttrErr(pctxt,
pcercuei 0:03b5121a232e 7230 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 7231
pcercuei 0:03b5121a232e 7232 attr_next:
pcercuei 0:03b5121a232e 7233 attr = attr->next;
pcercuei 0:03b5121a232e 7234 }
pcercuei 0:03b5121a232e 7235 /*
pcercuei 0:03b5121a232e 7236 * 3.2.3 : 2
pcercuei 0:03b5121a232e 7237 * If default and use are both present, use must have
pcercuei 0:03b5121a232e 7238 * the actual value optional.
pcercuei 0:03b5121a232e 7239 */
pcercuei 0:03b5121a232e 7240 if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
pcercuei 0:03b5121a232e 7241 (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
pcercuei 0:03b5121a232e 7242 xmlSchemaPSimpleTypeErr(pctxt,
pcercuei 0:03b5121a232e 7243 XML_SCHEMAP_SRC_ATTRIBUTE_2,
pcercuei 0:03b5121a232e 7244 NULL, node, NULL,
pcercuei 0:03b5121a232e 7245 "(optional | prohibited | required)", NULL,
pcercuei 0:03b5121a232e 7246 "The value of the attribute 'use' must be 'optional' "
pcercuei 0:03b5121a232e 7247 "if the attribute 'default' is present",
pcercuei 0:03b5121a232e 7248 NULL, NULL);
pcercuei 0:03b5121a232e 7249 }
pcercuei 0:03b5121a232e 7250 /*
pcercuei 0:03b5121a232e 7251 * We want correct attributes.
pcercuei 0:03b5121a232e 7252 */
pcercuei 0:03b5121a232e 7253 if (nberrors != pctxt->nberrors)
pcercuei 0:03b5121a232e 7254 return(NULL);
pcercuei 0:03b5121a232e 7255 if (! isRef) {
pcercuei 0:03b5121a232e 7256 xmlSchemaAttributePtr attrDecl;
pcercuei 0:03b5121a232e 7257
pcercuei 0:03b5121a232e 7258 /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
pcercuei 0:03b5121a232e 7259 if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
pcercuei 0:03b5121a232e 7260 ns = pctxt->targetNamespace;
pcercuei 0:03b5121a232e 7261 /*
pcercuei 0:03b5121a232e 7262 * 3.2.6 Schema Component Constraint: xsi: Not Allowed
pcercuei 0:03b5121a232e 7263 * TODO: Move this to the component layer.
pcercuei 0:03b5121a232e 7264 */
pcercuei 0:03b5121a232e 7265 if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
pcercuei 0:03b5121a232e 7266 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 7267 XML_SCHEMAP_NO_XSI,
pcercuei 0:03b5121a232e 7268 node, NULL,
pcercuei 0:03b5121a232e 7269 "The target namespace must not match '%s'",
pcercuei 0:03b5121a232e 7270 xmlSchemaInstanceNs, NULL);
pcercuei 0:03b5121a232e 7271 }
pcercuei 0:03b5121a232e 7272 attr = xmlSchemaGetPropNode(node, "name");
pcercuei 0:03b5121a232e 7273 if (attr == NULL) {
pcercuei 0:03b5121a232e 7274 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 7275 NULL, node, "name", NULL);
pcercuei 0:03b5121a232e 7276 return (NULL);
pcercuei 0:03b5121a232e 7277 }
pcercuei 0:03b5121a232e 7278 if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
pcercuei 0:03b5121a232e 7279 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
pcercuei 0:03b5121a232e 7280 return (NULL);
pcercuei 0:03b5121a232e 7281 }
pcercuei 0:03b5121a232e 7282 /*
pcercuei 0:03b5121a232e 7283 * 3.2.6 Schema Component Constraint: xmlns Not Allowed
pcercuei 0:03b5121a232e 7284 * TODO: Move this to the component layer.
pcercuei 0:03b5121a232e 7285 */
pcercuei 0:03b5121a232e 7286 if (xmlStrEqual(name, BAD_CAST "xmlns")) {
pcercuei 0:03b5121a232e 7287 xmlSchemaPSimpleTypeErr(pctxt,
pcercuei 0:03b5121a232e 7288 XML_SCHEMAP_NO_XMLNS,
pcercuei 0:03b5121a232e 7289 NULL, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 7290 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
pcercuei 0:03b5121a232e 7291 "The value of the attribute must not match 'xmlns'",
pcercuei 0:03b5121a232e 7292 NULL, NULL);
pcercuei 0:03b5121a232e 7293 return (NULL);
pcercuei 0:03b5121a232e 7294 }
pcercuei 0:03b5121a232e 7295 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
pcercuei 0:03b5121a232e 7296 goto check_children;
pcercuei 0:03b5121a232e 7297 /*
pcercuei 0:03b5121a232e 7298 * Create the attribute use component.
pcercuei 0:03b5121a232e 7299 */
pcercuei 0:03b5121a232e 7300 use = xmlSchemaAddAttributeUse(pctxt, node);
pcercuei 0:03b5121a232e 7301 if (use == NULL)
pcercuei 0:03b5121a232e 7302 return(NULL);
pcercuei 0:03b5121a232e 7303 use->occurs = occurs;
pcercuei 0:03b5121a232e 7304 /*
pcercuei 0:03b5121a232e 7305 * Create the attribute declaration.
pcercuei 0:03b5121a232e 7306 */
pcercuei 0:03b5121a232e 7307 attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
pcercuei 0:03b5121a232e 7308 if (attrDecl == NULL)
pcercuei 0:03b5121a232e 7309 return (NULL);
pcercuei 0:03b5121a232e 7310 if (tmpName != NULL) {
pcercuei 0:03b5121a232e 7311 attrDecl->typeName = tmpName;
pcercuei 0:03b5121a232e 7312 attrDecl->typeNs = tmpNs;
pcercuei 0:03b5121a232e 7313 }
pcercuei 0:03b5121a232e 7314 use->attrDecl = attrDecl;
pcercuei 0:03b5121a232e 7315 /*
pcercuei 0:03b5121a232e 7316 * Value constraint.
pcercuei 0:03b5121a232e 7317 */
pcercuei 0:03b5121a232e 7318 if (defValue != NULL) {
pcercuei 0:03b5121a232e 7319 attrDecl->defValue = defValue;
pcercuei 0:03b5121a232e 7320 if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
pcercuei 0:03b5121a232e 7321 attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
pcercuei 0:03b5121a232e 7322 }
pcercuei 0:03b5121a232e 7323 } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
pcercuei 0:03b5121a232e 7324 xmlSchemaQNameRefPtr ref;
pcercuei 0:03b5121a232e 7325
pcercuei 0:03b5121a232e 7326 /*
pcercuei 0:03b5121a232e 7327 * Create the attribute use component.
pcercuei 0:03b5121a232e 7328 */
pcercuei 0:03b5121a232e 7329 use = xmlSchemaAddAttributeUse(pctxt, node);
pcercuei 0:03b5121a232e 7330 if (use == NULL)
pcercuei 0:03b5121a232e 7331 return(NULL);
pcercuei 0:03b5121a232e 7332 /*
pcercuei 0:03b5121a232e 7333 * We need to resolve the reference at later stage.
pcercuei 0:03b5121a232e 7334 */
pcercuei 0:03b5121a232e 7335 WXS_ADD_PENDING(pctxt, use);
pcercuei 0:03b5121a232e 7336 use->occurs = occurs;
pcercuei 0:03b5121a232e 7337 /*
pcercuei 0:03b5121a232e 7338 * Create a QName reference to the attribute declaration.
pcercuei 0:03b5121a232e 7339 */
pcercuei 0:03b5121a232e 7340 ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
pcercuei 0:03b5121a232e 7341 tmpName, tmpNs);
pcercuei 0:03b5121a232e 7342 if (ref == NULL)
pcercuei 0:03b5121a232e 7343 return(NULL);
pcercuei 0:03b5121a232e 7344 /*
pcercuei 0:03b5121a232e 7345 * Assign the reference. This will be substituted for the
pcercuei 0:03b5121a232e 7346 * referenced attribute declaration when the QName is resolved.
pcercuei 0:03b5121a232e 7347 */
pcercuei 0:03b5121a232e 7348 use->attrDecl = WXS_ATTR_CAST ref;
pcercuei 0:03b5121a232e 7349 /*
pcercuei 0:03b5121a232e 7350 * Value constraint.
pcercuei 0:03b5121a232e 7351 */
pcercuei 0:03b5121a232e 7352 if (defValue != NULL)
pcercuei 0:03b5121a232e 7353 use->defValue = defValue;
pcercuei 0:03b5121a232e 7354 if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
pcercuei 0:03b5121a232e 7355 use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
pcercuei 0:03b5121a232e 7356 }
pcercuei 0:03b5121a232e 7357
pcercuei 0:03b5121a232e 7358 check_children:
pcercuei 0:03b5121a232e 7359 /*
pcercuei 0:03b5121a232e 7360 * And now for the children...
pcercuei 0:03b5121a232e 7361 */
pcercuei 0:03b5121a232e 7362 child = node->children;
pcercuei 0:03b5121a232e 7363 if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
pcercuei 0:03b5121a232e 7364 xmlSchemaAttributeUseProhibPtr prohib;
pcercuei 0:03b5121a232e 7365
pcercuei 0:03b5121a232e 7366 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 7367 xmlSchemaParseAnnotation(pctxt, child, 0);
pcercuei 0:03b5121a232e 7368 child = child->next;
pcercuei 0:03b5121a232e 7369 }
pcercuei 0:03b5121a232e 7370 if (child != NULL) {
pcercuei 0:03b5121a232e 7371 xmlSchemaPContentErr(pctxt,
pcercuei 0:03b5121a232e 7372 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 7373 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 7374 "(annotation?)");
pcercuei 0:03b5121a232e 7375 }
pcercuei 0:03b5121a232e 7376 /*
pcercuei 0:03b5121a232e 7377 * Check for pointlessness of attribute prohibitions.
pcercuei 0:03b5121a232e 7378 */
pcercuei 0:03b5121a232e 7379 if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
pcercuei 0:03b5121a232e 7380 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 7381 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
pcercuei 0:03b5121a232e 7382 node, NULL,
pcercuei 0:03b5121a232e 7383 "Skipping attribute use prohibition, since it is "
pcercuei 0:03b5121a232e 7384 "pointless inside an <attributeGroup>",
pcercuei 0:03b5121a232e 7385 NULL, NULL, NULL);
pcercuei 0:03b5121a232e 7386 return(NULL);
pcercuei 0:03b5121a232e 7387 } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
pcercuei 0:03b5121a232e 7388 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 7389 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
pcercuei 0:03b5121a232e 7390 node, NULL,
pcercuei 0:03b5121a232e 7391 "Skipping attribute use prohibition, since it is "
pcercuei 0:03b5121a232e 7392 "pointless when extending a type",
pcercuei 0:03b5121a232e 7393 NULL, NULL, NULL);
pcercuei 0:03b5121a232e 7394 return(NULL);
pcercuei 0:03b5121a232e 7395 }
pcercuei 0:03b5121a232e 7396 if (! isRef) {
pcercuei 0:03b5121a232e 7397 tmpName = name;
pcercuei 0:03b5121a232e 7398 tmpNs = ns;
pcercuei 0:03b5121a232e 7399 }
pcercuei 0:03b5121a232e 7400 /*
pcercuei 0:03b5121a232e 7401 * Check for duplicate attribute prohibitions.
pcercuei 0:03b5121a232e 7402 */
pcercuei 0:03b5121a232e 7403 if (uses) {
pcercuei 0:03b5121a232e 7404 int i;
pcercuei 0:03b5121a232e 7405
pcercuei 0:03b5121a232e 7406 for (i = 0; i < uses->nbItems; i++) {
pcercuei 0:03b5121a232e 7407 use = uses->items[i];
pcercuei 0:03b5121a232e 7408 if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
pcercuei 0:03b5121a232e 7409 (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
pcercuei 0:03b5121a232e 7410 (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
pcercuei 0:03b5121a232e 7411 {
pcercuei 0:03b5121a232e 7412 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 7413
pcercuei 0:03b5121a232e 7414 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 7415 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
pcercuei 0:03b5121a232e 7416 node, NULL,
pcercuei 0:03b5121a232e 7417 "Skipping duplicate attribute use prohibition '%s'",
pcercuei 0:03b5121a232e 7418 xmlSchemaFormatQName(&str, tmpNs, tmpName),
pcercuei 0:03b5121a232e 7419 NULL, NULL);
pcercuei 0:03b5121a232e 7420 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 7421 return(NULL);
pcercuei 0:03b5121a232e 7422 }
pcercuei 0:03b5121a232e 7423 }
pcercuei 0:03b5121a232e 7424 }
pcercuei 0:03b5121a232e 7425 /*
pcercuei 0:03b5121a232e 7426 * Create the attribute prohibition helper component.
pcercuei 0:03b5121a232e 7427 */
pcercuei 0:03b5121a232e 7428 prohib = xmlSchemaAddAttributeUseProhib(pctxt);
pcercuei 0:03b5121a232e 7429 if (prohib == NULL)
pcercuei 0:03b5121a232e 7430 return(NULL);
pcercuei 0:03b5121a232e 7431 prohib->node = node;
pcercuei 0:03b5121a232e 7432 prohib->name = tmpName;
pcercuei 0:03b5121a232e 7433 prohib->targetNamespace = tmpNs;
pcercuei 0:03b5121a232e 7434 if (isRef) {
pcercuei 0:03b5121a232e 7435 /*
pcercuei 0:03b5121a232e 7436 * We need at least to resolve to the attribute declaration.
pcercuei 0:03b5121a232e 7437 */
pcercuei 0:03b5121a232e 7438 WXS_ADD_PENDING(pctxt, prohib);
pcercuei 0:03b5121a232e 7439 }
pcercuei 0:03b5121a232e 7440 return(WXS_BASIC_CAST prohib);
pcercuei 0:03b5121a232e 7441 } else {
pcercuei 0:03b5121a232e 7442 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 7443 /*
pcercuei 0:03b5121a232e 7444 * TODO: Should this go into the attr decl?
pcercuei 0:03b5121a232e 7445 */
pcercuei 0:03b5121a232e 7446 use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
pcercuei 0:03b5121a232e 7447 child = child->next;
pcercuei 0:03b5121a232e 7448 }
pcercuei 0:03b5121a232e 7449 if (isRef) {
pcercuei 0:03b5121a232e 7450 if (child != NULL) {
pcercuei 0:03b5121a232e 7451 if (IS_SCHEMA(child, "simpleType"))
pcercuei 0:03b5121a232e 7452 /*
pcercuei 0:03b5121a232e 7453 * 3.2.3 : 3.2
pcercuei 0:03b5121a232e 7454 * If ref is present, then all of <simpleType>,
pcercuei 0:03b5121a232e 7455 * form and type must be absent.
pcercuei 0:03b5121a232e 7456 */
pcercuei 0:03b5121a232e 7457 xmlSchemaPContentErr(pctxt,
pcercuei 0:03b5121a232e 7458 XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
pcercuei 0:03b5121a232e 7459 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 7460 "(annotation?)");
pcercuei 0:03b5121a232e 7461 else
pcercuei 0:03b5121a232e 7462 xmlSchemaPContentErr(pctxt,
pcercuei 0:03b5121a232e 7463 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 7464 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 7465 "(annotation?)");
pcercuei 0:03b5121a232e 7466 }
pcercuei 0:03b5121a232e 7467 } else {
pcercuei 0:03b5121a232e 7468 if (IS_SCHEMA(child, "simpleType")) {
pcercuei 0:03b5121a232e 7469 if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
pcercuei 0:03b5121a232e 7470 /*
pcercuei 0:03b5121a232e 7471 * 3.2.3 : 4
pcercuei 0:03b5121a232e 7472 * type and <simpleType> must not both be present.
pcercuei 0:03b5121a232e 7473 */
pcercuei 0:03b5121a232e 7474 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
pcercuei 0:03b5121a232e 7475 NULL, node, child,
pcercuei 0:03b5121a232e 7476 "The attribute 'type' and the <simpleType> child "
pcercuei 0:03b5121a232e 7477 "are mutually exclusive", NULL);
pcercuei 0:03b5121a232e 7478 } else
pcercuei 0:03b5121a232e 7479 WXS_ATTRUSE_TYPEDEF(use) =
pcercuei 0:03b5121a232e 7480 xmlSchemaParseSimpleType(pctxt, schema, child, 0);
pcercuei 0:03b5121a232e 7481 child = child->next;
pcercuei 0:03b5121a232e 7482 }
pcercuei 0:03b5121a232e 7483 if (child != NULL)
pcercuei 0:03b5121a232e 7484 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 7485 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 7486 "(annotation?, simpleType?)");
pcercuei 0:03b5121a232e 7487 }
pcercuei 0:03b5121a232e 7488 }
pcercuei 0:03b5121a232e 7489 return (WXS_BASIC_CAST use);
pcercuei 0:03b5121a232e 7490 }
pcercuei 0:03b5121a232e 7491
pcercuei 0:03b5121a232e 7492
pcercuei 0:03b5121a232e 7493 static xmlSchemaAttributePtr
pcercuei 0:03b5121a232e 7494 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 7495 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 7496 xmlNodePtr node)
pcercuei 0:03b5121a232e 7497 {
pcercuei 0:03b5121a232e 7498 const xmlChar *attrValue;
pcercuei 0:03b5121a232e 7499 xmlSchemaAttributePtr ret;
pcercuei 0:03b5121a232e 7500 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 7501 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 7502
pcercuei 0:03b5121a232e 7503 /*
pcercuei 0:03b5121a232e 7504 * Note that the w3c spec assumes the schema to be validated with schema
pcercuei 0:03b5121a232e 7505 * for schemas beforehand.
pcercuei 0:03b5121a232e 7506 *
pcercuei 0:03b5121a232e 7507 * 3.2.3 Constraints on XML Representations of Attribute Declarations
pcercuei 0:03b5121a232e 7508 */
pcercuei 0:03b5121a232e 7509 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 7510 return (NULL);
pcercuei 0:03b5121a232e 7511 /*
pcercuei 0:03b5121a232e 7512 * 3.2.3 : 3.1
pcercuei 0:03b5121a232e 7513 * One of ref or name must be present, but not both
pcercuei 0:03b5121a232e 7514 */
pcercuei 0:03b5121a232e 7515 attr = xmlSchemaGetPropNode(node, "name");
pcercuei 0:03b5121a232e 7516 if (attr == NULL) {
pcercuei 0:03b5121a232e 7517 xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 7518 NULL, node, "name", NULL);
pcercuei 0:03b5121a232e 7519 return (NULL);
pcercuei 0:03b5121a232e 7520 }
pcercuei 0:03b5121a232e 7521 if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
pcercuei 0:03b5121a232e 7522 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
pcercuei 0:03b5121a232e 7523 return (NULL);
pcercuei 0:03b5121a232e 7524 }
pcercuei 0:03b5121a232e 7525 /*
pcercuei 0:03b5121a232e 7526 * 3.2.6 Schema Component Constraint: xmlns Not Allowed
pcercuei 0:03b5121a232e 7527 * TODO: Move this to the component layer.
pcercuei 0:03b5121a232e 7528 */
pcercuei 0:03b5121a232e 7529 if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
pcercuei 0:03b5121a232e 7530 xmlSchemaPSimpleTypeErr(pctxt,
pcercuei 0:03b5121a232e 7531 XML_SCHEMAP_NO_XMLNS,
pcercuei 0:03b5121a232e 7532 NULL, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 7533 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
pcercuei 0:03b5121a232e 7534 "The value of the attribute must not match 'xmlns'",
pcercuei 0:03b5121a232e 7535 NULL, NULL);
pcercuei 0:03b5121a232e 7536 return (NULL);
pcercuei 0:03b5121a232e 7537 }
pcercuei 0:03b5121a232e 7538 /*
pcercuei 0:03b5121a232e 7539 * 3.2.6 Schema Component Constraint: xsi: Not Allowed
pcercuei 0:03b5121a232e 7540 * TODO: Move this to the component layer.
pcercuei 0:03b5121a232e 7541 * Or better leave it here and add it to the component layer
pcercuei 0:03b5121a232e 7542 * if we have a schema construction API.
pcercuei 0:03b5121a232e 7543 */
pcercuei 0:03b5121a232e 7544 if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
pcercuei 0:03b5121a232e 7545 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 7546 XML_SCHEMAP_NO_XSI, node, NULL,
pcercuei 0:03b5121a232e 7547 "The target namespace must not match '%s'",
pcercuei 0:03b5121a232e 7548 xmlSchemaInstanceNs, NULL);
pcercuei 0:03b5121a232e 7549 }
pcercuei 0:03b5121a232e 7550
pcercuei 0:03b5121a232e 7551 ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
pcercuei 0:03b5121a232e 7552 pctxt->targetNamespace, node, 1);
pcercuei 0:03b5121a232e 7553 if (ret == NULL)
pcercuei 0:03b5121a232e 7554 return (NULL);
pcercuei 0:03b5121a232e 7555 ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
pcercuei 0:03b5121a232e 7556
pcercuei 0:03b5121a232e 7557 /*
pcercuei 0:03b5121a232e 7558 * Check for illegal attributes.
pcercuei 0:03b5121a232e 7559 */
pcercuei 0:03b5121a232e 7560 attr = node->properties;
pcercuei 0:03b5121a232e 7561 while (attr != NULL) {
pcercuei 0:03b5121a232e 7562 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 7563 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 7564 (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
pcercuei 0:03b5121a232e 7565 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
pcercuei 0:03b5121a232e 7566 (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
pcercuei 0:03b5121a232e 7567 (!xmlStrEqual(attr->name, BAD_CAST "type")))
pcercuei 0:03b5121a232e 7568 {
pcercuei 0:03b5121a232e 7569 xmlSchemaPIllegalAttrErr(pctxt,
pcercuei 0:03b5121a232e 7570 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 7571 }
pcercuei 0:03b5121a232e 7572 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 7573 xmlSchemaPIllegalAttrErr(pctxt,
pcercuei 0:03b5121a232e 7574 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 7575 }
pcercuei 0:03b5121a232e 7576 attr = attr->next;
pcercuei 0:03b5121a232e 7577 }
pcercuei 0:03b5121a232e 7578 xmlSchemaPValAttrQName(pctxt, schema, NULL,
pcercuei 0:03b5121a232e 7579 node, "type", &ret->typeNs, &ret->typeName);
pcercuei 0:03b5121a232e 7580
pcercuei 0:03b5121a232e 7581 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 7582 /*
pcercuei 0:03b5121a232e 7583 * Attribute "fixed".
pcercuei 0:03b5121a232e 7584 */
pcercuei 0:03b5121a232e 7585 ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
pcercuei 0:03b5121a232e 7586 if (ret->defValue != NULL)
pcercuei 0:03b5121a232e 7587 ret->flags |= XML_SCHEMAS_ATTR_FIXED;
pcercuei 0:03b5121a232e 7588 /*
pcercuei 0:03b5121a232e 7589 * Attribute "default".
pcercuei 0:03b5121a232e 7590 */
pcercuei 0:03b5121a232e 7591 attr = xmlSchemaGetPropNode(node, "default");
pcercuei 0:03b5121a232e 7592 if (attr != NULL) {
pcercuei 0:03b5121a232e 7593 /*
pcercuei 0:03b5121a232e 7594 * 3.2.3 : 1
pcercuei 0:03b5121a232e 7595 * default and fixed must not both be present.
pcercuei 0:03b5121a232e 7596 */
pcercuei 0:03b5121a232e 7597 if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
pcercuei 0:03b5121a232e 7598 xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
pcercuei 0:03b5121a232e 7599 WXS_BASIC_CAST ret, attr, "default", "fixed");
pcercuei 0:03b5121a232e 7600 } else
pcercuei 0:03b5121a232e 7601 ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 7602 }
pcercuei 0:03b5121a232e 7603 /*
pcercuei 0:03b5121a232e 7604 * And now for the children...
pcercuei 0:03b5121a232e 7605 */
pcercuei 0:03b5121a232e 7606 child = node->children;
pcercuei 0:03b5121a232e 7607 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 7608 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
pcercuei 0:03b5121a232e 7609 child = child->next;
pcercuei 0:03b5121a232e 7610 }
pcercuei 0:03b5121a232e 7611 if (IS_SCHEMA(child, "simpleType")) {
pcercuei 0:03b5121a232e 7612 if (ret->typeName != NULL) {
pcercuei 0:03b5121a232e 7613 /*
pcercuei 0:03b5121a232e 7614 * 3.2.3 : 4
pcercuei 0:03b5121a232e 7615 * type and <simpleType> must not both be present.
pcercuei 0:03b5121a232e 7616 */
pcercuei 0:03b5121a232e 7617 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
pcercuei 0:03b5121a232e 7618 NULL, node, child,
pcercuei 0:03b5121a232e 7619 "The attribute 'type' and the <simpleType> child "
pcercuei 0:03b5121a232e 7620 "are mutually exclusive", NULL);
pcercuei 0:03b5121a232e 7621 } else
pcercuei 0:03b5121a232e 7622 ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
pcercuei 0:03b5121a232e 7623 child = child->next;
pcercuei 0:03b5121a232e 7624 }
pcercuei 0:03b5121a232e 7625 if (child != NULL)
pcercuei 0:03b5121a232e 7626 xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 7627 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 7628 "(annotation?, simpleType?)");
pcercuei 0:03b5121a232e 7629
pcercuei 0:03b5121a232e 7630 return (ret);
pcercuei 0:03b5121a232e 7631 }
pcercuei 0:03b5121a232e 7632
pcercuei 0:03b5121a232e 7633 /**
pcercuei 0:03b5121a232e 7634 * xmlSchemaParseAttributeGroupRef:
pcercuei 0:03b5121a232e 7635 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 7636 * @schema: the schema being built
pcercuei 0:03b5121a232e 7637 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 7638 *
pcercuei 0:03b5121a232e 7639 * Parse an attribute group definition reference.
pcercuei 0:03b5121a232e 7640 * Note that a reference to an attribute group does not
pcercuei 0:03b5121a232e 7641 * correspond to any component at all.
pcercuei 0:03b5121a232e 7642 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 7643 *
pcercuei 0:03b5121a232e 7644 * Returns the attribute group or NULL in case of error.
pcercuei 0:03b5121a232e 7645 */
pcercuei 0:03b5121a232e 7646 static xmlSchemaQNameRefPtr
pcercuei 0:03b5121a232e 7647 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 7648 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 7649 xmlNodePtr node)
pcercuei 0:03b5121a232e 7650 {
pcercuei 0:03b5121a232e 7651 xmlSchemaQNameRefPtr ret;
pcercuei 0:03b5121a232e 7652 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 7653 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 7654 const xmlChar *refNs = NULL, *ref = NULL;
pcercuei 0:03b5121a232e 7655
pcercuei 0:03b5121a232e 7656 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 7657 return (NULL);
pcercuei 0:03b5121a232e 7658
pcercuei 0:03b5121a232e 7659 attr = xmlSchemaGetPropNode(node, "ref");
pcercuei 0:03b5121a232e 7660 if (attr == NULL) {
pcercuei 0:03b5121a232e 7661 xmlSchemaPMissingAttrErr(pctxt,
pcercuei 0:03b5121a232e 7662 XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 7663 NULL, node, "ref", NULL);
pcercuei 0:03b5121a232e 7664 return (NULL);
pcercuei 0:03b5121a232e 7665 }
pcercuei 0:03b5121a232e 7666 xmlSchemaPValAttrNodeQName(pctxt, schema,
pcercuei 0:03b5121a232e 7667 NULL, attr, &refNs, &ref);
pcercuei 0:03b5121a232e 7668 if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
pcercuei 0:03b5121a232e 7669 return(NULL);
pcercuei 0:03b5121a232e 7670
pcercuei 0:03b5121a232e 7671 /*
pcercuei 0:03b5121a232e 7672 * Check for illegal attributes.
pcercuei 0:03b5121a232e 7673 */
pcercuei 0:03b5121a232e 7674 attr = node->properties;
pcercuei 0:03b5121a232e 7675 while (attr != NULL) {
pcercuei 0:03b5121a232e 7676 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 7677 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
pcercuei 0:03b5121a232e 7678 (!xmlStrEqual(attr->name, BAD_CAST "id")))
pcercuei 0:03b5121a232e 7679 {
pcercuei 0:03b5121a232e 7680 xmlSchemaPIllegalAttrErr(pctxt,
pcercuei 0:03b5121a232e 7681 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 7682 }
pcercuei 0:03b5121a232e 7683 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 7684 xmlSchemaPIllegalAttrErr(pctxt,
pcercuei 0:03b5121a232e 7685 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 7686 }
pcercuei 0:03b5121a232e 7687 attr = attr->next;
pcercuei 0:03b5121a232e 7688 }
pcercuei 0:03b5121a232e 7689 /* Attribute ID */
pcercuei 0:03b5121a232e 7690 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 7691
pcercuei 0:03b5121a232e 7692 /*
pcercuei 0:03b5121a232e 7693 * And now for the children...
pcercuei 0:03b5121a232e 7694 */
pcercuei 0:03b5121a232e 7695 child = node->children;
pcercuei 0:03b5121a232e 7696 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 7697 /*
pcercuei 0:03b5121a232e 7698 * TODO: We do not have a place to store the annotation, do we?
pcercuei 0:03b5121a232e 7699 */
pcercuei 0:03b5121a232e 7700 xmlSchemaParseAnnotation(pctxt, child, 0);
pcercuei 0:03b5121a232e 7701 child = child->next;
pcercuei 0:03b5121a232e 7702 }
pcercuei 0:03b5121a232e 7703 if (child != NULL) {
pcercuei 0:03b5121a232e 7704 xmlSchemaPContentErr(pctxt,
pcercuei 0:03b5121a232e 7705 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 7706 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 7707 "(annotation?)");
pcercuei 0:03b5121a232e 7708 }
pcercuei 0:03b5121a232e 7709
pcercuei 0:03b5121a232e 7710 /*
pcercuei 0:03b5121a232e 7711 * Handle attribute group redefinitions.
pcercuei 0:03b5121a232e 7712 */
pcercuei 0:03b5121a232e 7713 if (pctxt->isRedefine && pctxt->redef &&
pcercuei 0:03b5121a232e 7714 (pctxt->redef->item->type ==
pcercuei 0:03b5121a232e 7715 XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
pcercuei 0:03b5121a232e 7716 (ref == pctxt->redef->refName) &&
pcercuei 0:03b5121a232e 7717 (refNs == pctxt->redef->refTargetNs))
pcercuei 0:03b5121a232e 7718 {
pcercuei 0:03b5121a232e 7719 /*
pcercuei 0:03b5121a232e 7720 * SPEC src-redefine:
pcercuei 0:03b5121a232e 7721 * (7.1) "If it has an <attributeGroup> among its contents
pcercuei 0:03b5121a232e 7722 * the `actual value` of whose ref [attribute] is the same
pcercuei 0:03b5121a232e 7723 * as the `actual value` of its own name attribute plus
pcercuei 0:03b5121a232e 7724 * target namespace, then it must have exactly one such group."
pcercuei 0:03b5121a232e 7725 */
pcercuei 0:03b5121a232e 7726 if (pctxt->redefCounter != 0) {
pcercuei 0:03b5121a232e 7727 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 7728
pcercuei 0:03b5121a232e 7729 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 7730 XML_SCHEMAP_SRC_REDEFINE, node, NULL,
pcercuei 0:03b5121a232e 7731 "The redefining attribute group definition "
pcercuei 0:03b5121a232e 7732 "'%s' must not contain more than one "
pcercuei 0:03b5121a232e 7733 "reference to the redefined definition",
pcercuei 0:03b5121a232e 7734 xmlSchemaFormatQName(&str, refNs, ref), NULL);
pcercuei 0:03b5121a232e 7735 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 7736 return(NULL);
pcercuei 0:03b5121a232e 7737 }
pcercuei 0:03b5121a232e 7738 pctxt->redefCounter++;
pcercuei 0:03b5121a232e 7739 /*
pcercuei 0:03b5121a232e 7740 * URGENT TODO: How to ensure that the reference will not be
pcercuei 0:03b5121a232e 7741 * handled by the normal component resolution mechanism?
pcercuei 0:03b5121a232e 7742 */
pcercuei 0:03b5121a232e 7743 ret = xmlSchemaNewQNameRef(pctxt,
pcercuei 0:03b5121a232e 7744 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
pcercuei 0:03b5121a232e 7745 if (ret == NULL)
pcercuei 0:03b5121a232e 7746 return(NULL);
pcercuei 0:03b5121a232e 7747 ret->node = node;
pcercuei 0:03b5121a232e 7748 pctxt->redef->reference = WXS_BASIC_CAST ret;
pcercuei 0:03b5121a232e 7749 } else {
pcercuei 0:03b5121a232e 7750 /*
pcercuei 0:03b5121a232e 7751 * Create a QName-reference helper component. We will substitute this
pcercuei 0:03b5121a232e 7752 * component for the attribute uses of the referenced attribute group
pcercuei 0:03b5121a232e 7753 * definition.
pcercuei 0:03b5121a232e 7754 */
pcercuei 0:03b5121a232e 7755 ret = xmlSchemaNewQNameRef(pctxt,
pcercuei 0:03b5121a232e 7756 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
pcercuei 0:03b5121a232e 7757 if (ret == NULL)
pcercuei 0:03b5121a232e 7758 return(NULL);
pcercuei 0:03b5121a232e 7759 ret->node = node;
pcercuei 0:03b5121a232e 7760 /* Add to pending items, to be able to resolve the reference. */
pcercuei 0:03b5121a232e 7761 WXS_ADD_PENDING(pctxt, ret);
pcercuei 0:03b5121a232e 7762 }
pcercuei 0:03b5121a232e 7763 return (ret);
pcercuei 0:03b5121a232e 7764 }
pcercuei 0:03b5121a232e 7765
pcercuei 0:03b5121a232e 7766 /**
pcercuei 0:03b5121a232e 7767 * xmlSchemaParseAttributeGroupDefinition:
pcercuei 0:03b5121a232e 7768 * @pctxt: a schema validation context
pcercuei 0:03b5121a232e 7769 * @schema: the schema being built
pcercuei 0:03b5121a232e 7770 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 7771 *
pcercuei 0:03b5121a232e 7772 * parse a XML schema Attribute Group declaration
pcercuei 0:03b5121a232e 7773 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 7774 *
pcercuei 0:03b5121a232e 7775 * Returns the attribute group definition or NULL in case of error.
pcercuei 0:03b5121a232e 7776 */
pcercuei 0:03b5121a232e 7777 static xmlSchemaAttributeGroupPtr
pcercuei 0:03b5121a232e 7778 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 7779 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 7780 xmlNodePtr node)
pcercuei 0:03b5121a232e 7781 {
pcercuei 0:03b5121a232e 7782 const xmlChar *name;
pcercuei 0:03b5121a232e 7783 xmlSchemaAttributeGroupPtr ret;
pcercuei 0:03b5121a232e 7784 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 7785 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 7786 int hasRefs = 0;
pcercuei 0:03b5121a232e 7787
pcercuei 0:03b5121a232e 7788 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 7789 return (NULL);
pcercuei 0:03b5121a232e 7790
pcercuei 0:03b5121a232e 7791 attr = xmlSchemaGetPropNode(node, "name");
pcercuei 0:03b5121a232e 7792 if (attr == NULL) {
pcercuei 0:03b5121a232e 7793 xmlSchemaPMissingAttrErr(pctxt,
pcercuei 0:03b5121a232e 7794 XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 7795 NULL, node, "name", NULL);
pcercuei 0:03b5121a232e 7796 return (NULL);
pcercuei 0:03b5121a232e 7797 }
pcercuei 0:03b5121a232e 7798 /*
pcercuei 0:03b5121a232e 7799 * The name is crucial, exit if invalid.
pcercuei 0:03b5121a232e 7800 */
pcercuei 0:03b5121a232e 7801 if (xmlSchemaPValAttrNode(pctxt,
pcercuei 0:03b5121a232e 7802 NULL, attr,
pcercuei 0:03b5121a232e 7803 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
pcercuei 0:03b5121a232e 7804 return (NULL);
pcercuei 0:03b5121a232e 7805 }
pcercuei 0:03b5121a232e 7806 ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
pcercuei 0:03b5121a232e 7807 name, pctxt->targetNamespace, node);
pcercuei 0:03b5121a232e 7808 if (ret == NULL)
pcercuei 0:03b5121a232e 7809 return (NULL);
pcercuei 0:03b5121a232e 7810 /*
pcercuei 0:03b5121a232e 7811 * Check for illegal attributes.
pcercuei 0:03b5121a232e 7812 */
pcercuei 0:03b5121a232e 7813 attr = node->properties;
pcercuei 0:03b5121a232e 7814 while (attr != NULL) {
pcercuei 0:03b5121a232e 7815 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 7816 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
pcercuei 0:03b5121a232e 7817 (!xmlStrEqual(attr->name, BAD_CAST "id")))
pcercuei 0:03b5121a232e 7818 {
pcercuei 0:03b5121a232e 7819 xmlSchemaPIllegalAttrErr(pctxt,
pcercuei 0:03b5121a232e 7820 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 7821 }
pcercuei 0:03b5121a232e 7822 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 7823 xmlSchemaPIllegalAttrErr(pctxt,
pcercuei 0:03b5121a232e 7824 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 7825 }
pcercuei 0:03b5121a232e 7826 attr = attr->next;
pcercuei 0:03b5121a232e 7827 }
pcercuei 0:03b5121a232e 7828 /* Attribute ID */
pcercuei 0:03b5121a232e 7829 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 7830 /*
pcercuei 0:03b5121a232e 7831 * And now for the children...
pcercuei 0:03b5121a232e 7832 */
pcercuei 0:03b5121a232e 7833 child = node->children;
pcercuei 0:03b5121a232e 7834 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 7835 ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
pcercuei 0:03b5121a232e 7836 child = child->next;
pcercuei 0:03b5121a232e 7837 }
pcercuei 0:03b5121a232e 7838 /*
pcercuei 0:03b5121a232e 7839 * Parse contained attribute decls/refs.
pcercuei 0:03b5121a232e 7840 */
pcercuei 0:03b5121a232e 7841 if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
pcercuei 0:03b5121a232e 7842 (xmlSchemaItemListPtr *) &(ret->attrUses),
pcercuei 0:03b5121a232e 7843 XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
pcercuei 0:03b5121a232e 7844 return(NULL);
pcercuei 0:03b5121a232e 7845 if (hasRefs)
pcercuei 0:03b5121a232e 7846 ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
pcercuei 0:03b5121a232e 7847 /*
pcercuei 0:03b5121a232e 7848 * Parse the attribute wildcard.
pcercuei 0:03b5121a232e 7849 */
pcercuei 0:03b5121a232e 7850 if (IS_SCHEMA(child, "anyAttribute")) {
pcercuei 0:03b5121a232e 7851 ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
pcercuei 0:03b5121a232e 7852 schema, child);
pcercuei 0:03b5121a232e 7853 child = child->next;
pcercuei 0:03b5121a232e 7854 }
pcercuei 0:03b5121a232e 7855 if (child != NULL) {
pcercuei 0:03b5121a232e 7856 xmlSchemaPContentErr(pctxt,
pcercuei 0:03b5121a232e 7857 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 7858 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 7859 "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
pcercuei 0:03b5121a232e 7860 }
pcercuei 0:03b5121a232e 7861 return (ret);
pcercuei 0:03b5121a232e 7862 }
pcercuei 0:03b5121a232e 7863
pcercuei 0:03b5121a232e 7864 /**
pcercuei 0:03b5121a232e 7865 * xmlSchemaPValAttrFormDefault:
pcercuei 0:03b5121a232e 7866 * @value: the value
pcercuei 0:03b5121a232e 7867 * @flags: the flags to be modified
pcercuei 0:03b5121a232e 7868 * @flagQualified: the specific flag for "qualified"
pcercuei 0:03b5121a232e 7869 *
pcercuei 0:03b5121a232e 7870 * Returns 0 if the value is valid, 1 otherwise.
pcercuei 0:03b5121a232e 7871 */
pcercuei 0:03b5121a232e 7872 static int
pcercuei 0:03b5121a232e 7873 xmlSchemaPValAttrFormDefault(const xmlChar *value,
pcercuei 0:03b5121a232e 7874 int *flags,
pcercuei 0:03b5121a232e 7875 int flagQualified)
pcercuei 0:03b5121a232e 7876 {
pcercuei 0:03b5121a232e 7877 if (xmlStrEqual(value, BAD_CAST "qualified")) {
pcercuei 0:03b5121a232e 7878 if ((*flags & flagQualified) == 0)
pcercuei 0:03b5121a232e 7879 *flags |= flagQualified;
pcercuei 0:03b5121a232e 7880 } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
pcercuei 0:03b5121a232e 7881 return (1);
pcercuei 0:03b5121a232e 7882
pcercuei 0:03b5121a232e 7883 return (0);
pcercuei 0:03b5121a232e 7884 }
pcercuei 0:03b5121a232e 7885
pcercuei 0:03b5121a232e 7886 /**
pcercuei 0:03b5121a232e 7887 * xmlSchemaPValAttrBlockFinal:
pcercuei 0:03b5121a232e 7888 * @value: the value
pcercuei 0:03b5121a232e 7889 * @flags: the flags to be modified
pcercuei 0:03b5121a232e 7890 * @flagAll: the specific flag for "#all"
pcercuei 0:03b5121a232e 7891 * @flagExtension: the specific flag for "extension"
pcercuei 0:03b5121a232e 7892 * @flagRestriction: the specific flag for "restriction"
pcercuei 0:03b5121a232e 7893 * @flagSubstitution: the specific flag for "substitution"
pcercuei 0:03b5121a232e 7894 * @flagList: the specific flag for "list"
pcercuei 0:03b5121a232e 7895 * @flagUnion: the specific flag for "union"
pcercuei 0:03b5121a232e 7896 *
pcercuei 0:03b5121a232e 7897 * Validates the value of the attribute "final" and "block". The value
pcercuei 0:03b5121a232e 7898 * is converted into the specified flag values and returned in @flags.
pcercuei 0:03b5121a232e 7899 *
pcercuei 0:03b5121a232e 7900 * Returns 0 if the value is valid, 1 otherwise.
pcercuei 0:03b5121a232e 7901 */
pcercuei 0:03b5121a232e 7902
pcercuei 0:03b5121a232e 7903 static int
pcercuei 0:03b5121a232e 7904 xmlSchemaPValAttrBlockFinal(const xmlChar *value,
pcercuei 0:03b5121a232e 7905 int *flags,
pcercuei 0:03b5121a232e 7906 int flagAll,
pcercuei 0:03b5121a232e 7907 int flagExtension,
pcercuei 0:03b5121a232e 7908 int flagRestriction,
pcercuei 0:03b5121a232e 7909 int flagSubstitution,
pcercuei 0:03b5121a232e 7910 int flagList,
pcercuei 0:03b5121a232e 7911 int flagUnion)
pcercuei 0:03b5121a232e 7912 {
pcercuei 0:03b5121a232e 7913 int ret = 0;
pcercuei 0:03b5121a232e 7914
pcercuei 0:03b5121a232e 7915 /*
pcercuei 0:03b5121a232e 7916 * TODO: This does not check for dublicate entries.
pcercuei 0:03b5121a232e 7917 */
pcercuei 0:03b5121a232e 7918 if ((flags == NULL) || (value == NULL))
pcercuei 0:03b5121a232e 7919 return (-1);
pcercuei 0:03b5121a232e 7920 if (value[0] == 0)
pcercuei 0:03b5121a232e 7921 return (0);
pcercuei 0:03b5121a232e 7922 if (xmlStrEqual(value, BAD_CAST "#all")) {
pcercuei 0:03b5121a232e 7923 if (flagAll != -1)
pcercuei 0:03b5121a232e 7924 *flags |= flagAll;
pcercuei 0:03b5121a232e 7925 else {
pcercuei 0:03b5121a232e 7926 if (flagExtension != -1)
pcercuei 0:03b5121a232e 7927 *flags |= flagExtension;
pcercuei 0:03b5121a232e 7928 if (flagRestriction != -1)
pcercuei 0:03b5121a232e 7929 *flags |= flagRestriction;
pcercuei 0:03b5121a232e 7930 if (flagSubstitution != -1)
pcercuei 0:03b5121a232e 7931 *flags |= flagSubstitution;
pcercuei 0:03b5121a232e 7932 if (flagList != -1)
pcercuei 0:03b5121a232e 7933 *flags |= flagList;
pcercuei 0:03b5121a232e 7934 if (flagUnion != -1)
pcercuei 0:03b5121a232e 7935 *flags |= flagUnion;
pcercuei 0:03b5121a232e 7936 }
pcercuei 0:03b5121a232e 7937 } else {
pcercuei 0:03b5121a232e 7938 const xmlChar *end, *cur = value;
pcercuei 0:03b5121a232e 7939 xmlChar *item;
pcercuei 0:03b5121a232e 7940
pcercuei 0:03b5121a232e 7941 do {
pcercuei 0:03b5121a232e 7942 while (IS_BLANK_CH(*cur))
pcercuei 0:03b5121a232e 7943 cur++;
pcercuei 0:03b5121a232e 7944 end = cur;
pcercuei 0:03b5121a232e 7945 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
pcercuei 0:03b5121a232e 7946 end++;
pcercuei 0:03b5121a232e 7947 if (end == cur)
pcercuei 0:03b5121a232e 7948 break;
pcercuei 0:03b5121a232e 7949 item = xmlStrndup(cur, end - cur);
pcercuei 0:03b5121a232e 7950 if (xmlStrEqual(item, BAD_CAST "extension")) {
pcercuei 0:03b5121a232e 7951 if (flagExtension != -1) {
pcercuei 0:03b5121a232e 7952 if ((*flags & flagExtension) == 0)
pcercuei 0:03b5121a232e 7953 *flags |= flagExtension;
pcercuei 0:03b5121a232e 7954 } else
pcercuei 0:03b5121a232e 7955 ret = 1;
pcercuei 0:03b5121a232e 7956 } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
pcercuei 0:03b5121a232e 7957 if (flagRestriction != -1) {
pcercuei 0:03b5121a232e 7958 if ((*flags & flagRestriction) == 0)
pcercuei 0:03b5121a232e 7959 *flags |= flagRestriction;
pcercuei 0:03b5121a232e 7960 } else
pcercuei 0:03b5121a232e 7961 ret = 1;
pcercuei 0:03b5121a232e 7962 } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
pcercuei 0:03b5121a232e 7963 if (flagSubstitution != -1) {
pcercuei 0:03b5121a232e 7964 if ((*flags & flagSubstitution) == 0)
pcercuei 0:03b5121a232e 7965 *flags |= flagSubstitution;
pcercuei 0:03b5121a232e 7966 } else
pcercuei 0:03b5121a232e 7967 ret = 1;
pcercuei 0:03b5121a232e 7968 } else if (xmlStrEqual(item, BAD_CAST "list")) {
pcercuei 0:03b5121a232e 7969 if (flagList != -1) {
pcercuei 0:03b5121a232e 7970 if ((*flags & flagList) == 0)
pcercuei 0:03b5121a232e 7971 *flags |= flagList;
pcercuei 0:03b5121a232e 7972 } else
pcercuei 0:03b5121a232e 7973 ret = 1;
pcercuei 0:03b5121a232e 7974 } else if (xmlStrEqual(item, BAD_CAST "union")) {
pcercuei 0:03b5121a232e 7975 if (flagUnion != -1) {
pcercuei 0:03b5121a232e 7976 if ((*flags & flagUnion) == 0)
pcercuei 0:03b5121a232e 7977 *flags |= flagUnion;
pcercuei 0:03b5121a232e 7978 } else
pcercuei 0:03b5121a232e 7979 ret = 1;
pcercuei 0:03b5121a232e 7980 } else
pcercuei 0:03b5121a232e 7981 ret = 1;
pcercuei 0:03b5121a232e 7982 if (item != NULL)
pcercuei 0:03b5121a232e 7983 xmlFree(item);
pcercuei 0:03b5121a232e 7984 cur = end;
pcercuei 0:03b5121a232e 7985 } while ((ret == 0) && (*cur != 0));
pcercuei 0:03b5121a232e 7986 }
pcercuei 0:03b5121a232e 7987
pcercuei 0:03b5121a232e 7988 return (ret);
pcercuei 0:03b5121a232e 7989 }
pcercuei 0:03b5121a232e 7990
pcercuei 0:03b5121a232e 7991 static int
pcercuei 0:03b5121a232e 7992 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 7993 xmlSchemaIDCPtr idc,
pcercuei 0:03b5121a232e 7994 xmlSchemaIDCSelectPtr selector,
pcercuei 0:03b5121a232e 7995 xmlAttrPtr attr,
pcercuei 0:03b5121a232e 7996 int isField)
pcercuei 0:03b5121a232e 7997 {
pcercuei 0:03b5121a232e 7998 xmlNodePtr node;
pcercuei 0:03b5121a232e 7999
pcercuei 0:03b5121a232e 8000 /*
pcercuei 0:03b5121a232e 8001 * c-selector-xpath:
pcercuei 0:03b5121a232e 8002 * Schema Component Constraint: Selector Value OK
pcercuei 0:03b5121a232e 8003 *
pcercuei 0:03b5121a232e 8004 * TODO: 1 The {selector} must be a valid XPath expression, as defined
pcercuei 0:03b5121a232e 8005 * in [XPath].
pcercuei 0:03b5121a232e 8006 */
pcercuei 0:03b5121a232e 8007 if (selector == NULL) {
pcercuei 0:03b5121a232e 8008 xmlSchemaPErr(ctxt, idc->node,
pcercuei 0:03b5121a232e 8009 XML_SCHEMAP_INTERNAL,
pcercuei 0:03b5121a232e 8010 "Internal error: xmlSchemaCheckCSelectorXPath, "
pcercuei 0:03b5121a232e 8011 "the selector is not specified.\n", NULL, NULL);
pcercuei 0:03b5121a232e 8012 return (-1);
pcercuei 0:03b5121a232e 8013 }
pcercuei 0:03b5121a232e 8014 if (attr == NULL)
pcercuei 0:03b5121a232e 8015 node = idc->node;
pcercuei 0:03b5121a232e 8016 else
pcercuei 0:03b5121a232e 8017 node = (xmlNodePtr) attr;
pcercuei 0:03b5121a232e 8018 if (selector->xpath == NULL) {
pcercuei 0:03b5121a232e 8019 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 8020 /* TODO: Adjust error code. */
pcercuei 0:03b5121a232e 8021 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 8022 NULL, node,
pcercuei 0:03b5121a232e 8023 "The XPath expression of the selector is not valid", NULL);
pcercuei 0:03b5121a232e 8024 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
pcercuei 0:03b5121a232e 8025 } else {
pcercuei 0:03b5121a232e 8026 const xmlChar **nsArray = NULL;
pcercuei 0:03b5121a232e 8027 xmlNsPtr *nsList = NULL;
pcercuei 0:03b5121a232e 8028 /*
pcercuei 0:03b5121a232e 8029 * Compile the XPath expression.
pcercuei 0:03b5121a232e 8030 */
pcercuei 0:03b5121a232e 8031 /*
pcercuei 0:03b5121a232e 8032 * TODO: We need the array of in-scope namespaces for compilation.
pcercuei 0:03b5121a232e 8033 * TODO: Call xmlPatterncompile with different options for selector/
pcercuei 0:03b5121a232e 8034 * field.
pcercuei 0:03b5121a232e 8035 */
pcercuei 0:03b5121a232e 8036 if (attr == NULL)
pcercuei 0:03b5121a232e 8037 nsList = NULL;
pcercuei 0:03b5121a232e 8038 else
pcercuei 0:03b5121a232e 8039 nsList = xmlGetNsList(attr->doc, attr->parent);
pcercuei 0:03b5121a232e 8040 /*
pcercuei 0:03b5121a232e 8041 * Build an array of prefixes and namespaces.
pcercuei 0:03b5121a232e 8042 */
pcercuei 0:03b5121a232e 8043 if (nsList != NULL) {
pcercuei 0:03b5121a232e 8044 int i, count = 0;
pcercuei 0:03b5121a232e 8045
pcercuei 0:03b5121a232e 8046 for (i = 0; nsList[i] != NULL; i++)
pcercuei 0:03b5121a232e 8047 count++;
pcercuei 0:03b5121a232e 8048
pcercuei 0:03b5121a232e 8049 nsArray = (const xmlChar **) xmlMalloc(
pcercuei 0:03b5121a232e 8050 (count * 2 + 1) * sizeof(const xmlChar *));
pcercuei 0:03b5121a232e 8051 if (nsArray == NULL) {
pcercuei 0:03b5121a232e 8052 xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
pcercuei 0:03b5121a232e 8053 NULL);
pcercuei 0:03b5121a232e 8054 xmlFree(nsList);
pcercuei 0:03b5121a232e 8055 return (-1);
pcercuei 0:03b5121a232e 8056 }
pcercuei 0:03b5121a232e 8057 for (i = 0; i < count; i++) {
pcercuei 0:03b5121a232e 8058 nsArray[2 * i] = nsList[i]->href;
pcercuei 0:03b5121a232e 8059 nsArray[2 * i + 1] = nsList[i]->prefix;
pcercuei 0:03b5121a232e 8060 }
pcercuei 0:03b5121a232e 8061 nsArray[count * 2] = NULL;
pcercuei 0:03b5121a232e 8062 xmlFree(nsList);
pcercuei 0:03b5121a232e 8063 }
pcercuei 0:03b5121a232e 8064 /*
pcercuei 0:03b5121a232e 8065 * TODO: Differentiate between "selector" and "field".
pcercuei 0:03b5121a232e 8066 */
pcercuei 0:03b5121a232e 8067 if (isField)
pcercuei 0:03b5121a232e 8068 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
pcercuei 0:03b5121a232e 8069 NULL, XML_PATTERN_XSFIELD, nsArray);
pcercuei 0:03b5121a232e 8070 else
pcercuei 0:03b5121a232e 8071 selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
pcercuei 0:03b5121a232e 8072 NULL, XML_PATTERN_XSSEL, nsArray);
pcercuei 0:03b5121a232e 8073 if (nsArray != NULL)
pcercuei 0:03b5121a232e 8074 xmlFree((xmlChar **) nsArray);
pcercuei 0:03b5121a232e 8075
pcercuei 0:03b5121a232e 8076 if (selector->xpathComp == NULL) {
pcercuei 0:03b5121a232e 8077 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 8078 /* TODO: Adjust error code? */
pcercuei 0:03b5121a232e 8079 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 8080 NULL, node,
pcercuei 0:03b5121a232e 8081 "The XPath expression '%s' could not be "
pcercuei 0:03b5121a232e 8082 "compiled", selector->xpath);
pcercuei 0:03b5121a232e 8083 return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
pcercuei 0:03b5121a232e 8084 }
pcercuei 0:03b5121a232e 8085 }
pcercuei 0:03b5121a232e 8086 return (0);
pcercuei 0:03b5121a232e 8087 }
pcercuei 0:03b5121a232e 8088
pcercuei 0:03b5121a232e 8089 #define ADD_ANNOTATION(annot) \
pcercuei 0:03b5121a232e 8090 xmlSchemaAnnotPtr cur = item->annot; \
pcercuei 0:03b5121a232e 8091 if (item->annot == NULL) { \
pcercuei 0:03b5121a232e 8092 item->annot = annot; \
pcercuei 0:03b5121a232e 8093 return (annot); \
pcercuei 0:03b5121a232e 8094 } \
pcercuei 0:03b5121a232e 8095 cur = item->annot; \
pcercuei 0:03b5121a232e 8096 if (cur->next != NULL) { \
pcercuei 0:03b5121a232e 8097 cur = cur->next; \
pcercuei 0:03b5121a232e 8098 } \
pcercuei 0:03b5121a232e 8099 cur->next = annot;
pcercuei 0:03b5121a232e 8100
pcercuei 0:03b5121a232e 8101 /**
pcercuei 0:03b5121a232e 8102 * xmlSchemaAssignAnnotation:
pcercuei 0:03b5121a232e 8103 * @item: the schema component
pcercuei 0:03b5121a232e 8104 * @annot: the annotation
pcercuei 0:03b5121a232e 8105 *
pcercuei 0:03b5121a232e 8106 * Adds the annotation to the given schema component.
pcercuei 0:03b5121a232e 8107 *
pcercuei 0:03b5121a232e 8108 * Returns the given annotaion.
pcercuei 0:03b5121a232e 8109 */
pcercuei 0:03b5121a232e 8110 static xmlSchemaAnnotPtr
pcercuei 0:03b5121a232e 8111 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
pcercuei 0:03b5121a232e 8112 xmlSchemaAnnotPtr annot)
pcercuei 0:03b5121a232e 8113 {
pcercuei 0:03b5121a232e 8114 if ((annItem == NULL) || (annot == NULL))
pcercuei 0:03b5121a232e 8115 return (NULL);
pcercuei 0:03b5121a232e 8116 switch (annItem->type) {
pcercuei 0:03b5121a232e 8117 case XML_SCHEMA_TYPE_ELEMENT: {
pcercuei 0:03b5121a232e 8118 xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
pcercuei 0:03b5121a232e 8119 ADD_ANNOTATION(annot)
pcercuei 0:03b5121a232e 8120 }
pcercuei 0:03b5121a232e 8121 break;
pcercuei 0:03b5121a232e 8122 case XML_SCHEMA_TYPE_ATTRIBUTE: {
pcercuei 0:03b5121a232e 8123 xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
pcercuei 0:03b5121a232e 8124 ADD_ANNOTATION(annot)
pcercuei 0:03b5121a232e 8125 }
pcercuei 0:03b5121a232e 8126 break;
pcercuei 0:03b5121a232e 8127 case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
pcercuei 0:03b5121a232e 8128 case XML_SCHEMA_TYPE_ANY: {
pcercuei 0:03b5121a232e 8129 xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
pcercuei 0:03b5121a232e 8130 ADD_ANNOTATION(annot)
pcercuei 0:03b5121a232e 8131 }
pcercuei 0:03b5121a232e 8132 break;
pcercuei 0:03b5121a232e 8133 case XML_SCHEMA_TYPE_PARTICLE:
pcercuei 0:03b5121a232e 8134 case XML_SCHEMA_TYPE_IDC_KEY:
pcercuei 0:03b5121a232e 8135 case XML_SCHEMA_TYPE_IDC_KEYREF:
pcercuei 0:03b5121a232e 8136 case XML_SCHEMA_TYPE_IDC_UNIQUE: {
pcercuei 0:03b5121a232e 8137 xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
pcercuei 0:03b5121a232e 8138 ADD_ANNOTATION(annot)
pcercuei 0:03b5121a232e 8139 }
pcercuei 0:03b5121a232e 8140 break;
pcercuei 0:03b5121a232e 8141 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
pcercuei 0:03b5121a232e 8142 xmlSchemaAttributeGroupPtr item =
pcercuei 0:03b5121a232e 8143 (xmlSchemaAttributeGroupPtr) annItem;
pcercuei 0:03b5121a232e 8144 ADD_ANNOTATION(annot)
pcercuei 0:03b5121a232e 8145 }
pcercuei 0:03b5121a232e 8146 break;
pcercuei 0:03b5121a232e 8147 case XML_SCHEMA_TYPE_NOTATION: {
pcercuei 0:03b5121a232e 8148 xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
pcercuei 0:03b5121a232e 8149 ADD_ANNOTATION(annot)
pcercuei 0:03b5121a232e 8150 }
pcercuei 0:03b5121a232e 8151 break;
pcercuei 0:03b5121a232e 8152 case XML_SCHEMA_FACET_MININCLUSIVE:
pcercuei 0:03b5121a232e 8153 case XML_SCHEMA_FACET_MINEXCLUSIVE:
pcercuei 0:03b5121a232e 8154 case XML_SCHEMA_FACET_MAXINCLUSIVE:
pcercuei 0:03b5121a232e 8155 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
pcercuei 0:03b5121a232e 8156 case XML_SCHEMA_FACET_TOTALDIGITS:
pcercuei 0:03b5121a232e 8157 case XML_SCHEMA_FACET_FRACTIONDIGITS:
pcercuei 0:03b5121a232e 8158 case XML_SCHEMA_FACET_PATTERN:
pcercuei 0:03b5121a232e 8159 case XML_SCHEMA_FACET_ENUMERATION:
pcercuei 0:03b5121a232e 8160 case XML_SCHEMA_FACET_WHITESPACE:
pcercuei 0:03b5121a232e 8161 case XML_SCHEMA_FACET_LENGTH:
pcercuei 0:03b5121a232e 8162 case XML_SCHEMA_FACET_MAXLENGTH:
pcercuei 0:03b5121a232e 8163 case XML_SCHEMA_FACET_MINLENGTH: {
pcercuei 0:03b5121a232e 8164 xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
pcercuei 0:03b5121a232e 8165 ADD_ANNOTATION(annot)
pcercuei 0:03b5121a232e 8166 }
pcercuei 0:03b5121a232e 8167 break;
pcercuei 0:03b5121a232e 8168 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 8169 case XML_SCHEMA_TYPE_COMPLEX: {
pcercuei 0:03b5121a232e 8170 xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
pcercuei 0:03b5121a232e 8171 ADD_ANNOTATION(annot)
pcercuei 0:03b5121a232e 8172 }
pcercuei 0:03b5121a232e 8173 break;
pcercuei 0:03b5121a232e 8174 case XML_SCHEMA_TYPE_GROUP: {
pcercuei 0:03b5121a232e 8175 xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
pcercuei 0:03b5121a232e 8176 ADD_ANNOTATION(annot)
pcercuei 0:03b5121a232e 8177 }
pcercuei 0:03b5121a232e 8178 break;
pcercuei 0:03b5121a232e 8179 case XML_SCHEMA_TYPE_SEQUENCE:
pcercuei 0:03b5121a232e 8180 case XML_SCHEMA_TYPE_CHOICE:
pcercuei 0:03b5121a232e 8181 case XML_SCHEMA_TYPE_ALL: {
pcercuei 0:03b5121a232e 8182 xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
pcercuei 0:03b5121a232e 8183 ADD_ANNOTATION(annot)
pcercuei 0:03b5121a232e 8184 }
pcercuei 0:03b5121a232e 8185 break;
pcercuei 0:03b5121a232e 8186 default:
pcercuei 0:03b5121a232e 8187 xmlSchemaPCustomErr(NULL,
pcercuei 0:03b5121a232e 8188 XML_SCHEMAP_INTERNAL,
pcercuei 0:03b5121a232e 8189 NULL, NULL,
pcercuei 0:03b5121a232e 8190 "Internal error: xmlSchemaAddAnnotation, "
pcercuei 0:03b5121a232e 8191 "The item is not a annotated schema component", NULL);
pcercuei 0:03b5121a232e 8192 break;
pcercuei 0:03b5121a232e 8193 }
pcercuei 0:03b5121a232e 8194 return (annot);
pcercuei 0:03b5121a232e 8195 }
pcercuei 0:03b5121a232e 8196
pcercuei 0:03b5121a232e 8197 /**
pcercuei 0:03b5121a232e 8198 * xmlSchemaParseIDCSelectorAndField:
pcercuei 0:03b5121a232e 8199 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 8200 * @schema: the schema being built
pcercuei 0:03b5121a232e 8201 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 8202 *
pcercuei 0:03b5121a232e 8203 * Parses a XML Schema identity-contraint definition's
pcercuei 0:03b5121a232e 8204 * <selector> and <field> elements.
pcercuei 0:03b5121a232e 8205 *
pcercuei 0:03b5121a232e 8206 * Returns the parsed identity-constraint definition.
pcercuei 0:03b5121a232e 8207 */
pcercuei 0:03b5121a232e 8208 static xmlSchemaIDCSelectPtr
pcercuei 0:03b5121a232e 8209 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 8210 xmlSchemaIDCPtr idc,
pcercuei 0:03b5121a232e 8211 xmlNodePtr node,
pcercuei 0:03b5121a232e 8212 int isField)
pcercuei 0:03b5121a232e 8213 {
pcercuei 0:03b5121a232e 8214 xmlSchemaIDCSelectPtr item;
pcercuei 0:03b5121a232e 8215 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 8216 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 8217
pcercuei 0:03b5121a232e 8218 /*
pcercuei 0:03b5121a232e 8219 * Check for illegal attributes.
pcercuei 0:03b5121a232e 8220 */
pcercuei 0:03b5121a232e 8221 attr = node->properties;
pcercuei 0:03b5121a232e 8222 while (attr != NULL) {
pcercuei 0:03b5121a232e 8223 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 8224 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 8225 (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
pcercuei 0:03b5121a232e 8226 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 8227 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 8228 }
pcercuei 0:03b5121a232e 8229 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 8230 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 8231 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 8232 }
pcercuei 0:03b5121a232e 8233 attr = attr->next;
pcercuei 0:03b5121a232e 8234 }
pcercuei 0:03b5121a232e 8235 /*
pcercuei 0:03b5121a232e 8236 * Create the item.
pcercuei 0:03b5121a232e 8237 */
pcercuei 0:03b5121a232e 8238 item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
pcercuei 0:03b5121a232e 8239 if (item == NULL) {
pcercuei 0:03b5121a232e 8240 xmlSchemaPErrMemory(ctxt,
pcercuei 0:03b5121a232e 8241 "allocating a 'selector' of an identity-constraint definition",
pcercuei 0:03b5121a232e 8242 NULL);
pcercuei 0:03b5121a232e 8243 return (NULL);
pcercuei 0:03b5121a232e 8244 }
pcercuei 0:03b5121a232e 8245 memset(item, 0, sizeof(xmlSchemaIDCSelect));
pcercuei 0:03b5121a232e 8246 /*
pcercuei 0:03b5121a232e 8247 * Attribute "xpath" (mandatory).
pcercuei 0:03b5121a232e 8248 */
pcercuei 0:03b5121a232e 8249 attr = xmlSchemaGetPropNode(node, "xpath");
pcercuei 0:03b5121a232e 8250 if (attr == NULL) {
pcercuei 0:03b5121a232e 8251 xmlSchemaPMissingAttrErr(ctxt,
pcercuei 0:03b5121a232e 8252 XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 8253 NULL, node,
pcercuei 0:03b5121a232e 8254 "name", NULL);
pcercuei 0:03b5121a232e 8255 } else {
pcercuei 0:03b5121a232e 8256 item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 8257 /*
pcercuei 0:03b5121a232e 8258 * URGENT TODO: "field"s have an other syntax than "selector"s.
pcercuei 0:03b5121a232e 8259 */
pcercuei 0:03b5121a232e 8260
pcercuei 0:03b5121a232e 8261 if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
pcercuei 0:03b5121a232e 8262 isField) == -1) {
pcercuei 0:03b5121a232e 8263 xmlSchemaPErr(ctxt,
pcercuei 0:03b5121a232e 8264 (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 8265 XML_SCHEMAP_INTERNAL,
pcercuei 0:03b5121a232e 8266 "Internal error: xmlSchemaParseIDCSelectorAndField, "
pcercuei 0:03b5121a232e 8267 "validating the XPath expression of a IDC selector.\n",
pcercuei 0:03b5121a232e 8268 NULL, NULL);
pcercuei 0:03b5121a232e 8269 }
pcercuei 0:03b5121a232e 8270
pcercuei 0:03b5121a232e 8271 }
pcercuei 0:03b5121a232e 8272 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 8273 /*
pcercuei 0:03b5121a232e 8274 * And now for the children...
pcercuei 0:03b5121a232e 8275 */
pcercuei 0:03b5121a232e 8276 child = node->children;
pcercuei 0:03b5121a232e 8277 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 8278 /*
pcercuei 0:03b5121a232e 8279 * Add the annotation to the parent IDC.
pcercuei 0:03b5121a232e 8280 */
pcercuei 0:03b5121a232e 8281 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
pcercuei 0:03b5121a232e 8282 xmlSchemaParseAnnotation(ctxt, child, 1));
pcercuei 0:03b5121a232e 8283 child = child->next;
pcercuei 0:03b5121a232e 8284 }
pcercuei 0:03b5121a232e 8285 if (child != NULL) {
pcercuei 0:03b5121a232e 8286 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 8287 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 8288 NULL, node, child,
pcercuei 0:03b5121a232e 8289 NULL, "(annotation?)");
pcercuei 0:03b5121a232e 8290 }
pcercuei 0:03b5121a232e 8291
pcercuei 0:03b5121a232e 8292 return (item);
pcercuei 0:03b5121a232e 8293 }
pcercuei 0:03b5121a232e 8294
pcercuei 0:03b5121a232e 8295 /**
pcercuei 0:03b5121a232e 8296 * xmlSchemaParseIDC:
pcercuei 0:03b5121a232e 8297 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 8298 * @schema: the schema being built
pcercuei 0:03b5121a232e 8299 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 8300 *
pcercuei 0:03b5121a232e 8301 * Parses a XML Schema identity-contraint definition.
pcercuei 0:03b5121a232e 8302 *
pcercuei 0:03b5121a232e 8303 * Returns the parsed identity-constraint definition.
pcercuei 0:03b5121a232e 8304 */
pcercuei 0:03b5121a232e 8305 static xmlSchemaIDCPtr
pcercuei 0:03b5121a232e 8306 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 8307 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 8308 xmlNodePtr node,
pcercuei 0:03b5121a232e 8309 xmlSchemaTypeType idcCategory,
pcercuei 0:03b5121a232e 8310 const xmlChar *targetNamespace)
pcercuei 0:03b5121a232e 8311 {
pcercuei 0:03b5121a232e 8312 xmlSchemaIDCPtr item = NULL;
pcercuei 0:03b5121a232e 8313 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 8314 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 8315 const xmlChar *name = NULL;
pcercuei 0:03b5121a232e 8316 xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
pcercuei 0:03b5121a232e 8317
pcercuei 0:03b5121a232e 8318 /*
pcercuei 0:03b5121a232e 8319 * Check for illegal attributes.
pcercuei 0:03b5121a232e 8320 */
pcercuei 0:03b5121a232e 8321 attr = node->properties;
pcercuei 0:03b5121a232e 8322 while (attr != NULL) {
pcercuei 0:03b5121a232e 8323 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 8324 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 8325 (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
pcercuei 0:03b5121a232e 8326 ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
pcercuei 0:03b5121a232e 8327 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
pcercuei 0:03b5121a232e 8328 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 8329 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 8330 }
pcercuei 0:03b5121a232e 8331 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 8332 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 8333 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 8334 }
pcercuei 0:03b5121a232e 8335 attr = attr->next;
pcercuei 0:03b5121a232e 8336 }
pcercuei 0:03b5121a232e 8337 /*
pcercuei 0:03b5121a232e 8338 * Attribute "name" (mandatory).
pcercuei 0:03b5121a232e 8339 */
pcercuei 0:03b5121a232e 8340 attr = xmlSchemaGetPropNode(node, "name");
pcercuei 0:03b5121a232e 8341 if (attr == NULL) {
pcercuei 0:03b5121a232e 8342 xmlSchemaPMissingAttrErr(ctxt,
pcercuei 0:03b5121a232e 8343 XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 8344 NULL, node,
pcercuei 0:03b5121a232e 8345 "name", NULL);
pcercuei 0:03b5121a232e 8346 return (NULL);
pcercuei 0:03b5121a232e 8347 } else if (xmlSchemaPValAttrNode(ctxt,
pcercuei 0:03b5121a232e 8348 NULL, attr,
pcercuei 0:03b5121a232e 8349 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
pcercuei 0:03b5121a232e 8350 return (NULL);
pcercuei 0:03b5121a232e 8351 }
pcercuei 0:03b5121a232e 8352 /* Create the component. */
pcercuei 0:03b5121a232e 8353 item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
pcercuei 0:03b5121a232e 8354 idcCategory, node);
pcercuei 0:03b5121a232e 8355 if (item == NULL)
pcercuei 0:03b5121a232e 8356 return(NULL);
pcercuei 0:03b5121a232e 8357
pcercuei 0:03b5121a232e 8358 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 8359 if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
pcercuei 0:03b5121a232e 8360 /*
pcercuei 0:03b5121a232e 8361 * Attribute "refer" (mandatory).
pcercuei 0:03b5121a232e 8362 */
pcercuei 0:03b5121a232e 8363 attr = xmlSchemaGetPropNode(node, "refer");
pcercuei 0:03b5121a232e 8364 if (attr == NULL) {
pcercuei 0:03b5121a232e 8365 xmlSchemaPMissingAttrErr(ctxt,
pcercuei 0:03b5121a232e 8366 XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 8367 NULL, node,
pcercuei 0:03b5121a232e 8368 "refer", NULL);
pcercuei 0:03b5121a232e 8369 } else {
pcercuei 0:03b5121a232e 8370 /*
pcercuei 0:03b5121a232e 8371 * Create a reference item.
pcercuei 0:03b5121a232e 8372 */
pcercuei 0:03b5121a232e 8373 item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
pcercuei 0:03b5121a232e 8374 NULL, NULL);
pcercuei 0:03b5121a232e 8375 if (item->ref == NULL)
pcercuei 0:03b5121a232e 8376 return (NULL);
pcercuei 0:03b5121a232e 8377 xmlSchemaPValAttrNodeQName(ctxt, schema,
pcercuei 0:03b5121a232e 8378 NULL, attr,
pcercuei 0:03b5121a232e 8379 &(item->ref->targetNamespace),
pcercuei 0:03b5121a232e 8380 &(item->ref->name));
pcercuei 0:03b5121a232e 8381 xmlSchemaCheckReference(ctxt, schema, node, attr,
pcercuei 0:03b5121a232e 8382 item->ref->targetNamespace);
pcercuei 0:03b5121a232e 8383 }
pcercuei 0:03b5121a232e 8384 }
pcercuei 0:03b5121a232e 8385 /*
pcercuei 0:03b5121a232e 8386 * And now for the children...
pcercuei 0:03b5121a232e 8387 */
pcercuei 0:03b5121a232e 8388 child = node->children;
pcercuei 0:03b5121a232e 8389 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 8390 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
pcercuei 0:03b5121a232e 8391 child = child->next;
pcercuei 0:03b5121a232e 8392 }
pcercuei 0:03b5121a232e 8393 if (child == NULL) {
pcercuei 0:03b5121a232e 8394 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 8395 XML_SCHEMAP_S4S_ELEM_MISSING,
pcercuei 0:03b5121a232e 8396 NULL, node, child,
pcercuei 0:03b5121a232e 8397 "A child element is missing",
pcercuei 0:03b5121a232e 8398 "(annotation?, (selector, field+))");
pcercuei 0:03b5121a232e 8399 }
pcercuei 0:03b5121a232e 8400 /*
pcercuei 0:03b5121a232e 8401 * Child element <selector>.
pcercuei 0:03b5121a232e 8402 */
pcercuei 0:03b5121a232e 8403 if (IS_SCHEMA(child, "selector")) {
pcercuei 0:03b5121a232e 8404 item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
pcercuei 0:03b5121a232e 8405 item, child, 0);
pcercuei 0:03b5121a232e 8406 child = child->next;
pcercuei 0:03b5121a232e 8407 /*
pcercuei 0:03b5121a232e 8408 * Child elements <field>.
pcercuei 0:03b5121a232e 8409 */
pcercuei 0:03b5121a232e 8410 if (IS_SCHEMA(child, "field")) {
pcercuei 0:03b5121a232e 8411 do {
pcercuei 0:03b5121a232e 8412 field = xmlSchemaParseIDCSelectorAndField(ctxt,
pcercuei 0:03b5121a232e 8413 item, child, 1);
pcercuei 0:03b5121a232e 8414 if (field != NULL) {
pcercuei 0:03b5121a232e 8415 field->index = item->nbFields;
pcercuei 0:03b5121a232e 8416 item->nbFields++;
pcercuei 0:03b5121a232e 8417 if (lastField != NULL)
pcercuei 0:03b5121a232e 8418 lastField->next = field;
pcercuei 0:03b5121a232e 8419 else
pcercuei 0:03b5121a232e 8420 item->fields = field;
pcercuei 0:03b5121a232e 8421 lastField = field;
pcercuei 0:03b5121a232e 8422 }
pcercuei 0:03b5121a232e 8423 child = child->next;
pcercuei 0:03b5121a232e 8424 } while (IS_SCHEMA(child, "field"));
pcercuei 0:03b5121a232e 8425 } else {
pcercuei 0:03b5121a232e 8426 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 8427 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 8428 NULL, node, child,
pcercuei 0:03b5121a232e 8429 NULL, "(annotation?, (selector, field+))");
pcercuei 0:03b5121a232e 8430 }
pcercuei 0:03b5121a232e 8431 }
pcercuei 0:03b5121a232e 8432 if (child != NULL) {
pcercuei 0:03b5121a232e 8433 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 8434 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 8435 NULL, node, child,
pcercuei 0:03b5121a232e 8436 NULL, "(annotation?, (selector, field+))");
pcercuei 0:03b5121a232e 8437 }
pcercuei 0:03b5121a232e 8438
pcercuei 0:03b5121a232e 8439 return (item);
pcercuei 0:03b5121a232e 8440 }
pcercuei 0:03b5121a232e 8441
pcercuei 0:03b5121a232e 8442 /**
pcercuei 0:03b5121a232e 8443 * xmlSchemaParseElement:
pcercuei 0:03b5121a232e 8444 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 8445 * @schema: the schema being built
pcercuei 0:03b5121a232e 8446 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 8447 * @topLevel: indicates if this is global declaration
pcercuei 0:03b5121a232e 8448 *
pcercuei 0:03b5121a232e 8449 * Parses a XML schema element declaration.
pcercuei 0:03b5121a232e 8450 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 8451 *
pcercuei 0:03b5121a232e 8452 * Returns the element declaration or a particle; NULL in case
pcercuei 0:03b5121a232e 8453 * of an error or if the particle has minOccurs==maxOccurs==0.
pcercuei 0:03b5121a232e 8454 */
pcercuei 0:03b5121a232e 8455 static xmlSchemaBasicItemPtr
pcercuei 0:03b5121a232e 8456 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 8457 xmlNodePtr node, int *isElemRef, int topLevel)
pcercuei 0:03b5121a232e 8458 {
pcercuei 0:03b5121a232e 8459 xmlSchemaElementPtr decl = NULL;
pcercuei 0:03b5121a232e 8460 xmlSchemaParticlePtr particle = NULL;
pcercuei 0:03b5121a232e 8461 xmlSchemaAnnotPtr annot = NULL;
pcercuei 0:03b5121a232e 8462 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 8463 xmlAttrPtr attr, nameAttr;
pcercuei 0:03b5121a232e 8464 int min, max, isRef = 0;
pcercuei 0:03b5121a232e 8465 xmlChar *des = NULL;
pcercuei 0:03b5121a232e 8466
pcercuei 0:03b5121a232e 8467 /* 3.3.3 Constraints on XML Representations of Element Declarations */
pcercuei 0:03b5121a232e 8468 /* TODO: Complete implementation of 3.3.6 */
pcercuei 0:03b5121a232e 8469
pcercuei 0:03b5121a232e 8470 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 8471 return (NULL);
pcercuei 0:03b5121a232e 8472
pcercuei 0:03b5121a232e 8473 if (isElemRef != NULL)
pcercuei 0:03b5121a232e 8474 *isElemRef = 0;
pcercuei 0:03b5121a232e 8475 /*
pcercuei 0:03b5121a232e 8476 * If we get a "ref" attribute on a local <element> we will assume it's
pcercuei 0:03b5121a232e 8477 * a reference - even if there's a "name" attribute; this seems to be more
pcercuei 0:03b5121a232e 8478 * robust.
pcercuei 0:03b5121a232e 8479 */
pcercuei 0:03b5121a232e 8480 nameAttr = xmlSchemaGetPropNode(node, "name");
pcercuei 0:03b5121a232e 8481 attr = xmlSchemaGetPropNode(node, "ref");
pcercuei 0:03b5121a232e 8482 if ((topLevel) || (attr == NULL)) {
pcercuei 0:03b5121a232e 8483 if (nameAttr == NULL) {
pcercuei 0:03b5121a232e 8484 xmlSchemaPMissingAttrErr(ctxt,
pcercuei 0:03b5121a232e 8485 XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 8486 NULL, node, "name", NULL);
pcercuei 0:03b5121a232e 8487 return (NULL);
pcercuei 0:03b5121a232e 8488 }
pcercuei 0:03b5121a232e 8489 } else
pcercuei 0:03b5121a232e 8490 isRef = 1;
pcercuei 0:03b5121a232e 8491
pcercuei 0:03b5121a232e 8492 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 8493 child = node->children;
pcercuei 0:03b5121a232e 8494 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 8495 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
pcercuei 0:03b5121a232e 8496 child = child->next;
pcercuei 0:03b5121a232e 8497 }
pcercuei 0:03b5121a232e 8498 /*
pcercuei 0:03b5121a232e 8499 * Skip particle part if a global declaration.
pcercuei 0:03b5121a232e 8500 */
pcercuei 0:03b5121a232e 8501 if (topLevel)
pcercuei 0:03b5121a232e 8502 goto declaration_part;
pcercuei 0:03b5121a232e 8503 /*
pcercuei 0:03b5121a232e 8504 * The particle part ==================================================
pcercuei 0:03b5121a232e 8505 */
pcercuei 0:03b5121a232e 8506 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
pcercuei 0:03b5121a232e 8507 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
pcercuei 0:03b5121a232e 8508 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
pcercuei 0:03b5121a232e 8509 particle = xmlSchemaAddParticle(ctxt, node, min, max);
pcercuei 0:03b5121a232e 8510 if (particle == NULL)
pcercuei 0:03b5121a232e 8511 goto return_null;
pcercuei 0:03b5121a232e 8512
pcercuei 0:03b5121a232e 8513 /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
pcercuei 0:03b5121a232e 8514
pcercuei 0:03b5121a232e 8515 if (isRef) {
pcercuei 0:03b5121a232e 8516 const xmlChar *refNs = NULL, *ref = NULL;
pcercuei 0:03b5121a232e 8517 xmlSchemaQNameRefPtr refer = NULL;
pcercuei 0:03b5121a232e 8518 /*
pcercuei 0:03b5121a232e 8519 * The reference part =============================================
pcercuei 0:03b5121a232e 8520 */
pcercuei 0:03b5121a232e 8521 if (isElemRef != NULL)
pcercuei 0:03b5121a232e 8522 *isElemRef = 1;
pcercuei 0:03b5121a232e 8523
pcercuei 0:03b5121a232e 8524 xmlSchemaPValAttrNodeQName(ctxt, schema,
pcercuei 0:03b5121a232e 8525 NULL, attr, &refNs, &ref);
pcercuei 0:03b5121a232e 8526 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
pcercuei 0:03b5121a232e 8527 /*
pcercuei 0:03b5121a232e 8528 * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
pcercuei 0:03b5121a232e 8529 */
pcercuei 0:03b5121a232e 8530 if (nameAttr != NULL) {
pcercuei 0:03b5121a232e 8531 xmlSchemaPMutualExclAttrErr(ctxt,
pcercuei 0:03b5121a232e 8532 XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
pcercuei 0:03b5121a232e 8533 }
pcercuei 0:03b5121a232e 8534 /*
pcercuei 0:03b5121a232e 8535 * Check for illegal attributes.
pcercuei 0:03b5121a232e 8536 */
pcercuei 0:03b5121a232e 8537 attr = node->properties;
pcercuei 0:03b5121a232e 8538 while (attr != NULL) {
pcercuei 0:03b5121a232e 8539 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 8540 if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
pcercuei 0:03b5121a232e 8541 xmlStrEqual(attr->name, BAD_CAST "name") ||
pcercuei 0:03b5121a232e 8542 xmlStrEqual(attr->name, BAD_CAST "id") ||
pcercuei 0:03b5121a232e 8543 xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
pcercuei 0:03b5121a232e 8544 xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
pcercuei 0:03b5121a232e 8545 {
pcercuei 0:03b5121a232e 8546 attr = attr->next;
pcercuei 0:03b5121a232e 8547 continue;
pcercuei 0:03b5121a232e 8548 } else {
pcercuei 0:03b5121a232e 8549 /* SPEC (3.3.3 : 2.2) */
pcercuei 0:03b5121a232e 8550 xmlSchemaPCustomAttrErr(ctxt,
pcercuei 0:03b5121a232e 8551 XML_SCHEMAP_SRC_ELEMENT_2_2,
pcercuei 0:03b5121a232e 8552 NULL, NULL, attr,
pcercuei 0:03b5121a232e 8553 "Only the attributes 'minOccurs', 'maxOccurs' and "
pcercuei 0:03b5121a232e 8554 "'id' are allowed in addition to 'ref'");
pcercuei 0:03b5121a232e 8555 break;
pcercuei 0:03b5121a232e 8556 }
pcercuei 0:03b5121a232e 8557 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 8558 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 8559 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 8560 }
pcercuei 0:03b5121a232e 8561 attr = attr->next;
pcercuei 0:03b5121a232e 8562 }
pcercuei 0:03b5121a232e 8563 /*
pcercuei 0:03b5121a232e 8564 * No children except <annotation> expected.
pcercuei 0:03b5121a232e 8565 */
pcercuei 0:03b5121a232e 8566 if (child != NULL) {
pcercuei 0:03b5121a232e 8567 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 8568 NULL, node, child, NULL, "(annotation?)");
pcercuei 0:03b5121a232e 8569 }
pcercuei 0:03b5121a232e 8570 if ((min == 0) && (max == 0))
pcercuei 0:03b5121a232e 8571 goto return_null;
pcercuei 0:03b5121a232e 8572 /*
pcercuei 0:03b5121a232e 8573 * Create the reference item and attach it to the particle.
pcercuei 0:03b5121a232e 8574 */
pcercuei 0:03b5121a232e 8575 refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
pcercuei 0:03b5121a232e 8576 ref, refNs);
pcercuei 0:03b5121a232e 8577 if (refer == NULL)
pcercuei 0:03b5121a232e 8578 goto return_null;
pcercuei 0:03b5121a232e 8579 particle->children = (xmlSchemaTreeItemPtr) refer;
pcercuei 0:03b5121a232e 8580 particle->annot = annot;
pcercuei 0:03b5121a232e 8581 /*
pcercuei 0:03b5121a232e 8582 * Add the particle to pending components, since the reference
pcercuei 0:03b5121a232e 8583 * need to be resolved.
pcercuei 0:03b5121a232e 8584 */
pcercuei 0:03b5121a232e 8585 WXS_ADD_PENDING(ctxt, particle);
pcercuei 0:03b5121a232e 8586 return ((xmlSchemaBasicItemPtr) particle);
pcercuei 0:03b5121a232e 8587 }
pcercuei 0:03b5121a232e 8588 /*
pcercuei 0:03b5121a232e 8589 * The declaration part ===============================================
pcercuei 0:03b5121a232e 8590 */
pcercuei 0:03b5121a232e 8591 declaration_part:
pcercuei 0:03b5121a232e 8592 {
pcercuei 0:03b5121a232e 8593 const xmlChar *ns = NULL, *fixed, *name, *attrValue;
pcercuei 0:03b5121a232e 8594 xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
pcercuei 0:03b5121a232e 8595
pcercuei 0:03b5121a232e 8596 if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
pcercuei 0:03b5121a232e 8597 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
pcercuei 0:03b5121a232e 8598 goto return_null;
pcercuei 0:03b5121a232e 8599 /*
pcercuei 0:03b5121a232e 8600 * Evaluate the target namespace.
pcercuei 0:03b5121a232e 8601 */
pcercuei 0:03b5121a232e 8602 if (topLevel) {
pcercuei 0:03b5121a232e 8603 ns = ctxt->targetNamespace;
pcercuei 0:03b5121a232e 8604 } else {
pcercuei 0:03b5121a232e 8605 attr = xmlSchemaGetPropNode(node, "form");
pcercuei 0:03b5121a232e 8606 if (attr != NULL) {
pcercuei 0:03b5121a232e 8607 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 8608 if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
pcercuei 0:03b5121a232e 8609 ns = ctxt->targetNamespace;
pcercuei 0:03b5121a232e 8610 } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
pcercuei 0:03b5121a232e 8611 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 8612 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 8613 NULL, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 8614 NULL, "(qualified | unqualified)",
pcercuei 0:03b5121a232e 8615 attrValue, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 8616 }
pcercuei 0:03b5121a232e 8617 } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
pcercuei 0:03b5121a232e 8618 ns = ctxt->targetNamespace;
pcercuei 0:03b5121a232e 8619 }
pcercuei 0:03b5121a232e 8620 decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
pcercuei 0:03b5121a232e 8621 if (decl == NULL) {
pcercuei 0:03b5121a232e 8622 goto return_null;
pcercuei 0:03b5121a232e 8623 }
pcercuei 0:03b5121a232e 8624 /*
pcercuei 0:03b5121a232e 8625 * Check for illegal attributes.
pcercuei 0:03b5121a232e 8626 */
pcercuei 0:03b5121a232e 8627 attr = node->properties;
pcercuei 0:03b5121a232e 8628 while (attr != NULL) {
pcercuei 0:03b5121a232e 8629 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 8630 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
pcercuei 0:03b5121a232e 8631 (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
pcercuei 0:03b5121a232e 8632 (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 8633 (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
pcercuei 0:03b5121a232e 8634 (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
pcercuei 0:03b5121a232e 8635 (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
pcercuei 0:03b5121a232e 8636 (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
pcercuei 0:03b5121a232e 8637 {
pcercuei 0:03b5121a232e 8638 if (topLevel == 0) {
pcercuei 0:03b5121a232e 8639 if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
pcercuei 0:03b5121a232e 8640 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
pcercuei 0:03b5121a232e 8641 (!xmlStrEqual(attr->name, BAD_CAST "form")))
pcercuei 0:03b5121a232e 8642 {
pcercuei 0:03b5121a232e 8643 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 8644 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 8645 }
pcercuei 0:03b5121a232e 8646 } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
pcercuei 0:03b5121a232e 8647 (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
pcercuei 0:03b5121a232e 8648 (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
pcercuei 0:03b5121a232e 8649
pcercuei 0:03b5121a232e 8650 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 8651 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 8652 }
pcercuei 0:03b5121a232e 8653 }
pcercuei 0:03b5121a232e 8654 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 8655
pcercuei 0:03b5121a232e 8656 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 8657 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 8658 }
pcercuei 0:03b5121a232e 8659 attr = attr->next;
pcercuei 0:03b5121a232e 8660 }
pcercuei 0:03b5121a232e 8661 /*
pcercuei 0:03b5121a232e 8662 * Extract/validate attributes.
pcercuei 0:03b5121a232e 8663 */
pcercuei 0:03b5121a232e 8664 if (topLevel) {
pcercuei 0:03b5121a232e 8665 /*
pcercuei 0:03b5121a232e 8666 * Process top attributes of global element declarations here.
pcercuei 0:03b5121a232e 8667 */
pcercuei 0:03b5121a232e 8668 decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
pcercuei 0:03b5121a232e 8669 decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
pcercuei 0:03b5121a232e 8670 xmlSchemaPValAttrQName(ctxt, schema,
pcercuei 0:03b5121a232e 8671 NULL, node, "substitutionGroup",
pcercuei 0:03b5121a232e 8672 &(decl->substGroupNs), &(decl->substGroup));
pcercuei 0:03b5121a232e 8673 if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
pcercuei 0:03b5121a232e 8674 decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
pcercuei 0:03b5121a232e 8675 /*
pcercuei 0:03b5121a232e 8676 * Attribute "final".
pcercuei 0:03b5121a232e 8677 */
pcercuei 0:03b5121a232e 8678 attr = xmlSchemaGetPropNode(node, "final");
pcercuei 0:03b5121a232e 8679 if (attr == NULL) {
pcercuei 0:03b5121a232e 8680 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
pcercuei 0:03b5121a232e 8681 decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
pcercuei 0:03b5121a232e 8682 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
pcercuei 0:03b5121a232e 8683 decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
pcercuei 0:03b5121a232e 8684 } else {
pcercuei 0:03b5121a232e 8685 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 8686 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
pcercuei 0:03b5121a232e 8687 -1,
pcercuei 0:03b5121a232e 8688 XML_SCHEMAS_ELEM_FINAL_EXTENSION,
pcercuei 0:03b5121a232e 8689 XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
pcercuei 0:03b5121a232e 8690 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 8691 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 8692 NULL, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 8693 NULL, "(#all | List of (extension | restriction))",
pcercuei 0:03b5121a232e 8694 attrValue, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 8695 }
pcercuei 0:03b5121a232e 8696 }
pcercuei 0:03b5121a232e 8697 }
pcercuei 0:03b5121a232e 8698 /*
pcercuei 0:03b5121a232e 8699 * Attribute "block".
pcercuei 0:03b5121a232e 8700 */
pcercuei 0:03b5121a232e 8701 attr = xmlSchemaGetPropNode(node, "block");
pcercuei 0:03b5121a232e 8702 if (attr == NULL) {
pcercuei 0:03b5121a232e 8703 /*
pcercuei 0:03b5121a232e 8704 * Apply default "block" values.
pcercuei 0:03b5121a232e 8705 */
pcercuei 0:03b5121a232e 8706 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
pcercuei 0:03b5121a232e 8707 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
pcercuei 0:03b5121a232e 8708 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
pcercuei 0:03b5121a232e 8709 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
pcercuei 0:03b5121a232e 8710 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
pcercuei 0:03b5121a232e 8711 decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
pcercuei 0:03b5121a232e 8712 } else {
pcercuei 0:03b5121a232e 8713 attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 8714 if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
pcercuei 0:03b5121a232e 8715 -1,
pcercuei 0:03b5121a232e 8716 XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
pcercuei 0:03b5121a232e 8717 XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
pcercuei 0:03b5121a232e 8718 XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
pcercuei 0:03b5121a232e 8719 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 8720 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 8721 NULL, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 8722 NULL, "(#all | List of (extension | "
pcercuei 0:03b5121a232e 8723 "restriction | substitution))", attrValue,
pcercuei 0:03b5121a232e 8724 NULL, NULL, NULL);
pcercuei 0:03b5121a232e 8725 }
pcercuei 0:03b5121a232e 8726 }
pcercuei 0:03b5121a232e 8727 if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
pcercuei 0:03b5121a232e 8728 decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
pcercuei 0:03b5121a232e 8729
pcercuei 0:03b5121a232e 8730 attr = xmlSchemaGetPropNode(node, "type");
pcercuei 0:03b5121a232e 8731 if (attr != NULL) {
pcercuei 0:03b5121a232e 8732 xmlSchemaPValAttrNodeQName(ctxt, schema,
pcercuei 0:03b5121a232e 8733 NULL, attr,
pcercuei 0:03b5121a232e 8734 &(decl->namedTypeNs), &(decl->namedType));
pcercuei 0:03b5121a232e 8735 xmlSchemaCheckReference(ctxt, schema, node,
pcercuei 0:03b5121a232e 8736 attr, decl->namedTypeNs);
pcercuei 0:03b5121a232e 8737 }
pcercuei 0:03b5121a232e 8738 decl->value = xmlSchemaGetProp(ctxt, node, "default");
pcercuei 0:03b5121a232e 8739 attr = xmlSchemaGetPropNode(node, "fixed");
pcercuei 0:03b5121a232e 8740 if (attr != NULL) {
pcercuei 0:03b5121a232e 8741 fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 8742 if (decl->value != NULL) {
pcercuei 0:03b5121a232e 8743 /*
pcercuei 0:03b5121a232e 8744 * 3.3.3 : 1
pcercuei 0:03b5121a232e 8745 * default and fixed must not both be present.
pcercuei 0:03b5121a232e 8746 */
pcercuei 0:03b5121a232e 8747 xmlSchemaPMutualExclAttrErr(ctxt,
pcercuei 0:03b5121a232e 8748 XML_SCHEMAP_SRC_ELEMENT_1,
pcercuei 0:03b5121a232e 8749 NULL, attr, "default", "fixed");
pcercuei 0:03b5121a232e 8750 } else {
pcercuei 0:03b5121a232e 8751 decl->flags |= XML_SCHEMAS_ELEM_FIXED;
pcercuei 0:03b5121a232e 8752 decl->value = fixed;
pcercuei 0:03b5121a232e 8753 }
pcercuei 0:03b5121a232e 8754 }
pcercuei 0:03b5121a232e 8755 /*
pcercuei 0:03b5121a232e 8756 * And now for the children...
pcercuei 0:03b5121a232e 8757 */
pcercuei 0:03b5121a232e 8758 if (IS_SCHEMA(child, "complexType")) {
pcercuei 0:03b5121a232e 8759 /*
pcercuei 0:03b5121a232e 8760 * 3.3.3 : 3
pcercuei 0:03b5121a232e 8761 * "type" and either <simpleType> or <complexType> are mutually
pcercuei 0:03b5121a232e 8762 * exclusive
pcercuei 0:03b5121a232e 8763 */
pcercuei 0:03b5121a232e 8764 if (decl->namedType != NULL) {
pcercuei 0:03b5121a232e 8765 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 8766 XML_SCHEMAP_SRC_ELEMENT_3,
pcercuei 0:03b5121a232e 8767 NULL, node, child,
pcercuei 0:03b5121a232e 8768 "The attribute 'type' and the <complexType> child are "
pcercuei 0:03b5121a232e 8769 "mutually exclusive", NULL);
pcercuei 0:03b5121a232e 8770 } else
pcercuei 0:03b5121a232e 8771 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
pcercuei 0:03b5121a232e 8772 child = child->next;
pcercuei 0:03b5121a232e 8773 } else if (IS_SCHEMA(child, "simpleType")) {
pcercuei 0:03b5121a232e 8774 /*
pcercuei 0:03b5121a232e 8775 * 3.3.3 : 3
pcercuei 0:03b5121a232e 8776 * "type" and either <simpleType> or <complexType> are
pcercuei 0:03b5121a232e 8777 * mutually exclusive
pcercuei 0:03b5121a232e 8778 */
pcercuei 0:03b5121a232e 8779 if (decl->namedType != NULL) {
pcercuei 0:03b5121a232e 8780 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 8781 XML_SCHEMAP_SRC_ELEMENT_3,
pcercuei 0:03b5121a232e 8782 NULL, node, child,
pcercuei 0:03b5121a232e 8783 "The attribute 'type' and the <simpleType> child are "
pcercuei 0:03b5121a232e 8784 "mutually exclusive", NULL);
pcercuei 0:03b5121a232e 8785 } else
pcercuei 0:03b5121a232e 8786 WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
pcercuei 0:03b5121a232e 8787 child = child->next;
pcercuei 0:03b5121a232e 8788 }
pcercuei 0:03b5121a232e 8789 while ((IS_SCHEMA(child, "unique")) ||
pcercuei 0:03b5121a232e 8790 (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
pcercuei 0:03b5121a232e 8791 if (IS_SCHEMA(child, "unique")) {
pcercuei 0:03b5121a232e 8792 curIDC = xmlSchemaParseIDC(ctxt, schema, child,
pcercuei 0:03b5121a232e 8793 XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
pcercuei 0:03b5121a232e 8794 } else if (IS_SCHEMA(child, "key")) {
pcercuei 0:03b5121a232e 8795 curIDC = xmlSchemaParseIDC(ctxt, schema, child,
pcercuei 0:03b5121a232e 8796 XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
pcercuei 0:03b5121a232e 8797 } else if (IS_SCHEMA(child, "keyref")) {
pcercuei 0:03b5121a232e 8798 curIDC = xmlSchemaParseIDC(ctxt, schema, child,
pcercuei 0:03b5121a232e 8799 XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
pcercuei 0:03b5121a232e 8800 }
pcercuei 0:03b5121a232e 8801 if (lastIDC != NULL)
pcercuei 0:03b5121a232e 8802 lastIDC->next = curIDC;
pcercuei 0:03b5121a232e 8803 else
pcercuei 0:03b5121a232e 8804 decl->idcs = (void *) curIDC;
pcercuei 0:03b5121a232e 8805 lastIDC = curIDC;
pcercuei 0:03b5121a232e 8806 child = child->next;
pcercuei 0:03b5121a232e 8807 }
pcercuei 0:03b5121a232e 8808 if (child != NULL) {
pcercuei 0:03b5121a232e 8809 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 8810 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 8811 NULL, node, child,
pcercuei 0:03b5121a232e 8812 NULL, "(annotation?, ((simpleType | complexType)?, "
pcercuei 0:03b5121a232e 8813 "(unique | key | keyref)*))");
pcercuei 0:03b5121a232e 8814 }
pcercuei 0:03b5121a232e 8815 decl->annot = annot;
pcercuei 0:03b5121a232e 8816 }
pcercuei 0:03b5121a232e 8817 /*
pcercuei 0:03b5121a232e 8818 * NOTE: Element Declaration Representation OK 4. will be checked at a
pcercuei 0:03b5121a232e 8819 * different layer.
pcercuei 0:03b5121a232e 8820 */
pcercuei 0:03b5121a232e 8821 FREE_AND_NULL(des)
pcercuei 0:03b5121a232e 8822 if (topLevel)
pcercuei 0:03b5121a232e 8823 return ((xmlSchemaBasicItemPtr) decl);
pcercuei 0:03b5121a232e 8824 else {
pcercuei 0:03b5121a232e 8825 particle->children = (xmlSchemaTreeItemPtr) decl;
pcercuei 0:03b5121a232e 8826 return ((xmlSchemaBasicItemPtr) particle);
pcercuei 0:03b5121a232e 8827 }
pcercuei 0:03b5121a232e 8828
pcercuei 0:03b5121a232e 8829 return_null:
pcercuei 0:03b5121a232e 8830 FREE_AND_NULL(des);
pcercuei 0:03b5121a232e 8831 if (annot != NULL) {
pcercuei 0:03b5121a232e 8832 if (particle != NULL)
pcercuei 0:03b5121a232e 8833 particle->annot = NULL;
pcercuei 0:03b5121a232e 8834 if (decl != NULL)
pcercuei 0:03b5121a232e 8835 decl->annot = NULL;
pcercuei 0:03b5121a232e 8836 xmlSchemaFreeAnnot(annot);
pcercuei 0:03b5121a232e 8837 }
pcercuei 0:03b5121a232e 8838 return (NULL);
pcercuei 0:03b5121a232e 8839 }
pcercuei 0:03b5121a232e 8840
pcercuei 0:03b5121a232e 8841 /**
pcercuei 0:03b5121a232e 8842 * xmlSchemaParseUnion:
pcercuei 0:03b5121a232e 8843 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 8844 * @schema: the schema being built
pcercuei 0:03b5121a232e 8845 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 8846 *
pcercuei 0:03b5121a232e 8847 * parse a XML schema Union definition
pcercuei 0:03b5121a232e 8848 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 8849 *
pcercuei 0:03b5121a232e 8850 * Returns -1 in case of internal error, 0 in case of success and a positive
pcercuei 0:03b5121a232e 8851 * error code otherwise.
pcercuei 0:03b5121a232e 8852 */
pcercuei 0:03b5121a232e 8853 static int
pcercuei 0:03b5121a232e 8854 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 8855 xmlNodePtr node)
pcercuei 0:03b5121a232e 8856 {
pcercuei 0:03b5121a232e 8857 xmlSchemaTypePtr type;
pcercuei 0:03b5121a232e 8858 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 8859 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 8860 const xmlChar *cur = NULL;
pcercuei 0:03b5121a232e 8861
pcercuei 0:03b5121a232e 8862 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 8863 return (-1);
pcercuei 0:03b5121a232e 8864 /* Not a component, don't create it. */
pcercuei 0:03b5121a232e 8865 type = ctxt->ctxtType;
pcercuei 0:03b5121a232e 8866 /*
pcercuei 0:03b5121a232e 8867 * Mark the simple type as being of variety "union".
pcercuei 0:03b5121a232e 8868 */
pcercuei 0:03b5121a232e 8869 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
pcercuei 0:03b5121a232e 8870 /*
pcercuei 0:03b5121a232e 8871 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
pcercuei 0:03b5121a232e 8872 * then the `simple ur-type definition`."
pcercuei 0:03b5121a232e 8873 */
pcercuei 0:03b5121a232e 8874 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
pcercuei 0:03b5121a232e 8875 /*
pcercuei 0:03b5121a232e 8876 * Check for illegal attributes.
pcercuei 0:03b5121a232e 8877 */
pcercuei 0:03b5121a232e 8878 attr = node->properties;
pcercuei 0:03b5121a232e 8879 while (attr != NULL) {
pcercuei 0:03b5121a232e 8880 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 8881 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 8882 (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
pcercuei 0:03b5121a232e 8883 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 8884 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 8885 }
pcercuei 0:03b5121a232e 8886 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 8887 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 8888 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 8889 }
pcercuei 0:03b5121a232e 8890 attr = attr->next;
pcercuei 0:03b5121a232e 8891 }
pcercuei 0:03b5121a232e 8892 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 8893 /*
pcercuei 0:03b5121a232e 8894 * Attribute "memberTypes". This is a list of QNames.
pcercuei 0:03b5121a232e 8895 * TODO: Check the value to contain anything.
pcercuei 0:03b5121a232e 8896 */
pcercuei 0:03b5121a232e 8897 attr = xmlSchemaGetPropNode(node, "memberTypes");
pcercuei 0:03b5121a232e 8898 if (attr != NULL) {
pcercuei 0:03b5121a232e 8899 const xmlChar *end;
pcercuei 0:03b5121a232e 8900 xmlChar *tmp;
pcercuei 0:03b5121a232e 8901 const xmlChar *localName, *nsName;
pcercuei 0:03b5121a232e 8902 xmlSchemaTypeLinkPtr link, lastLink = NULL;
pcercuei 0:03b5121a232e 8903 xmlSchemaQNameRefPtr ref;
pcercuei 0:03b5121a232e 8904
pcercuei 0:03b5121a232e 8905 cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 8906 type->base = cur;
pcercuei 0:03b5121a232e 8907 do {
pcercuei 0:03b5121a232e 8908 while (IS_BLANK_CH(*cur))
pcercuei 0:03b5121a232e 8909 cur++;
pcercuei 0:03b5121a232e 8910 end = cur;
pcercuei 0:03b5121a232e 8911 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
pcercuei 0:03b5121a232e 8912 end++;
pcercuei 0:03b5121a232e 8913 if (end == cur)
pcercuei 0:03b5121a232e 8914 break;
pcercuei 0:03b5121a232e 8915 tmp = xmlStrndup(cur, end - cur);
pcercuei 0:03b5121a232e 8916 if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
pcercuei 0:03b5121a232e 8917 NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
pcercuei 0:03b5121a232e 8918 /*
pcercuei 0:03b5121a232e 8919 * Create the member type link.
pcercuei 0:03b5121a232e 8920 */
pcercuei 0:03b5121a232e 8921 link = (xmlSchemaTypeLinkPtr)
pcercuei 0:03b5121a232e 8922 xmlMalloc(sizeof(xmlSchemaTypeLink));
pcercuei 0:03b5121a232e 8923 if (link == NULL) {
pcercuei 0:03b5121a232e 8924 xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
pcercuei 0:03b5121a232e 8925 "allocating a type link", NULL);
pcercuei 0:03b5121a232e 8926 return (-1);
pcercuei 0:03b5121a232e 8927 }
pcercuei 0:03b5121a232e 8928 link->type = NULL;
pcercuei 0:03b5121a232e 8929 link->next = NULL;
pcercuei 0:03b5121a232e 8930 if (lastLink == NULL)
pcercuei 0:03b5121a232e 8931 type->memberTypes = link;
pcercuei 0:03b5121a232e 8932 else
pcercuei 0:03b5121a232e 8933 lastLink->next = link;
pcercuei 0:03b5121a232e 8934 lastLink = link;
pcercuei 0:03b5121a232e 8935 /*
pcercuei 0:03b5121a232e 8936 * Create a reference item.
pcercuei 0:03b5121a232e 8937 */
pcercuei 0:03b5121a232e 8938 ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
pcercuei 0:03b5121a232e 8939 localName, nsName);
pcercuei 0:03b5121a232e 8940 if (ref == NULL) {
pcercuei 0:03b5121a232e 8941 FREE_AND_NULL(tmp)
pcercuei 0:03b5121a232e 8942 return (-1);
pcercuei 0:03b5121a232e 8943 }
pcercuei 0:03b5121a232e 8944 /*
pcercuei 0:03b5121a232e 8945 * Assign the reference to the link, it will be resolved
pcercuei 0:03b5121a232e 8946 * later during fixup of the union simple type.
pcercuei 0:03b5121a232e 8947 */
pcercuei 0:03b5121a232e 8948 link->type = (xmlSchemaTypePtr) ref;
pcercuei 0:03b5121a232e 8949 }
pcercuei 0:03b5121a232e 8950 FREE_AND_NULL(tmp)
pcercuei 0:03b5121a232e 8951 cur = end;
pcercuei 0:03b5121a232e 8952 } while (*cur != 0);
pcercuei 0:03b5121a232e 8953
pcercuei 0:03b5121a232e 8954 }
pcercuei 0:03b5121a232e 8955 /*
pcercuei 0:03b5121a232e 8956 * And now for the children...
pcercuei 0:03b5121a232e 8957 */
pcercuei 0:03b5121a232e 8958 child = node->children;
pcercuei 0:03b5121a232e 8959 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 8960 /*
pcercuei 0:03b5121a232e 8961 * Add the annotation to the simple type ancestor.
pcercuei 0:03b5121a232e 8962 */
pcercuei 0:03b5121a232e 8963 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
pcercuei 0:03b5121a232e 8964 xmlSchemaParseAnnotation(ctxt, child, 1));
pcercuei 0:03b5121a232e 8965 child = child->next;
pcercuei 0:03b5121a232e 8966 }
pcercuei 0:03b5121a232e 8967 if (IS_SCHEMA(child, "simpleType")) {
pcercuei 0:03b5121a232e 8968 xmlSchemaTypePtr subtype, last = NULL;
pcercuei 0:03b5121a232e 8969
pcercuei 0:03b5121a232e 8970 /*
pcercuei 0:03b5121a232e 8971 * Anchor the member types in the "subtypes" field of the
pcercuei 0:03b5121a232e 8972 * simple type.
pcercuei 0:03b5121a232e 8973 */
pcercuei 0:03b5121a232e 8974 while (IS_SCHEMA(child, "simpleType")) {
pcercuei 0:03b5121a232e 8975 subtype = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 8976 xmlSchemaParseSimpleType(ctxt, schema, child, 0);
pcercuei 0:03b5121a232e 8977 if (subtype != NULL) {
pcercuei 0:03b5121a232e 8978 if (last == NULL) {
pcercuei 0:03b5121a232e 8979 type->subtypes = subtype;
pcercuei 0:03b5121a232e 8980 last = subtype;
pcercuei 0:03b5121a232e 8981 } else {
pcercuei 0:03b5121a232e 8982 last->next = subtype;
pcercuei 0:03b5121a232e 8983 last = subtype;
pcercuei 0:03b5121a232e 8984 }
pcercuei 0:03b5121a232e 8985 last->next = NULL;
pcercuei 0:03b5121a232e 8986 }
pcercuei 0:03b5121a232e 8987 child = child->next;
pcercuei 0:03b5121a232e 8988 }
pcercuei 0:03b5121a232e 8989 }
pcercuei 0:03b5121a232e 8990 if (child != NULL) {
pcercuei 0:03b5121a232e 8991 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 8992 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 8993 NULL, node, child, NULL, "(annotation?, simpleType*)");
pcercuei 0:03b5121a232e 8994 }
pcercuei 0:03b5121a232e 8995 if ((attr == NULL) && (type->subtypes == NULL)) {
pcercuei 0:03b5121a232e 8996 /*
pcercuei 0:03b5121a232e 8997 * src-union-memberTypes-or-simpleTypes
pcercuei 0:03b5121a232e 8998 * Either the memberTypes [attribute] of the <union> element must
pcercuei 0:03b5121a232e 8999 * be non-empty or there must be at least one simpleType [child].
pcercuei 0:03b5121a232e 9000 */
pcercuei 0:03b5121a232e 9001 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 9002 XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
pcercuei 0:03b5121a232e 9003 NULL, node,
pcercuei 0:03b5121a232e 9004 "Either the attribute 'memberTypes' or "
pcercuei 0:03b5121a232e 9005 "at least one <simpleType> child must be present", NULL);
pcercuei 0:03b5121a232e 9006 }
pcercuei 0:03b5121a232e 9007 return (0);
pcercuei 0:03b5121a232e 9008 }
pcercuei 0:03b5121a232e 9009
pcercuei 0:03b5121a232e 9010 /**
pcercuei 0:03b5121a232e 9011 * xmlSchemaParseList:
pcercuei 0:03b5121a232e 9012 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 9013 * @schema: the schema being built
pcercuei 0:03b5121a232e 9014 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 9015 *
pcercuei 0:03b5121a232e 9016 * parse a XML schema List definition
pcercuei 0:03b5121a232e 9017 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 9018 *
pcercuei 0:03b5121a232e 9019 * Returns -1 in case of error, 0 if the declaration is improper and
pcercuei 0:03b5121a232e 9020 * 1 in case of success.
pcercuei 0:03b5121a232e 9021 */
pcercuei 0:03b5121a232e 9022 static xmlSchemaTypePtr
pcercuei 0:03b5121a232e 9023 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 9024 xmlNodePtr node)
pcercuei 0:03b5121a232e 9025 {
pcercuei 0:03b5121a232e 9026 xmlSchemaTypePtr type;
pcercuei 0:03b5121a232e 9027 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 9028 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 9029
pcercuei 0:03b5121a232e 9030 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 9031 return (NULL);
pcercuei 0:03b5121a232e 9032 /* Not a component, don't create it. */
pcercuei 0:03b5121a232e 9033 type = ctxt->ctxtType;
pcercuei 0:03b5121a232e 9034 /*
pcercuei 0:03b5121a232e 9035 * Mark the type as being of variety "list".
pcercuei 0:03b5121a232e 9036 */
pcercuei 0:03b5121a232e 9037 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
pcercuei 0:03b5121a232e 9038 /*
pcercuei 0:03b5121a232e 9039 * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
pcercuei 0:03b5121a232e 9040 * then the `simple ur-type definition`."
pcercuei 0:03b5121a232e 9041 */
pcercuei 0:03b5121a232e 9042 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
pcercuei 0:03b5121a232e 9043 /*
pcercuei 0:03b5121a232e 9044 * Check for illegal attributes.
pcercuei 0:03b5121a232e 9045 */
pcercuei 0:03b5121a232e 9046 attr = node->properties;
pcercuei 0:03b5121a232e 9047 while (attr != NULL) {
pcercuei 0:03b5121a232e 9048 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 9049 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 9050 (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
pcercuei 0:03b5121a232e 9051 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 9052 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 9053 }
pcercuei 0:03b5121a232e 9054 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 9055 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 9056 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 9057 }
pcercuei 0:03b5121a232e 9058 attr = attr->next;
pcercuei 0:03b5121a232e 9059 }
pcercuei 0:03b5121a232e 9060
pcercuei 0:03b5121a232e 9061 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 9062
pcercuei 0:03b5121a232e 9063 /*
pcercuei 0:03b5121a232e 9064 * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
pcercuei 0:03b5121a232e 9065 * fields for holding the reference to the itemType.
pcercuei 0:03b5121a232e 9066 *
pcercuei 0:03b5121a232e 9067 * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
pcercuei 0:03b5121a232e 9068 * the "ref" fields.
pcercuei 0:03b5121a232e 9069 */
pcercuei 0:03b5121a232e 9070 xmlSchemaPValAttrQName(ctxt, schema, NULL,
pcercuei 0:03b5121a232e 9071 node, "itemType", &(type->baseNs), &(type->base));
pcercuei 0:03b5121a232e 9072 /*
pcercuei 0:03b5121a232e 9073 * And now for the children...
pcercuei 0:03b5121a232e 9074 */
pcercuei 0:03b5121a232e 9075 child = node->children;
pcercuei 0:03b5121a232e 9076 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 9077 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
pcercuei 0:03b5121a232e 9078 xmlSchemaParseAnnotation(ctxt, child, 1));
pcercuei 0:03b5121a232e 9079 child = child->next;
pcercuei 0:03b5121a232e 9080 }
pcercuei 0:03b5121a232e 9081 if (IS_SCHEMA(child, "simpleType")) {
pcercuei 0:03b5121a232e 9082 /*
pcercuei 0:03b5121a232e 9083 * src-list-itemType-or-simpleType
pcercuei 0:03b5121a232e 9084 * Either the itemType [attribute] or the <simpleType> [child] of
pcercuei 0:03b5121a232e 9085 * the <list> element must be present, but not both.
pcercuei 0:03b5121a232e 9086 */
pcercuei 0:03b5121a232e 9087 if (type->base != NULL) {
pcercuei 0:03b5121a232e 9088 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 9089 XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
pcercuei 0:03b5121a232e 9090 NULL, node,
pcercuei 0:03b5121a232e 9091 "The attribute 'itemType' and the <simpleType> child "
pcercuei 0:03b5121a232e 9092 "are mutually exclusive", NULL);
pcercuei 0:03b5121a232e 9093 } else {
pcercuei 0:03b5121a232e 9094 type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
pcercuei 0:03b5121a232e 9095 }
pcercuei 0:03b5121a232e 9096 child = child->next;
pcercuei 0:03b5121a232e 9097 } else if (type->base == NULL) {
pcercuei 0:03b5121a232e 9098 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 9099 XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
pcercuei 0:03b5121a232e 9100 NULL, node,
pcercuei 0:03b5121a232e 9101 "Either the attribute 'itemType' or the <simpleType> child "
pcercuei 0:03b5121a232e 9102 "must be present", NULL);
pcercuei 0:03b5121a232e 9103 }
pcercuei 0:03b5121a232e 9104 if (child != NULL) {
pcercuei 0:03b5121a232e 9105 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 9106 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 9107 NULL, node, child, NULL, "(annotation?, simpleType?)");
pcercuei 0:03b5121a232e 9108 }
pcercuei 0:03b5121a232e 9109 if ((type->base == NULL) &&
pcercuei 0:03b5121a232e 9110 (type->subtypes == NULL) &&
pcercuei 0:03b5121a232e 9111 (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
pcercuei 0:03b5121a232e 9112 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 9113 XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
pcercuei 0:03b5121a232e 9114 NULL, node,
pcercuei 0:03b5121a232e 9115 "Either the attribute 'itemType' or the <simpleType> child "
pcercuei 0:03b5121a232e 9116 "must be present", NULL);
pcercuei 0:03b5121a232e 9117 }
pcercuei 0:03b5121a232e 9118 return (NULL);
pcercuei 0:03b5121a232e 9119 }
pcercuei 0:03b5121a232e 9120
pcercuei 0:03b5121a232e 9121 /**
pcercuei 0:03b5121a232e 9122 * xmlSchemaParseSimpleType:
pcercuei 0:03b5121a232e 9123 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 9124 * @schema: the schema being built
pcercuei 0:03b5121a232e 9125 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 9126 *
pcercuei 0:03b5121a232e 9127 * parse a XML schema Simple Type definition
pcercuei 0:03b5121a232e 9128 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 9129 *
pcercuei 0:03b5121a232e 9130 * Returns -1 in case of error, 0 if the declaration is improper and
pcercuei 0:03b5121a232e 9131 * 1 in case of success.
pcercuei 0:03b5121a232e 9132 */
pcercuei 0:03b5121a232e 9133 static xmlSchemaTypePtr
pcercuei 0:03b5121a232e 9134 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 9135 xmlNodePtr node, int topLevel)
pcercuei 0:03b5121a232e 9136 {
pcercuei 0:03b5121a232e 9137 xmlSchemaTypePtr type, oldCtxtType;
pcercuei 0:03b5121a232e 9138 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 9139 const xmlChar *attrValue = NULL;
pcercuei 0:03b5121a232e 9140 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 9141 int hasRestriction = 0;
pcercuei 0:03b5121a232e 9142
pcercuei 0:03b5121a232e 9143 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 9144 return (NULL);
pcercuei 0:03b5121a232e 9145
pcercuei 0:03b5121a232e 9146 if (topLevel) {
pcercuei 0:03b5121a232e 9147 attr = xmlSchemaGetPropNode(node, "name");
pcercuei 0:03b5121a232e 9148 if (attr == NULL) {
pcercuei 0:03b5121a232e 9149 xmlSchemaPMissingAttrErr(ctxt,
pcercuei 0:03b5121a232e 9150 XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 9151 NULL, node,
pcercuei 0:03b5121a232e 9152 "name", NULL);
pcercuei 0:03b5121a232e 9153 return (NULL);
pcercuei 0:03b5121a232e 9154 } else {
pcercuei 0:03b5121a232e 9155 if (xmlSchemaPValAttrNode(ctxt,
pcercuei 0:03b5121a232e 9156 NULL, attr,
pcercuei 0:03b5121a232e 9157 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
pcercuei 0:03b5121a232e 9158 return (NULL);
pcercuei 0:03b5121a232e 9159 /*
pcercuei 0:03b5121a232e 9160 * Skip built-in types.
pcercuei 0:03b5121a232e 9161 */
pcercuei 0:03b5121a232e 9162 if (ctxt->isS4S) {
pcercuei 0:03b5121a232e 9163 xmlSchemaTypePtr biType;
pcercuei 0:03b5121a232e 9164
pcercuei 0:03b5121a232e 9165 if (ctxt->isRedefine) {
pcercuei 0:03b5121a232e 9166 /*
pcercuei 0:03b5121a232e 9167 * REDEFINE: Disallow redefinition of built-in-types.
pcercuei 0:03b5121a232e 9168 * TODO: It seems that the spec does not say anything
pcercuei 0:03b5121a232e 9169 * about this case.
pcercuei 0:03b5121a232e 9170 */
pcercuei 0:03b5121a232e 9171 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
pcercuei 0:03b5121a232e 9172 NULL, node,
pcercuei 0:03b5121a232e 9173 "Redefinition of built-in simple types is not "
pcercuei 0:03b5121a232e 9174 "supported", NULL);
pcercuei 0:03b5121a232e 9175 return(NULL);
pcercuei 0:03b5121a232e 9176 }
pcercuei 0:03b5121a232e 9177 biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
pcercuei 0:03b5121a232e 9178 if (biType != NULL)
pcercuei 0:03b5121a232e 9179 return (biType);
pcercuei 0:03b5121a232e 9180 }
pcercuei 0:03b5121a232e 9181 }
pcercuei 0:03b5121a232e 9182 }
pcercuei 0:03b5121a232e 9183 /*
pcercuei 0:03b5121a232e 9184 * TargetNamespace:
pcercuei 0:03b5121a232e 9185 * SPEC "The `actual value` of the targetNamespace [attribute]
pcercuei 0:03b5121a232e 9186 * of the <schema> ancestor element information item if present,
pcercuei 0:03b5121a232e 9187 * otherwise `absent`.
pcercuei 0:03b5121a232e 9188 */
pcercuei 0:03b5121a232e 9189 if (topLevel == 0) {
pcercuei 0:03b5121a232e 9190 #ifdef ENABLE_NAMED_LOCALS
pcercuei 0:03b5121a232e 9191 char buf[40];
pcercuei 0:03b5121a232e 9192 #endif
pcercuei 0:03b5121a232e 9193 /*
pcercuei 0:03b5121a232e 9194 * Parse as local simple type definition.
pcercuei 0:03b5121a232e 9195 */
pcercuei 0:03b5121a232e 9196 #ifdef ENABLE_NAMED_LOCALS
pcercuei 0:03b5121a232e 9197 snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
pcercuei 0:03b5121a232e 9198 type = xmlSchemaAddType(ctxt, schema,
pcercuei 0:03b5121a232e 9199 XML_SCHEMA_TYPE_SIMPLE,
pcercuei 0:03b5121a232e 9200 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
pcercuei 0:03b5121a232e 9201 ctxt->targetNamespace, node, 0);
pcercuei 0:03b5121a232e 9202 #else
pcercuei 0:03b5121a232e 9203 type = xmlSchemaAddType(ctxt, schema,
pcercuei 0:03b5121a232e 9204 XML_SCHEMA_TYPE_SIMPLE,
pcercuei 0:03b5121a232e 9205 NULL, ctxt->targetNamespace, node, 0);
pcercuei 0:03b5121a232e 9206 #endif
pcercuei 0:03b5121a232e 9207 if (type == NULL)
pcercuei 0:03b5121a232e 9208 return (NULL);
pcercuei 0:03b5121a232e 9209 type->type = XML_SCHEMA_TYPE_SIMPLE;
pcercuei 0:03b5121a232e 9210 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
pcercuei 0:03b5121a232e 9211 /*
pcercuei 0:03b5121a232e 9212 * Check for illegal attributes.
pcercuei 0:03b5121a232e 9213 */
pcercuei 0:03b5121a232e 9214 attr = node->properties;
pcercuei 0:03b5121a232e 9215 while (attr != NULL) {
pcercuei 0:03b5121a232e 9216 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 9217 if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
pcercuei 0:03b5121a232e 9218 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 9219 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 9220 }
pcercuei 0:03b5121a232e 9221 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 9222 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 9223 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 9224 }
pcercuei 0:03b5121a232e 9225 attr = attr->next;
pcercuei 0:03b5121a232e 9226 }
pcercuei 0:03b5121a232e 9227 } else {
pcercuei 0:03b5121a232e 9228 /*
pcercuei 0:03b5121a232e 9229 * Parse as global simple type definition.
pcercuei 0:03b5121a232e 9230 *
pcercuei 0:03b5121a232e 9231 * Note that attrValue is the value of the attribute "name" here.
pcercuei 0:03b5121a232e 9232 */
pcercuei 0:03b5121a232e 9233 type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
pcercuei 0:03b5121a232e 9234 attrValue, ctxt->targetNamespace, node, 1);
pcercuei 0:03b5121a232e 9235 if (type == NULL)
pcercuei 0:03b5121a232e 9236 return (NULL);
pcercuei 0:03b5121a232e 9237 type->type = XML_SCHEMA_TYPE_SIMPLE;
pcercuei 0:03b5121a232e 9238 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
pcercuei 0:03b5121a232e 9239 type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
pcercuei 0:03b5121a232e 9240 /*
pcercuei 0:03b5121a232e 9241 * Check for illegal attributes.
pcercuei 0:03b5121a232e 9242 */
pcercuei 0:03b5121a232e 9243 attr = node->properties;
pcercuei 0:03b5121a232e 9244 while (attr != NULL) {
pcercuei 0:03b5121a232e 9245 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 9246 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 9247 (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
pcercuei 0:03b5121a232e 9248 (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
pcercuei 0:03b5121a232e 9249 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 9250 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 9251 }
pcercuei 0:03b5121a232e 9252 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 9253 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 9254 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 9255 }
pcercuei 0:03b5121a232e 9256 attr = attr->next;
pcercuei 0:03b5121a232e 9257 }
pcercuei 0:03b5121a232e 9258 /*
pcercuei 0:03b5121a232e 9259 * Attribute "final".
pcercuei 0:03b5121a232e 9260 */
pcercuei 0:03b5121a232e 9261 attr = xmlSchemaGetPropNode(node, "final");
pcercuei 0:03b5121a232e 9262 if (attr == NULL) {
pcercuei 0:03b5121a232e 9263 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
pcercuei 0:03b5121a232e 9264 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
pcercuei 0:03b5121a232e 9265 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
pcercuei 0:03b5121a232e 9266 type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
pcercuei 0:03b5121a232e 9267 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
pcercuei 0:03b5121a232e 9268 type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
pcercuei 0:03b5121a232e 9269 } else {
pcercuei 0:03b5121a232e 9270 attrValue = xmlSchemaGetProp(ctxt, node, "final");
pcercuei 0:03b5121a232e 9271 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
pcercuei 0:03b5121a232e 9272 -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
pcercuei 0:03b5121a232e 9273 XML_SCHEMAS_TYPE_FINAL_LIST,
pcercuei 0:03b5121a232e 9274 XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
pcercuei 0:03b5121a232e 9275
pcercuei 0:03b5121a232e 9276 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 9277 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 9278 WXS_BASIC_CAST type, (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 9279 NULL, "(#all | List of (list | union | restriction)",
pcercuei 0:03b5121a232e 9280 attrValue, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 9281 }
pcercuei 0:03b5121a232e 9282 }
pcercuei 0:03b5121a232e 9283 }
pcercuei 0:03b5121a232e 9284 type->targetNamespace = ctxt->targetNamespace;
pcercuei 0:03b5121a232e 9285 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 9286 /*
pcercuei 0:03b5121a232e 9287 * And now for the children...
pcercuei 0:03b5121a232e 9288 */
pcercuei 0:03b5121a232e 9289 oldCtxtType = ctxt->ctxtType;
pcercuei 0:03b5121a232e 9290
pcercuei 0:03b5121a232e 9291 ctxt->ctxtType = type;
pcercuei 0:03b5121a232e 9292
pcercuei 0:03b5121a232e 9293 child = node->children;
pcercuei 0:03b5121a232e 9294 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 9295 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
pcercuei 0:03b5121a232e 9296 child = child->next;
pcercuei 0:03b5121a232e 9297 }
pcercuei 0:03b5121a232e 9298 if (child == NULL) {
pcercuei 0:03b5121a232e 9299 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
pcercuei 0:03b5121a232e 9300 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 9301 "(annotation?, (restriction | list | union))");
pcercuei 0:03b5121a232e 9302 } else if (IS_SCHEMA(child, "restriction")) {
pcercuei 0:03b5121a232e 9303 xmlSchemaParseRestriction(ctxt, schema, child,
pcercuei 0:03b5121a232e 9304 XML_SCHEMA_TYPE_SIMPLE);
pcercuei 0:03b5121a232e 9305 hasRestriction = 1;
pcercuei 0:03b5121a232e 9306 child = child->next;
pcercuei 0:03b5121a232e 9307 } else if (IS_SCHEMA(child, "list")) {
pcercuei 0:03b5121a232e 9308 xmlSchemaParseList(ctxt, schema, child);
pcercuei 0:03b5121a232e 9309 child = child->next;
pcercuei 0:03b5121a232e 9310 } else if (IS_SCHEMA(child, "union")) {
pcercuei 0:03b5121a232e 9311 xmlSchemaParseUnion(ctxt, schema, child);
pcercuei 0:03b5121a232e 9312 child = child->next;
pcercuei 0:03b5121a232e 9313 }
pcercuei 0:03b5121a232e 9314 if (child != NULL) {
pcercuei 0:03b5121a232e 9315 xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 9316 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 9317 "(annotation?, (restriction | list | union))");
pcercuei 0:03b5121a232e 9318 }
pcercuei 0:03b5121a232e 9319 /*
pcercuei 0:03b5121a232e 9320 * REDEFINE: SPEC src-redefine (5)
pcercuei 0:03b5121a232e 9321 * "Within the [children], each <simpleType> must have a
pcercuei 0:03b5121a232e 9322 * <restriction> among its [children] ... the `actual value` of whose
pcercuei 0:03b5121a232e 9323 * base [attribute] must be the same as the `actual value` of its own
pcercuei 0:03b5121a232e 9324 * name attribute plus target namespace;"
pcercuei 0:03b5121a232e 9325 */
pcercuei 0:03b5121a232e 9326 if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
pcercuei 0:03b5121a232e 9327 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
pcercuei 0:03b5121a232e 9328 NULL, node, "This is a redefinition, thus the "
pcercuei 0:03b5121a232e 9329 "<simpleType> must have a <restriction> child", NULL);
pcercuei 0:03b5121a232e 9330 }
pcercuei 0:03b5121a232e 9331
pcercuei 0:03b5121a232e 9332 ctxt->ctxtType = oldCtxtType;
pcercuei 0:03b5121a232e 9333 return (type);
pcercuei 0:03b5121a232e 9334 }
pcercuei 0:03b5121a232e 9335
pcercuei 0:03b5121a232e 9336 /**
pcercuei 0:03b5121a232e 9337 * xmlSchemaParseModelGroupDefRef:
pcercuei 0:03b5121a232e 9338 * @ctxt: the parser context
pcercuei 0:03b5121a232e 9339 * @schema: the schema being built
pcercuei 0:03b5121a232e 9340 * @node: the node
pcercuei 0:03b5121a232e 9341 *
pcercuei 0:03b5121a232e 9342 * Parses a reference to a model group definition.
pcercuei 0:03b5121a232e 9343 *
pcercuei 0:03b5121a232e 9344 * We will return a particle component with a qname-component or
pcercuei 0:03b5121a232e 9345 * NULL in case of an error.
pcercuei 0:03b5121a232e 9346 */
pcercuei 0:03b5121a232e 9347 static xmlSchemaTreeItemPtr
pcercuei 0:03b5121a232e 9348 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 9349 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 9350 xmlNodePtr node)
pcercuei 0:03b5121a232e 9351 {
pcercuei 0:03b5121a232e 9352 xmlSchemaParticlePtr item;
pcercuei 0:03b5121a232e 9353 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 9354 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 9355 const xmlChar *ref = NULL, *refNs = NULL;
pcercuei 0:03b5121a232e 9356 int min, max;
pcercuei 0:03b5121a232e 9357
pcercuei 0:03b5121a232e 9358 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 9359 return (NULL);
pcercuei 0:03b5121a232e 9360
pcercuei 0:03b5121a232e 9361 attr = xmlSchemaGetPropNode(node, "ref");
pcercuei 0:03b5121a232e 9362 if (attr == NULL) {
pcercuei 0:03b5121a232e 9363 xmlSchemaPMissingAttrErr(ctxt,
pcercuei 0:03b5121a232e 9364 XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 9365 NULL, node, "ref", NULL);
pcercuei 0:03b5121a232e 9366 return (NULL);
pcercuei 0:03b5121a232e 9367 } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
pcercuei 0:03b5121a232e 9368 attr, &refNs, &ref) != 0) {
pcercuei 0:03b5121a232e 9369 return (NULL);
pcercuei 0:03b5121a232e 9370 }
pcercuei 0:03b5121a232e 9371 xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
pcercuei 0:03b5121a232e 9372 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
pcercuei 0:03b5121a232e 9373 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
pcercuei 0:03b5121a232e 9374 "(xs:nonNegativeInteger | unbounded)");
pcercuei 0:03b5121a232e 9375 /*
pcercuei 0:03b5121a232e 9376 * Check for illegal attributes.
pcercuei 0:03b5121a232e 9377 */
pcercuei 0:03b5121a232e 9378 attr = node->properties;
pcercuei 0:03b5121a232e 9379 while (attr != NULL) {
pcercuei 0:03b5121a232e 9380 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 9381 if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
pcercuei 0:03b5121a232e 9382 (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 9383 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
pcercuei 0:03b5121a232e 9384 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
pcercuei 0:03b5121a232e 9385 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 9386 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 9387 }
pcercuei 0:03b5121a232e 9388 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 9389 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 9390 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 9391 }
pcercuei 0:03b5121a232e 9392 attr = attr->next;
pcercuei 0:03b5121a232e 9393 }
pcercuei 0:03b5121a232e 9394 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 9395 item = xmlSchemaAddParticle(ctxt, node, min, max);
pcercuei 0:03b5121a232e 9396 if (item == NULL)
pcercuei 0:03b5121a232e 9397 return (NULL);
pcercuei 0:03b5121a232e 9398 /*
pcercuei 0:03b5121a232e 9399 * Create a qname-reference and set as the term; it will be substituted
pcercuei 0:03b5121a232e 9400 * for the model group after the reference has been resolved.
pcercuei 0:03b5121a232e 9401 */
pcercuei 0:03b5121a232e 9402 item->children = (xmlSchemaTreeItemPtr)
pcercuei 0:03b5121a232e 9403 xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
pcercuei 0:03b5121a232e 9404 xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
pcercuei 0:03b5121a232e 9405 /*
pcercuei 0:03b5121a232e 9406 * And now for the children...
pcercuei 0:03b5121a232e 9407 */
pcercuei 0:03b5121a232e 9408 child = node->children;
pcercuei 0:03b5121a232e 9409 /* TODO: Is annotation even allowed for a model group reference? */
pcercuei 0:03b5121a232e 9410 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 9411 /*
pcercuei 0:03b5121a232e 9412 * TODO: What to do exactly with the annotation?
pcercuei 0:03b5121a232e 9413 */
pcercuei 0:03b5121a232e 9414 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
pcercuei 0:03b5121a232e 9415 child = child->next;
pcercuei 0:03b5121a232e 9416 }
pcercuei 0:03b5121a232e 9417 if (child != NULL) {
pcercuei 0:03b5121a232e 9418 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 9419 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 9420 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 9421 "(annotation?)");
pcercuei 0:03b5121a232e 9422 }
pcercuei 0:03b5121a232e 9423 /*
pcercuei 0:03b5121a232e 9424 * Corresponds to no component at all if minOccurs==maxOccurs==0.
pcercuei 0:03b5121a232e 9425 */
pcercuei 0:03b5121a232e 9426 if ((min == 0) && (max == 0))
pcercuei 0:03b5121a232e 9427 return (NULL);
pcercuei 0:03b5121a232e 9428
pcercuei 0:03b5121a232e 9429 return ((xmlSchemaTreeItemPtr) item);
pcercuei 0:03b5121a232e 9430 }
pcercuei 0:03b5121a232e 9431
pcercuei 0:03b5121a232e 9432 /**
pcercuei 0:03b5121a232e 9433 * xmlSchemaParseModelGroupDefinition:
pcercuei 0:03b5121a232e 9434 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 9435 * @schema: the schema being built
pcercuei 0:03b5121a232e 9436 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 9437 *
pcercuei 0:03b5121a232e 9438 * Parses a XML schema model group definition.
pcercuei 0:03b5121a232e 9439 *
pcercuei 0:03b5121a232e 9440 * Note that the contraint src-redefine (6.2) can't be applied until
pcercuei 0:03b5121a232e 9441 * references have been resolved. So we will do this at the
pcercuei 0:03b5121a232e 9442 * component fixup level.
pcercuei 0:03b5121a232e 9443 *
pcercuei 0:03b5121a232e 9444 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 9445 *
pcercuei 0:03b5121a232e 9446 * Returns -1 in case of error, 0 if the declaration is improper and
pcercuei 0:03b5121a232e 9447 * 1 in case of success.
pcercuei 0:03b5121a232e 9448 */
pcercuei 0:03b5121a232e 9449 static xmlSchemaModelGroupDefPtr
pcercuei 0:03b5121a232e 9450 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 9451 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 9452 xmlNodePtr node)
pcercuei 0:03b5121a232e 9453 {
pcercuei 0:03b5121a232e 9454 xmlSchemaModelGroupDefPtr item;
pcercuei 0:03b5121a232e 9455 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 9456 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 9457 const xmlChar *name;
pcercuei 0:03b5121a232e 9458
pcercuei 0:03b5121a232e 9459 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 9460 return (NULL);
pcercuei 0:03b5121a232e 9461
pcercuei 0:03b5121a232e 9462 attr = xmlSchemaGetPropNode(node, "name");
pcercuei 0:03b5121a232e 9463 if (attr == NULL) {
pcercuei 0:03b5121a232e 9464 xmlSchemaPMissingAttrErr(ctxt,
pcercuei 0:03b5121a232e 9465 XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 9466 NULL, node,
pcercuei 0:03b5121a232e 9467 "name", NULL);
pcercuei 0:03b5121a232e 9468 return (NULL);
pcercuei 0:03b5121a232e 9469 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
pcercuei 0:03b5121a232e 9470 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
pcercuei 0:03b5121a232e 9471 return (NULL);
pcercuei 0:03b5121a232e 9472 }
pcercuei 0:03b5121a232e 9473 item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
pcercuei 0:03b5121a232e 9474 ctxt->targetNamespace, node);
pcercuei 0:03b5121a232e 9475 if (item == NULL)
pcercuei 0:03b5121a232e 9476 return (NULL);
pcercuei 0:03b5121a232e 9477 /*
pcercuei 0:03b5121a232e 9478 * Check for illegal attributes.
pcercuei 0:03b5121a232e 9479 */
pcercuei 0:03b5121a232e 9480 attr = node->properties;
pcercuei 0:03b5121a232e 9481 while (attr != NULL) {
pcercuei 0:03b5121a232e 9482 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 9483 if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
pcercuei 0:03b5121a232e 9484 (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
pcercuei 0:03b5121a232e 9485 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 9486 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 9487 }
pcercuei 0:03b5121a232e 9488 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 9489 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 9490 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 9491 }
pcercuei 0:03b5121a232e 9492 attr = attr->next;
pcercuei 0:03b5121a232e 9493 }
pcercuei 0:03b5121a232e 9494 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 9495 /*
pcercuei 0:03b5121a232e 9496 * And now for the children...
pcercuei 0:03b5121a232e 9497 */
pcercuei 0:03b5121a232e 9498 child = node->children;
pcercuei 0:03b5121a232e 9499 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 9500 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
pcercuei 0:03b5121a232e 9501 child = child->next;
pcercuei 0:03b5121a232e 9502 }
pcercuei 0:03b5121a232e 9503 if (IS_SCHEMA(child, "all")) {
pcercuei 0:03b5121a232e 9504 item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
pcercuei 0:03b5121a232e 9505 XML_SCHEMA_TYPE_ALL, 0);
pcercuei 0:03b5121a232e 9506 child = child->next;
pcercuei 0:03b5121a232e 9507 } else if (IS_SCHEMA(child, "choice")) {
pcercuei 0:03b5121a232e 9508 item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
pcercuei 0:03b5121a232e 9509 XML_SCHEMA_TYPE_CHOICE, 0);
pcercuei 0:03b5121a232e 9510 child = child->next;
pcercuei 0:03b5121a232e 9511 } else if (IS_SCHEMA(child, "sequence")) {
pcercuei 0:03b5121a232e 9512 item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
pcercuei 0:03b5121a232e 9513 XML_SCHEMA_TYPE_SEQUENCE, 0);
pcercuei 0:03b5121a232e 9514 child = child->next;
pcercuei 0:03b5121a232e 9515 }
pcercuei 0:03b5121a232e 9516
pcercuei 0:03b5121a232e 9517
pcercuei 0:03b5121a232e 9518
pcercuei 0:03b5121a232e 9519 if (child != NULL) {
pcercuei 0:03b5121a232e 9520 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 9521 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 9522 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 9523 "(annotation?, (all | choice | sequence)?)");
pcercuei 0:03b5121a232e 9524 }
pcercuei 0:03b5121a232e 9525 return (item);
pcercuei 0:03b5121a232e 9526 }
pcercuei 0:03b5121a232e 9527
pcercuei 0:03b5121a232e 9528 /**
pcercuei 0:03b5121a232e 9529 * xmlSchemaCleanupDoc:
pcercuei 0:03b5121a232e 9530 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 9531 * @node: the root of the document.
pcercuei 0:03b5121a232e 9532 *
pcercuei 0:03b5121a232e 9533 * removes unwanted nodes in a schemas document tree
pcercuei 0:03b5121a232e 9534 */
pcercuei 0:03b5121a232e 9535 static void
pcercuei 0:03b5121a232e 9536 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
pcercuei 0:03b5121a232e 9537 {
pcercuei 0:03b5121a232e 9538 xmlNodePtr delete, cur;
pcercuei 0:03b5121a232e 9539
pcercuei 0:03b5121a232e 9540 if ((ctxt == NULL) || (root == NULL)) return;
pcercuei 0:03b5121a232e 9541
pcercuei 0:03b5121a232e 9542 /*
pcercuei 0:03b5121a232e 9543 * Remove all the blank text nodes
pcercuei 0:03b5121a232e 9544 */
pcercuei 0:03b5121a232e 9545 delete = NULL;
pcercuei 0:03b5121a232e 9546 cur = root;
pcercuei 0:03b5121a232e 9547 while (cur != NULL) {
pcercuei 0:03b5121a232e 9548 if (delete != NULL) {
pcercuei 0:03b5121a232e 9549 xmlUnlinkNode(delete);
pcercuei 0:03b5121a232e 9550 xmlFreeNode(delete);
pcercuei 0:03b5121a232e 9551 delete = NULL;
pcercuei 0:03b5121a232e 9552 }
pcercuei 0:03b5121a232e 9553 if (cur->type == XML_TEXT_NODE) {
pcercuei 0:03b5121a232e 9554 if (IS_BLANK_NODE(cur)) {
pcercuei 0:03b5121a232e 9555 if (xmlNodeGetSpacePreserve(cur) != 1) {
pcercuei 0:03b5121a232e 9556 delete = cur;
pcercuei 0:03b5121a232e 9557 }
pcercuei 0:03b5121a232e 9558 }
pcercuei 0:03b5121a232e 9559 } else if ((cur->type != XML_ELEMENT_NODE) &&
pcercuei 0:03b5121a232e 9560 (cur->type != XML_CDATA_SECTION_NODE)) {
pcercuei 0:03b5121a232e 9561 delete = cur;
pcercuei 0:03b5121a232e 9562 goto skip_children;
pcercuei 0:03b5121a232e 9563 }
pcercuei 0:03b5121a232e 9564
pcercuei 0:03b5121a232e 9565 /*
pcercuei 0:03b5121a232e 9566 * Skip to next node
pcercuei 0:03b5121a232e 9567 */
pcercuei 0:03b5121a232e 9568 if (cur->children != NULL) {
pcercuei 0:03b5121a232e 9569 if ((cur->children->type != XML_ENTITY_DECL) &&
pcercuei 0:03b5121a232e 9570 (cur->children->type != XML_ENTITY_REF_NODE) &&
pcercuei 0:03b5121a232e 9571 (cur->children->type != XML_ENTITY_NODE)) {
pcercuei 0:03b5121a232e 9572 cur = cur->children;
pcercuei 0:03b5121a232e 9573 continue;
pcercuei 0:03b5121a232e 9574 }
pcercuei 0:03b5121a232e 9575 }
pcercuei 0:03b5121a232e 9576 skip_children:
pcercuei 0:03b5121a232e 9577 if (cur->next != NULL) {
pcercuei 0:03b5121a232e 9578 cur = cur->next;
pcercuei 0:03b5121a232e 9579 continue;
pcercuei 0:03b5121a232e 9580 }
pcercuei 0:03b5121a232e 9581
pcercuei 0:03b5121a232e 9582 do {
pcercuei 0:03b5121a232e 9583 cur = cur->parent;
pcercuei 0:03b5121a232e 9584 if (cur == NULL)
pcercuei 0:03b5121a232e 9585 break;
pcercuei 0:03b5121a232e 9586 if (cur == root) {
pcercuei 0:03b5121a232e 9587 cur = NULL;
pcercuei 0:03b5121a232e 9588 break;
pcercuei 0:03b5121a232e 9589 }
pcercuei 0:03b5121a232e 9590 if (cur->next != NULL) {
pcercuei 0:03b5121a232e 9591 cur = cur->next;
pcercuei 0:03b5121a232e 9592 break;
pcercuei 0:03b5121a232e 9593 }
pcercuei 0:03b5121a232e 9594 } while (cur != NULL);
pcercuei 0:03b5121a232e 9595 }
pcercuei 0:03b5121a232e 9596 if (delete != NULL) {
pcercuei 0:03b5121a232e 9597 xmlUnlinkNode(delete);
pcercuei 0:03b5121a232e 9598 xmlFreeNode(delete);
pcercuei 0:03b5121a232e 9599 delete = NULL;
pcercuei 0:03b5121a232e 9600 }
pcercuei 0:03b5121a232e 9601 }
pcercuei 0:03b5121a232e 9602
pcercuei 0:03b5121a232e 9603
pcercuei 0:03b5121a232e 9604 static void
pcercuei 0:03b5121a232e 9605 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
pcercuei 0:03b5121a232e 9606 {
pcercuei 0:03b5121a232e 9607 if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
pcercuei 0:03b5121a232e 9608 schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
pcercuei 0:03b5121a232e 9609
pcercuei 0:03b5121a232e 9610 if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
pcercuei 0:03b5121a232e 9611 schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
pcercuei 0:03b5121a232e 9612
pcercuei 0:03b5121a232e 9613 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
pcercuei 0:03b5121a232e 9614 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
pcercuei 0:03b5121a232e 9615 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
pcercuei 0:03b5121a232e 9616 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
pcercuei 0:03b5121a232e 9617 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
pcercuei 0:03b5121a232e 9618 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
pcercuei 0:03b5121a232e 9619 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
pcercuei 0:03b5121a232e 9620 schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
pcercuei 0:03b5121a232e 9621
pcercuei 0:03b5121a232e 9622 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
pcercuei 0:03b5121a232e 9623 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
pcercuei 0:03b5121a232e 9624 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
pcercuei 0:03b5121a232e 9625 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
pcercuei 0:03b5121a232e 9626 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
pcercuei 0:03b5121a232e 9627 schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
pcercuei 0:03b5121a232e 9628 }
pcercuei 0:03b5121a232e 9629
pcercuei 0:03b5121a232e 9630 static int
pcercuei 0:03b5121a232e 9631 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 9632 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 9633 xmlNodePtr node)
pcercuei 0:03b5121a232e 9634 {
pcercuei 0:03b5121a232e 9635 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 9636 const xmlChar *val;
pcercuei 0:03b5121a232e 9637 int res = 0, oldErrs = ctxt->nberrors;
pcercuei 0:03b5121a232e 9638
pcercuei 0:03b5121a232e 9639 /*
pcercuei 0:03b5121a232e 9640 * Those flags should be moved to the parser context flags,
pcercuei 0:03b5121a232e 9641 * since they are not visible at the component level. I.e.
pcercuei 0:03b5121a232e 9642 * they are used if processing schema *documents* only.
pcercuei 0:03b5121a232e 9643 */
pcercuei 0:03b5121a232e 9644 res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 9645 HFAILURE;
pcercuei 0:03b5121a232e 9646
pcercuei 0:03b5121a232e 9647 /*
pcercuei 0:03b5121a232e 9648 * Since the version is of type xs:token, we won't bother to
pcercuei 0:03b5121a232e 9649 * check it.
pcercuei 0:03b5121a232e 9650 */
pcercuei 0:03b5121a232e 9651 /* REMOVED:
pcercuei 0:03b5121a232e 9652 attr = xmlSchemaGetPropNode(node, "version");
pcercuei 0:03b5121a232e 9653 if (attr != NULL) {
pcercuei 0:03b5121a232e 9654 res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
pcercuei 0:03b5121a232e 9655 xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
pcercuei 0:03b5121a232e 9656 HFAILURE;
pcercuei 0:03b5121a232e 9657 }
pcercuei 0:03b5121a232e 9658 */
pcercuei 0:03b5121a232e 9659 attr = xmlSchemaGetPropNode(node, "targetNamespace");
pcercuei 0:03b5121a232e 9660 if (attr != NULL) {
pcercuei 0:03b5121a232e 9661 res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
pcercuei 0:03b5121a232e 9662 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
pcercuei 0:03b5121a232e 9663 HFAILURE;
pcercuei 0:03b5121a232e 9664 if (res != 0) {
pcercuei 0:03b5121a232e 9665 ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
pcercuei 0:03b5121a232e 9666 goto exit;
pcercuei 0:03b5121a232e 9667 }
pcercuei 0:03b5121a232e 9668 }
pcercuei 0:03b5121a232e 9669 attr = xmlSchemaGetPropNode(node, "elementFormDefault");
pcercuei 0:03b5121a232e 9670 if (attr != NULL) {
pcercuei 0:03b5121a232e 9671 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 9672 res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
pcercuei 0:03b5121a232e 9673 XML_SCHEMAS_QUALIF_ELEM);
pcercuei 0:03b5121a232e 9674 HFAILURE;
pcercuei 0:03b5121a232e 9675 if (res != 0) {
pcercuei 0:03b5121a232e 9676 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 9677 XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
pcercuei 0:03b5121a232e 9678 NULL, (xmlNodePtr) attr, NULL,
pcercuei 0:03b5121a232e 9679 "(qualified | unqualified)", val, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 9680 }
pcercuei 0:03b5121a232e 9681 }
pcercuei 0:03b5121a232e 9682 attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
pcercuei 0:03b5121a232e 9683 if (attr != NULL) {
pcercuei 0:03b5121a232e 9684 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 9685 res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
pcercuei 0:03b5121a232e 9686 XML_SCHEMAS_QUALIF_ATTR);
pcercuei 0:03b5121a232e 9687 HFAILURE;
pcercuei 0:03b5121a232e 9688 if (res != 0) {
pcercuei 0:03b5121a232e 9689 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 9690 XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
pcercuei 0:03b5121a232e 9691 NULL, (xmlNodePtr) attr, NULL,
pcercuei 0:03b5121a232e 9692 "(qualified | unqualified)", val, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 9693 }
pcercuei 0:03b5121a232e 9694 }
pcercuei 0:03b5121a232e 9695 attr = xmlSchemaGetPropNode(node, "finalDefault");
pcercuei 0:03b5121a232e 9696 if (attr != NULL) {
pcercuei 0:03b5121a232e 9697 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 9698 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
pcercuei 0:03b5121a232e 9699 XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
pcercuei 0:03b5121a232e 9700 XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
pcercuei 0:03b5121a232e 9701 -1,
pcercuei 0:03b5121a232e 9702 XML_SCHEMAS_FINAL_DEFAULT_LIST,
pcercuei 0:03b5121a232e 9703 XML_SCHEMAS_FINAL_DEFAULT_UNION);
pcercuei 0:03b5121a232e 9704 HFAILURE;
pcercuei 0:03b5121a232e 9705 if (res != 0) {
pcercuei 0:03b5121a232e 9706 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 9707 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 9708 NULL, (xmlNodePtr) attr, NULL,
pcercuei 0:03b5121a232e 9709 "(#all | List of (extension | restriction | list | union))",
pcercuei 0:03b5121a232e 9710 val, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 9711 }
pcercuei 0:03b5121a232e 9712 }
pcercuei 0:03b5121a232e 9713 attr = xmlSchemaGetPropNode(node, "blockDefault");
pcercuei 0:03b5121a232e 9714 if (attr != NULL) {
pcercuei 0:03b5121a232e 9715 val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 9716 res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
pcercuei 0:03b5121a232e 9717 XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
pcercuei 0:03b5121a232e 9718 XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
pcercuei 0:03b5121a232e 9719 XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
pcercuei 0:03b5121a232e 9720 HFAILURE;
pcercuei 0:03b5121a232e 9721 if (res != 0) {
pcercuei 0:03b5121a232e 9722 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 9723 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 9724 NULL, (xmlNodePtr) attr, NULL,
pcercuei 0:03b5121a232e 9725 "(#all | List of (extension | restriction | substitution))",
pcercuei 0:03b5121a232e 9726 val, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 9727 }
pcercuei 0:03b5121a232e 9728 }
pcercuei 0:03b5121a232e 9729
pcercuei 0:03b5121a232e 9730 exit:
pcercuei 0:03b5121a232e 9731 if (oldErrs != ctxt->nberrors)
pcercuei 0:03b5121a232e 9732 res = ctxt->err;
pcercuei 0:03b5121a232e 9733 return(res);
pcercuei 0:03b5121a232e 9734 exit_failure:
pcercuei 0:03b5121a232e 9735 return(-1);
pcercuei 0:03b5121a232e 9736 }
pcercuei 0:03b5121a232e 9737
pcercuei 0:03b5121a232e 9738 /**
pcercuei 0:03b5121a232e 9739 * xmlSchemaParseSchemaTopLevel:
pcercuei 0:03b5121a232e 9740 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 9741 * @schema: the schemas
pcercuei 0:03b5121a232e 9742 * @nodes: the list of top level nodes
pcercuei 0:03b5121a232e 9743 *
pcercuei 0:03b5121a232e 9744 * Returns the internal XML Schema structure built from the resource or
pcercuei 0:03b5121a232e 9745 * NULL in case of error
pcercuei 0:03b5121a232e 9746 */
pcercuei 0:03b5121a232e 9747 static int
pcercuei 0:03b5121a232e 9748 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 9749 xmlSchemaPtr schema, xmlNodePtr nodes)
pcercuei 0:03b5121a232e 9750 {
pcercuei 0:03b5121a232e 9751 xmlNodePtr child;
pcercuei 0:03b5121a232e 9752 xmlSchemaAnnotPtr annot;
pcercuei 0:03b5121a232e 9753 int res = 0, oldErrs, tmpOldErrs;
pcercuei 0:03b5121a232e 9754
pcercuei 0:03b5121a232e 9755 if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
pcercuei 0:03b5121a232e 9756 return(-1);
pcercuei 0:03b5121a232e 9757
pcercuei 0:03b5121a232e 9758 oldErrs = ctxt->nberrors;
pcercuei 0:03b5121a232e 9759 child = nodes;
pcercuei 0:03b5121a232e 9760 while ((IS_SCHEMA(child, "include")) ||
pcercuei 0:03b5121a232e 9761 (IS_SCHEMA(child, "import")) ||
pcercuei 0:03b5121a232e 9762 (IS_SCHEMA(child, "redefine")) ||
pcercuei 0:03b5121a232e 9763 (IS_SCHEMA(child, "annotation"))) {
pcercuei 0:03b5121a232e 9764 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 9765 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
pcercuei 0:03b5121a232e 9766 if (schema->annot == NULL)
pcercuei 0:03b5121a232e 9767 schema->annot = annot;
pcercuei 0:03b5121a232e 9768 else
pcercuei 0:03b5121a232e 9769 xmlSchemaFreeAnnot(annot);
pcercuei 0:03b5121a232e 9770 } else if (IS_SCHEMA(child, "import")) {
pcercuei 0:03b5121a232e 9771 tmpOldErrs = ctxt->nberrors;
pcercuei 0:03b5121a232e 9772 res = xmlSchemaParseImport(ctxt, schema, child);
pcercuei 0:03b5121a232e 9773 HFAILURE;
pcercuei 0:03b5121a232e 9774 HSTOP(ctxt);
pcercuei 0:03b5121a232e 9775 if (tmpOldErrs != ctxt->nberrors)
pcercuei 0:03b5121a232e 9776 goto exit;
pcercuei 0:03b5121a232e 9777 } else if (IS_SCHEMA(child, "include")) {
pcercuei 0:03b5121a232e 9778 tmpOldErrs = ctxt->nberrors;
pcercuei 0:03b5121a232e 9779 res = xmlSchemaParseInclude(ctxt, schema, child);
pcercuei 0:03b5121a232e 9780 HFAILURE;
pcercuei 0:03b5121a232e 9781 HSTOP(ctxt);
pcercuei 0:03b5121a232e 9782 if (tmpOldErrs != ctxt->nberrors)
pcercuei 0:03b5121a232e 9783 goto exit;
pcercuei 0:03b5121a232e 9784 } else if (IS_SCHEMA(child, "redefine")) {
pcercuei 0:03b5121a232e 9785 tmpOldErrs = ctxt->nberrors;
pcercuei 0:03b5121a232e 9786 res = xmlSchemaParseRedefine(ctxt, schema, child);
pcercuei 0:03b5121a232e 9787 HFAILURE;
pcercuei 0:03b5121a232e 9788 HSTOP(ctxt);
pcercuei 0:03b5121a232e 9789 if (tmpOldErrs != ctxt->nberrors)
pcercuei 0:03b5121a232e 9790 goto exit;
pcercuei 0:03b5121a232e 9791 }
pcercuei 0:03b5121a232e 9792 child = child->next;
pcercuei 0:03b5121a232e 9793 }
pcercuei 0:03b5121a232e 9794 /*
pcercuei 0:03b5121a232e 9795 * URGENT TODO: Change the functions to return int results.
pcercuei 0:03b5121a232e 9796 * We need especially to catch internal errors.
pcercuei 0:03b5121a232e 9797 */
pcercuei 0:03b5121a232e 9798 while (child != NULL) {
pcercuei 0:03b5121a232e 9799 if (IS_SCHEMA(child, "complexType")) {
pcercuei 0:03b5121a232e 9800 xmlSchemaParseComplexType(ctxt, schema, child, 1);
pcercuei 0:03b5121a232e 9801 child = child->next;
pcercuei 0:03b5121a232e 9802 } else if (IS_SCHEMA(child, "simpleType")) {
pcercuei 0:03b5121a232e 9803 xmlSchemaParseSimpleType(ctxt, schema, child, 1);
pcercuei 0:03b5121a232e 9804 child = child->next;
pcercuei 0:03b5121a232e 9805 } else if (IS_SCHEMA(child, "element")) {
pcercuei 0:03b5121a232e 9806 xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
pcercuei 0:03b5121a232e 9807 child = child->next;
pcercuei 0:03b5121a232e 9808 } else if (IS_SCHEMA(child, "attribute")) {
pcercuei 0:03b5121a232e 9809 xmlSchemaParseGlobalAttribute(ctxt, schema, child);
pcercuei 0:03b5121a232e 9810 child = child->next;
pcercuei 0:03b5121a232e 9811 } else if (IS_SCHEMA(child, "attributeGroup")) {
pcercuei 0:03b5121a232e 9812 xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
pcercuei 0:03b5121a232e 9813 child = child->next;
pcercuei 0:03b5121a232e 9814 } else if (IS_SCHEMA(child, "group")) {
pcercuei 0:03b5121a232e 9815 xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
pcercuei 0:03b5121a232e 9816 child = child->next;
pcercuei 0:03b5121a232e 9817 } else if (IS_SCHEMA(child, "notation")) {
pcercuei 0:03b5121a232e 9818 xmlSchemaParseNotation(ctxt, schema, child);
pcercuei 0:03b5121a232e 9819 child = child->next;
pcercuei 0:03b5121a232e 9820 } else {
pcercuei 0:03b5121a232e 9821 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 9822 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 9823 NULL, child->parent, child,
pcercuei 0:03b5121a232e 9824 NULL, "((include | import | redefine | annotation)*, "
pcercuei 0:03b5121a232e 9825 "(((simpleType | complexType | group | attributeGroup) "
pcercuei 0:03b5121a232e 9826 "| element | attribute | notation), annotation*)*)");
pcercuei 0:03b5121a232e 9827 child = child->next;
pcercuei 0:03b5121a232e 9828 }
pcercuei 0:03b5121a232e 9829 while (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 9830 /*
pcercuei 0:03b5121a232e 9831 * TODO: We should add all annotations.
pcercuei 0:03b5121a232e 9832 */
pcercuei 0:03b5121a232e 9833 annot = xmlSchemaParseAnnotation(ctxt, child, 1);
pcercuei 0:03b5121a232e 9834 if (schema->annot == NULL)
pcercuei 0:03b5121a232e 9835 schema->annot = annot;
pcercuei 0:03b5121a232e 9836 else
pcercuei 0:03b5121a232e 9837 xmlSchemaFreeAnnot(annot);
pcercuei 0:03b5121a232e 9838 child = child->next;
pcercuei 0:03b5121a232e 9839 }
pcercuei 0:03b5121a232e 9840 }
pcercuei 0:03b5121a232e 9841 exit:
pcercuei 0:03b5121a232e 9842 ctxt->ctxtType = NULL;
pcercuei 0:03b5121a232e 9843 if (oldErrs != ctxt->nberrors)
pcercuei 0:03b5121a232e 9844 res = ctxt->err;
pcercuei 0:03b5121a232e 9845 return(res);
pcercuei 0:03b5121a232e 9846 exit_failure:
pcercuei 0:03b5121a232e 9847 return(-1);
pcercuei 0:03b5121a232e 9848 }
pcercuei 0:03b5121a232e 9849
pcercuei 0:03b5121a232e 9850 static xmlSchemaSchemaRelationPtr
pcercuei 0:03b5121a232e 9851 xmlSchemaSchemaRelationCreate(void)
pcercuei 0:03b5121a232e 9852 {
pcercuei 0:03b5121a232e 9853 xmlSchemaSchemaRelationPtr ret;
pcercuei 0:03b5121a232e 9854
pcercuei 0:03b5121a232e 9855 ret = (xmlSchemaSchemaRelationPtr)
pcercuei 0:03b5121a232e 9856 xmlMalloc(sizeof(xmlSchemaSchemaRelation));
pcercuei 0:03b5121a232e 9857 if (ret == NULL) {
pcercuei 0:03b5121a232e 9858 xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
pcercuei 0:03b5121a232e 9859 return(NULL);
pcercuei 0:03b5121a232e 9860 }
pcercuei 0:03b5121a232e 9861 memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
pcercuei 0:03b5121a232e 9862 return(ret);
pcercuei 0:03b5121a232e 9863 }
pcercuei 0:03b5121a232e 9864
pcercuei 0:03b5121a232e 9865 #if 0
pcercuei 0:03b5121a232e 9866 static void
pcercuei 0:03b5121a232e 9867 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
pcercuei 0:03b5121a232e 9868 {
pcercuei 0:03b5121a232e 9869 xmlFree(rel);
pcercuei 0:03b5121a232e 9870 }
pcercuei 0:03b5121a232e 9871 #endif
pcercuei 0:03b5121a232e 9872
pcercuei 0:03b5121a232e 9873 static void
pcercuei 0:03b5121a232e 9874 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
pcercuei 0:03b5121a232e 9875 {
pcercuei 0:03b5121a232e 9876 xmlSchemaRedefPtr prev;
pcercuei 0:03b5121a232e 9877
pcercuei 0:03b5121a232e 9878 while (redef != NULL) {
pcercuei 0:03b5121a232e 9879 prev = redef;
pcercuei 0:03b5121a232e 9880 redef = redef->next;
pcercuei 0:03b5121a232e 9881 xmlFree(prev);
pcercuei 0:03b5121a232e 9882 }
pcercuei 0:03b5121a232e 9883 }
pcercuei 0:03b5121a232e 9884
pcercuei 0:03b5121a232e 9885 static void
pcercuei 0:03b5121a232e 9886 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
pcercuei 0:03b5121a232e 9887 {
pcercuei 0:03b5121a232e 9888 /*
pcercuei 0:03b5121a232e 9889 * After the construction context has been freed, there will be
pcercuei 0:03b5121a232e 9890 * no schema graph available any more. Only the schema buckets
pcercuei 0:03b5121a232e 9891 * will stay alive, which are put into the "schemasImports" and
pcercuei 0:03b5121a232e 9892 * "includes" slots of the xmlSchema.
pcercuei 0:03b5121a232e 9893 */
pcercuei 0:03b5121a232e 9894 if (con->buckets != NULL)
pcercuei 0:03b5121a232e 9895 xmlSchemaItemListFree(con->buckets);
pcercuei 0:03b5121a232e 9896 if (con->pending != NULL)
pcercuei 0:03b5121a232e 9897 xmlSchemaItemListFree(con->pending);
pcercuei 0:03b5121a232e 9898 if (con->substGroups != NULL)
pcercuei 0:03b5121a232e 9899 xmlHashFree(con->substGroups,
pcercuei 0:03b5121a232e 9900 (xmlHashDeallocator) xmlSchemaSubstGroupFree);
pcercuei 0:03b5121a232e 9901 if (con->redefs != NULL)
pcercuei 0:03b5121a232e 9902 xmlSchemaRedefListFree(con->redefs);
pcercuei 0:03b5121a232e 9903 if (con->dict != NULL)
pcercuei 0:03b5121a232e 9904 xmlDictFree(con->dict);
pcercuei 0:03b5121a232e 9905 xmlFree(con);
pcercuei 0:03b5121a232e 9906 }
pcercuei 0:03b5121a232e 9907
pcercuei 0:03b5121a232e 9908 static xmlSchemaConstructionCtxtPtr
pcercuei 0:03b5121a232e 9909 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
pcercuei 0:03b5121a232e 9910 {
pcercuei 0:03b5121a232e 9911 xmlSchemaConstructionCtxtPtr ret;
pcercuei 0:03b5121a232e 9912
pcercuei 0:03b5121a232e 9913 ret = (xmlSchemaConstructionCtxtPtr)
pcercuei 0:03b5121a232e 9914 xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
pcercuei 0:03b5121a232e 9915 if (ret == NULL) {
pcercuei 0:03b5121a232e 9916 xmlSchemaPErrMemory(NULL,
pcercuei 0:03b5121a232e 9917 "allocating schema construction context", NULL);
pcercuei 0:03b5121a232e 9918 return (NULL);
pcercuei 0:03b5121a232e 9919 }
pcercuei 0:03b5121a232e 9920 memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
pcercuei 0:03b5121a232e 9921
pcercuei 0:03b5121a232e 9922 ret->buckets = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 9923 if (ret->buckets == NULL) {
pcercuei 0:03b5121a232e 9924 xmlSchemaPErrMemory(NULL,
pcercuei 0:03b5121a232e 9925 "allocating list of schema buckets", NULL);
pcercuei 0:03b5121a232e 9926 xmlFree(ret);
pcercuei 0:03b5121a232e 9927 return (NULL);
pcercuei 0:03b5121a232e 9928 }
pcercuei 0:03b5121a232e 9929 ret->pending = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 9930 if (ret->pending == NULL) {
pcercuei 0:03b5121a232e 9931 xmlSchemaPErrMemory(NULL,
pcercuei 0:03b5121a232e 9932 "allocating list of pending global components", NULL);
pcercuei 0:03b5121a232e 9933 xmlSchemaConstructionCtxtFree(ret);
pcercuei 0:03b5121a232e 9934 return (NULL);
pcercuei 0:03b5121a232e 9935 }
pcercuei 0:03b5121a232e 9936 ret->dict = dict;
pcercuei 0:03b5121a232e 9937 xmlDictReference(dict);
pcercuei 0:03b5121a232e 9938 return(ret);
pcercuei 0:03b5121a232e 9939 }
pcercuei 0:03b5121a232e 9940
pcercuei 0:03b5121a232e 9941 static xmlSchemaParserCtxtPtr
pcercuei 0:03b5121a232e 9942 xmlSchemaParserCtxtCreate(void)
pcercuei 0:03b5121a232e 9943 {
pcercuei 0:03b5121a232e 9944 xmlSchemaParserCtxtPtr ret;
pcercuei 0:03b5121a232e 9945
pcercuei 0:03b5121a232e 9946 ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
pcercuei 0:03b5121a232e 9947 if (ret == NULL) {
pcercuei 0:03b5121a232e 9948 xmlSchemaPErrMemory(NULL, "allocating schema parser context",
pcercuei 0:03b5121a232e 9949 NULL);
pcercuei 0:03b5121a232e 9950 return (NULL);
pcercuei 0:03b5121a232e 9951 }
pcercuei 0:03b5121a232e 9952 memset(ret, 0, sizeof(xmlSchemaParserCtxt));
pcercuei 0:03b5121a232e 9953 ret->type = XML_SCHEMA_CTXT_PARSER;
pcercuei 0:03b5121a232e 9954 ret->attrProhibs = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 9955 if (ret->attrProhibs == NULL) {
pcercuei 0:03b5121a232e 9956 xmlFree(ret);
pcercuei 0:03b5121a232e 9957 return(NULL);
pcercuei 0:03b5121a232e 9958 }
pcercuei 0:03b5121a232e 9959 return(ret);
pcercuei 0:03b5121a232e 9960 }
pcercuei 0:03b5121a232e 9961
pcercuei 0:03b5121a232e 9962 /**
pcercuei 0:03b5121a232e 9963 * xmlSchemaNewParserCtxtUseDict:
pcercuei 0:03b5121a232e 9964 * @URL: the location of the schema
pcercuei 0:03b5121a232e 9965 * @dict: the dictionary to be used
pcercuei 0:03b5121a232e 9966 *
pcercuei 0:03b5121a232e 9967 * Create an XML Schemas parse context for that file/resource expected
pcercuei 0:03b5121a232e 9968 * to contain an XML Schemas file.
pcercuei 0:03b5121a232e 9969 *
pcercuei 0:03b5121a232e 9970 * Returns the parser context or NULL in case of error
pcercuei 0:03b5121a232e 9971 */
pcercuei 0:03b5121a232e 9972 static xmlSchemaParserCtxtPtr
pcercuei 0:03b5121a232e 9973 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
pcercuei 0:03b5121a232e 9974 {
pcercuei 0:03b5121a232e 9975 xmlSchemaParserCtxtPtr ret;
pcercuei 0:03b5121a232e 9976
pcercuei 0:03b5121a232e 9977 ret = xmlSchemaParserCtxtCreate();
pcercuei 0:03b5121a232e 9978 if (ret == NULL)
pcercuei 0:03b5121a232e 9979 return (NULL);
pcercuei 0:03b5121a232e 9980 ret->dict = dict;
pcercuei 0:03b5121a232e 9981 xmlDictReference(dict);
pcercuei 0:03b5121a232e 9982 if (URL != NULL)
pcercuei 0:03b5121a232e 9983 ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
pcercuei 0:03b5121a232e 9984 return (ret);
pcercuei 0:03b5121a232e 9985 }
pcercuei 0:03b5121a232e 9986
pcercuei 0:03b5121a232e 9987 static int
pcercuei 0:03b5121a232e 9988 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 9989 {
pcercuei 0:03b5121a232e 9990 if (vctxt->pctxt == NULL) {
pcercuei 0:03b5121a232e 9991 if (vctxt->schema != NULL)
pcercuei 0:03b5121a232e 9992 vctxt->pctxt =
pcercuei 0:03b5121a232e 9993 xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
pcercuei 0:03b5121a232e 9994 else
pcercuei 0:03b5121a232e 9995 vctxt->pctxt = xmlSchemaNewParserCtxt("*");
pcercuei 0:03b5121a232e 9996 if (vctxt->pctxt == NULL) {
pcercuei 0:03b5121a232e 9997 VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
pcercuei 0:03b5121a232e 9998 "failed to create a temp. parser context");
pcercuei 0:03b5121a232e 9999 return (-1);
pcercuei 0:03b5121a232e 10000 }
pcercuei 0:03b5121a232e 10001 /* TODO: Pass user data. */
pcercuei 0:03b5121a232e 10002 xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
pcercuei 0:03b5121a232e 10003 vctxt->warning, vctxt->errCtxt);
pcercuei 0:03b5121a232e 10004 xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
pcercuei 0:03b5121a232e 10005 vctxt->errCtxt);
pcercuei 0:03b5121a232e 10006 }
pcercuei 0:03b5121a232e 10007 return (0);
pcercuei 0:03b5121a232e 10008 }
pcercuei 0:03b5121a232e 10009
pcercuei 0:03b5121a232e 10010 /**
pcercuei 0:03b5121a232e 10011 * xmlSchemaGetSchemaBucket:
pcercuei 0:03b5121a232e 10012 * @pctxt: the schema parser context
pcercuei 0:03b5121a232e 10013 * @schemaLocation: the URI of the schema document
pcercuei 0:03b5121a232e 10014 *
pcercuei 0:03b5121a232e 10015 * Returns a schema bucket if it was already parsed.
pcercuei 0:03b5121a232e 10016 *
pcercuei 0:03b5121a232e 10017 * Returns a schema bucket if it was already parsed from
pcercuei 0:03b5121a232e 10018 * @schemaLocation, NULL otherwise.
pcercuei 0:03b5121a232e 10019 */
pcercuei 0:03b5121a232e 10020 static xmlSchemaBucketPtr
pcercuei 0:03b5121a232e 10021 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 10022 const xmlChar *schemaLocation)
pcercuei 0:03b5121a232e 10023 {
pcercuei 0:03b5121a232e 10024 xmlSchemaBucketPtr cur;
pcercuei 0:03b5121a232e 10025 xmlSchemaItemListPtr list;
pcercuei 0:03b5121a232e 10026
pcercuei 0:03b5121a232e 10027 list = pctxt->constructor->buckets;
pcercuei 0:03b5121a232e 10028 if (list->nbItems == 0)
pcercuei 0:03b5121a232e 10029 return(NULL);
pcercuei 0:03b5121a232e 10030 else {
pcercuei 0:03b5121a232e 10031 int i;
pcercuei 0:03b5121a232e 10032 for (i = 0; i < list->nbItems; i++) {
pcercuei 0:03b5121a232e 10033 cur = (xmlSchemaBucketPtr) list->items[i];
pcercuei 0:03b5121a232e 10034 /* Pointer comparison! */
pcercuei 0:03b5121a232e 10035 if (cur->schemaLocation == schemaLocation)
pcercuei 0:03b5121a232e 10036 return(cur);
pcercuei 0:03b5121a232e 10037 }
pcercuei 0:03b5121a232e 10038 }
pcercuei 0:03b5121a232e 10039 return(NULL);
pcercuei 0:03b5121a232e 10040 }
pcercuei 0:03b5121a232e 10041
pcercuei 0:03b5121a232e 10042 static xmlSchemaBucketPtr
pcercuei 0:03b5121a232e 10043 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 10044 const xmlChar *schemaLocation,
pcercuei 0:03b5121a232e 10045 const xmlChar *targetNamespace)
pcercuei 0:03b5121a232e 10046 {
pcercuei 0:03b5121a232e 10047 xmlSchemaBucketPtr cur;
pcercuei 0:03b5121a232e 10048 xmlSchemaItemListPtr list;
pcercuei 0:03b5121a232e 10049
pcercuei 0:03b5121a232e 10050 list = pctxt->constructor->buckets;
pcercuei 0:03b5121a232e 10051 if (list->nbItems == 0)
pcercuei 0:03b5121a232e 10052 return(NULL);
pcercuei 0:03b5121a232e 10053 else {
pcercuei 0:03b5121a232e 10054 int i;
pcercuei 0:03b5121a232e 10055 for (i = 0; i < list->nbItems; i++) {
pcercuei 0:03b5121a232e 10056 cur = (xmlSchemaBucketPtr) list->items[i];
pcercuei 0:03b5121a232e 10057 /* Pointer comparison! */
pcercuei 0:03b5121a232e 10058 if ((cur->origTargetNamespace == NULL) &&
pcercuei 0:03b5121a232e 10059 (cur->schemaLocation == schemaLocation) &&
pcercuei 0:03b5121a232e 10060 (cur->targetNamespace == targetNamespace))
pcercuei 0:03b5121a232e 10061 return(cur);
pcercuei 0:03b5121a232e 10062 }
pcercuei 0:03b5121a232e 10063 }
pcercuei 0:03b5121a232e 10064 return(NULL);
pcercuei 0:03b5121a232e 10065 }
pcercuei 0:03b5121a232e 10066
pcercuei 0:03b5121a232e 10067
pcercuei 0:03b5121a232e 10068 #define IS_BAD_SCHEMA_DOC(b) \
pcercuei 0:03b5121a232e 10069 (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
pcercuei 0:03b5121a232e 10070
pcercuei 0:03b5121a232e 10071 static xmlSchemaBucketPtr
pcercuei 0:03b5121a232e 10072 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 10073 const xmlChar *targetNamespace,
pcercuei 0:03b5121a232e 10074 int imported)
pcercuei 0:03b5121a232e 10075 {
pcercuei 0:03b5121a232e 10076 xmlSchemaBucketPtr cur;
pcercuei 0:03b5121a232e 10077 xmlSchemaItemListPtr list;
pcercuei 0:03b5121a232e 10078
pcercuei 0:03b5121a232e 10079 list = pctxt->constructor->buckets;
pcercuei 0:03b5121a232e 10080 if (list->nbItems == 0)
pcercuei 0:03b5121a232e 10081 return(NULL);
pcercuei 0:03b5121a232e 10082 else {
pcercuei 0:03b5121a232e 10083 int i;
pcercuei 0:03b5121a232e 10084 for (i = 0; i < list->nbItems; i++) {
pcercuei 0:03b5121a232e 10085 cur = (xmlSchemaBucketPtr) list->items[i];
pcercuei 0:03b5121a232e 10086 if ((! IS_BAD_SCHEMA_DOC(cur)) &&
pcercuei 0:03b5121a232e 10087 (cur->origTargetNamespace == targetNamespace) &&
pcercuei 0:03b5121a232e 10088 ((imported && cur->imported) ||
pcercuei 0:03b5121a232e 10089 ((!imported) && (!cur->imported))))
pcercuei 0:03b5121a232e 10090 return(cur);
pcercuei 0:03b5121a232e 10091 }
pcercuei 0:03b5121a232e 10092 }
pcercuei 0:03b5121a232e 10093 return(NULL);
pcercuei 0:03b5121a232e 10094 }
pcercuei 0:03b5121a232e 10095
pcercuei 0:03b5121a232e 10096 static int
pcercuei 0:03b5121a232e 10097 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 10098 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 10099 xmlSchemaBucketPtr bucket)
pcercuei 0:03b5121a232e 10100 {
pcercuei 0:03b5121a232e 10101 int oldFlags;
pcercuei 0:03b5121a232e 10102 xmlDocPtr oldDoc;
pcercuei 0:03b5121a232e 10103 xmlNodePtr node;
pcercuei 0:03b5121a232e 10104 int ret, oldErrs;
pcercuei 0:03b5121a232e 10105 xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
pcercuei 0:03b5121a232e 10106
pcercuei 0:03b5121a232e 10107 /*
pcercuei 0:03b5121a232e 10108 * Save old values; reset the *main* schema.
pcercuei 0:03b5121a232e 10109 * URGENT TODO: This is not good; move the per-document information
pcercuei 0:03b5121a232e 10110 * to the parser. Get rid of passing the main schema to the
pcercuei 0:03b5121a232e 10111 * parsing functions.
pcercuei 0:03b5121a232e 10112 */
pcercuei 0:03b5121a232e 10113 oldFlags = schema->flags;
pcercuei 0:03b5121a232e 10114 oldDoc = schema->doc;
pcercuei 0:03b5121a232e 10115 if (schema->flags != 0)
pcercuei 0:03b5121a232e 10116 xmlSchemaClearSchemaDefaults(schema);
pcercuei 0:03b5121a232e 10117 schema->doc = bucket->doc;
pcercuei 0:03b5121a232e 10118 pctxt->schema = schema;
pcercuei 0:03b5121a232e 10119 /*
pcercuei 0:03b5121a232e 10120 * Keep the current target namespace on the parser *not* on the
pcercuei 0:03b5121a232e 10121 * main schema.
pcercuei 0:03b5121a232e 10122 */
pcercuei 0:03b5121a232e 10123 pctxt->targetNamespace = bucket->targetNamespace;
pcercuei 0:03b5121a232e 10124 WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
pcercuei 0:03b5121a232e 10125
pcercuei 0:03b5121a232e 10126 if ((bucket->targetNamespace != NULL) &&
pcercuei 0:03b5121a232e 10127 xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 10128 /*
pcercuei 0:03b5121a232e 10129 * We are parsing the schema for schemas!
pcercuei 0:03b5121a232e 10130 */
pcercuei 0:03b5121a232e 10131 pctxt->isS4S = 1;
pcercuei 0:03b5121a232e 10132 }
pcercuei 0:03b5121a232e 10133 /* Mark it as parsed, even if parsing fails. */
pcercuei 0:03b5121a232e 10134 bucket->parsed++;
pcercuei 0:03b5121a232e 10135 /* Compile the schema doc. */
pcercuei 0:03b5121a232e 10136 node = xmlDocGetRootElement(bucket->doc);
pcercuei 0:03b5121a232e 10137 ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
pcercuei 0:03b5121a232e 10138 if (ret != 0)
pcercuei 0:03b5121a232e 10139 goto exit;
pcercuei 0:03b5121a232e 10140 /* An empty schema; just get out. */
pcercuei 0:03b5121a232e 10141 if (node->children == NULL)
pcercuei 0:03b5121a232e 10142 goto exit;
pcercuei 0:03b5121a232e 10143 oldErrs = pctxt->nberrors;
pcercuei 0:03b5121a232e 10144 ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
pcercuei 0:03b5121a232e 10145 if (ret != 0)
pcercuei 0:03b5121a232e 10146 goto exit;
pcercuei 0:03b5121a232e 10147 /*
pcercuei 0:03b5121a232e 10148 * TODO: Not nice, but I'm not 100% sure we will get always an error
pcercuei 0:03b5121a232e 10149 * as a result of the obove functions; so better rely on pctxt->err
pcercuei 0:03b5121a232e 10150 * as well.
pcercuei 0:03b5121a232e 10151 */
pcercuei 0:03b5121a232e 10152 if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
pcercuei 0:03b5121a232e 10153 ret = pctxt->err;
pcercuei 0:03b5121a232e 10154 goto exit;
pcercuei 0:03b5121a232e 10155 }
pcercuei 0:03b5121a232e 10156
pcercuei 0:03b5121a232e 10157 exit:
pcercuei 0:03b5121a232e 10158 WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
pcercuei 0:03b5121a232e 10159 /* Restore schema values. */
pcercuei 0:03b5121a232e 10160 schema->doc = oldDoc;
pcercuei 0:03b5121a232e 10161 schema->flags = oldFlags;
pcercuei 0:03b5121a232e 10162 return(ret);
pcercuei 0:03b5121a232e 10163 }
pcercuei 0:03b5121a232e 10164
pcercuei 0:03b5121a232e 10165 static int
pcercuei 0:03b5121a232e 10166 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 10167 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 10168 xmlSchemaBucketPtr bucket)
pcercuei 0:03b5121a232e 10169 {
pcercuei 0:03b5121a232e 10170 xmlSchemaParserCtxtPtr newpctxt;
pcercuei 0:03b5121a232e 10171 int res = 0;
pcercuei 0:03b5121a232e 10172
pcercuei 0:03b5121a232e 10173 if (bucket == NULL)
pcercuei 0:03b5121a232e 10174 return(0);
pcercuei 0:03b5121a232e 10175 if (bucket->parsed) {
pcercuei 0:03b5121a232e 10176 PERROR_INT("xmlSchemaParseNewDoc",
pcercuei 0:03b5121a232e 10177 "reparsing a schema doc");
pcercuei 0:03b5121a232e 10178 return(-1);
pcercuei 0:03b5121a232e 10179 }
pcercuei 0:03b5121a232e 10180 if (bucket->doc == NULL) {
pcercuei 0:03b5121a232e 10181 PERROR_INT("xmlSchemaParseNewDoc",
pcercuei 0:03b5121a232e 10182 "parsing a schema doc, but there's no doc");
pcercuei 0:03b5121a232e 10183 return(-1);
pcercuei 0:03b5121a232e 10184 }
pcercuei 0:03b5121a232e 10185 if (pctxt->constructor == NULL) {
pcercuei 0:03b5121a232e 10186 PERROR_INT("xmlSchemaParseNewDoc",
pcercuei 0:03b5121a232e 10187 "no constructor");
pcercuei 0:03b5121a232e 10188 return(-1);
pcercuei 0:03b5121a232e 10189 }
pcercuei 0:03b5121a232e 10190 /* Create and init the temporary parser context. */
pcercuei 0:03b5121a232e 10191 newpctxt = xmlSchemaNewParserCtxtUseDict(
pcercuei 0:03b5121a232e 10192 (const char *) bucket->schemaLocation, pctxt->dict);
pcercuei 0:03b5121a232e 10193 if (newpctxt == NULL)
pcercuei 0:03b5121a232e 10194 return(-1);
pcercuei 0:03b5121a232e 10195 newpctxt->constructor = pctxt->constructor;
pcercuei 0:03b5121a232e 10196 /*
pcercuei 0:03b5121a232e 10197 * TODO: Can we avoid that the parser knows about the main schema?
pcercuei 0:03b5121a232e 10198 * It would be better if he knows about the current schema bucket
pcercuei 0:03b5121a232e 10199 * only.
pcercuei 0:03b5121a232e 10200 */
pcercuei 0:03b5121a232e 10201 newpctxt->schema = schema;
pcercuei 0:03b5121a232e 10202 xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
pcercuei 0:03b5121a232e 10203 pctxt->errCtxt);
pcercuei 0:03b5121a232e 10204 xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
pcercuei 0:03b5121a232e 10205 pctxt->errCtxt);
pcercuei 0:03b5121a232e 10206 newpctxt->counter = pctxt->counter;
pcercuei 0:03b5121a232e 10207
pcercuei 0:03b5121a232e 10208
pcercuei 0:03b5121a232e 10209 res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
pcercuei 0:03b5121a232e 10210
pcercuei 0:03b5121a232e 10211 /* Channel back errors and cleanup the temporary parser context. */
pcercuei 0:03b5121a232e 10212 if (res != 0)
pcercuei 0:03b5121a232e 10213 pctxt->err = res;
pcercuei 0:03b5121a232e 10214 pctxt->nberrors += newpctxt->nberrors;
pcercuei 0:03b5121a232e 10215 pctxt->counter = newpctxt->counter;
pcercuei 0:03b5121a232e 10216 newpctxt->constructor = NULL;
pcercuei 0:03b5121a232e 10217 /* Free the parser context. */
pcercuei 0:03b5121a232e 10218 xmlSchemaFreeParserCtxt(newpctxt);
pcercuei 0:03b5121a232e 10219 return(res);
pcercuei 0:03b5121a232e 10220 }
pcercuei 0:03b5121a232e 10221
pcercuei 0:03b5121a232e 10222 static void
pcercuei 0:03b5121a232e 10223 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
pcercuei 0:03b5121a232e 10224 xmlSchemaSchemaRelationPtr rel)
pcercuei 0:03b5121a232e 10225 {
pcercuei 0:03b5121a232e 10226 xmlSchemaSchemaRelationPtr cur = bucket->relations;
pcercuei 0:03b5121a232e 10227
pcercuei 0:03b5121a232e 10228 if (cur == NULL) {
pcercuei 0:03b5121a232e 10229 bucket->relations = rel;
pcercuei 0:03b5121a232e 10230 return;
pcercuei 0:03b5121a232e 10231 }
pcercuei 0:03b5121a232e 10232 while (cur->next != NULL)
pcercuei 0:03b5121a232e 10233 cur = cur->next;
pcercuei 0:03b5121a232e 10234 cur->next = rel;
pcercuei 0:03b5121a232e 10235 }
pcercuei 0:03b5121a232e 10236
pcercuei 0:03b5121a232e 10237
pcercuei 0:03b5121a232e 10238 static const xmlChar *
pcercuei 0:03b5121a232e 10239 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
pcercuei 0:03b5121a232e 10240 xmlNodePtr ctxtNode)
pcercuei 0:03b5121a232e 10241 {
pcercuei 0:03b5121a232e 10242 /*
pcercuei 0:03b5121a232e 10243 * Build an absolue location URI.
pcercuei 0:03b5121a232e 10244 */
pcercuei 0:03b5121a232e 10245 if (location != NULL) {
pcercuei 0:03b5121a232e 10246 if (ctxtNode == NULL)
pcercuei 0:03b5121a232e 10247 return(location);
pcercuei 0:03b5121a232e 10248 else {
pcercuei 0:03b5121a232e 10249 xmlChar *base, *URI;
pcercuei 0:03b5121a232e 10250 const xmlChar *ret = NULL;
pcercuei 0:03b5121a232e 10251
pcercuei 0:03b5121a232e 10252 base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
pcercuei 0:03b5121a232e 10253 if (base == NULL) {
pcercuei 0:03b5121a232e 10254 URI = xmlBuildURI(location, ctxtNode->doc->URL);
pcercuei 0:03b5121a232e 10255 } else {
pcercuei 0:03b5121a232e 10256 URI = xmlBuildURI(location, base);
pcercuei 0:03b5121a232e 10257 xmlFree(base);
pcercuei 0:03b5121a232e 10258 }
pcercuei 0:03b5121a232e 10259 if (URI != NULL) {
pcercuei 0:03b5121a232e 10260 ret = xmlDictLookup(dict, URI, -1);
pcercuei 0:03b5121a232e 10261 xmlFree(URI);
pcercuei 0:03b5121a232e 10262 return(ret);
pcercuei 0:03b5121a232e 10263 }
pcercuei 0:03b5121a232e 10264 }
pcercuei 0:03b5121a232e 10265 }
pcercuei 0:03b5121a232e 10266 return(NULL);
pcercuei 0:03b5121a232e 10267 }
pcercuei 0:03b5121a232e 10268
pcercuei 0:03b5121a232e 10269
pcercuei 0:03b5121a232e 10270
pcercuei 0:03b5121a232e 10271 /**
pcercuei 0:03b5121a232e 10272 * xmlSchemaAddSchemaDoc:
pcercuei 0:03b5121a232e 10273 * @pctxt: a schema validation context
pcercuei 0:03b5121a232e 10274 * @schema: the schema being built
pcercuei 0:03b5121a232e 10275 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 10276 *
pcercuei 0:03b5121a232e 10277 * Parse an included (and to-be-redefined) XML schema document.
pcercuei 0:03b5121a232e 10278 *
pcercuei 0:03b5121a232e 10279 * Returns 0 on success, a positive error code on errors and
pcercuei 0:03b5121a232e 10280 * -1 in case of an internal or API error.
pcercuei 0:03b5121a232e 10281 */
pcercuei 0:03b5121a232e 10282
pcercuei 0:03b5121a232e 10283 static int
pcercuei 0:03b5121a232e 10284 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 10285 int type, /* import or include or redefine */
pcercuei 0:03b5121a232e 10286 const xmlChar *schemaLocation,
pcercuei 0:03b5121a232e 10287 xmlDocPtr schemaDoc,
pcercuei 0:03b5121a232e 10288 const char *schemaBuffer,
pcercuei 0:03b5121a232e 10289 int schemaBufferLen,
pcercuei 0:03b5121a232e 10290 xmlNodePtr invokingNode,
pcercuei 0:03b5121a232e 10291 const xmlChar *sourceTargetNamespace,
pcercuei 0:03b5121a232e 10292 const xmlChar *importNamespace,
pcercuei 0:03b5121a232e 10293 xmlSchemaBucketPtr *bucket)
pcercuei 0:03b5121a232e 10294 {
pcercuei 0:03b5121a232e 10295 const xmlChar *targetNamespace = NULL;
pcercuei 0:03b5121a232e 10296 xmlSchemaSchemaRelationPtr relation = NULL;
pcercuei 0:03b5121a232e 10297 xmlDocPtr doc = NULL;
pcercuei 0:03b5121a232e 10298 int res = 0, err = 0, located = 0, preserveDoc = 0;
pcercuei 0:03b5121a232e 10299 xmlSchemaBucketPtr bkt = NULL;
pcercuei 0:03b5121a232e 10300
pcercuei 0:03b5121a232e 10301 if (bucket != NULL)
pcercuei 0:03b5121a232e 10302 *bucket = NULL;
pcercuei 0:03b5121a232e 10303
pcercuei 0:03b5121a232e 10304 switch (type) {
pcercuei 0:03b5121a232e 10305 case XML_SCHEMA_SCHEMA_IMPORT:
pcercuei 0:03b5121a232e 10306 case XML_SCHEMA_SCHEMA_MAIN:
pcercuei 0:03b5121a232e 10307 err = XML_SCHEMAP_SRC_IMPORT;
pcercuei 0:03b5121a232e 10308 break;
pcercuei 0:03b5121a232e 10309 case XML_SCHEMA_SCHEMA_INCLUDE:
pcercuei 0:03b5121a232e 10310 err = XML_SCHEMAP_SRC_INCLUDE;
pcercuei 0:03b5121a232e 10311 break;
pcercuei 0:03b5121a232e 10312 case XML_SCHEMA_SCHEMA_REDEFINE:
pcercuei 0:03b5121a232e 10313 err = XML_SCHEMAP_SRC_REDEFINE;
pcercuei 0:03b5121a232e 10314 break;
pcercuei 0:03b5121a232e 10315 }
pcercuei 0:03b5121a232e 10316
pcercuei 0:03b5121a232e 10317
pcercuei 0:03b5121a232e 10318 /* Special handling for the main schema:
pcercuei 0:03b5121a232e 10319 * skip the location and relation logic and just parse the doc.
pcercuei 0:03b5121a232e 10320 * We need just a bucket to be returned in this case.
pcercuei 0:03b5121a232e 10321 */
pcercuei 0:03b5121a232e 10322 if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
pcercuei 0:03b5121a232e 10323 goto doc_load;
pcercuei 0:03b5121a232e 10324
pcercuei 0:03b5121a232e 10325 /* Note that we expect the location to be an absulute URI. */
pcercuei 0:03b5121a232e 10326 if (schemaLocation != NULL) {
pcercuei 0:03b5121a232e 10327 bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
pcercuei 0:03b5121a232e 10328 if ((bkt != NULL) &&
pcercuei 0:03b5121a232e 10329 (pctxt->constructor->bucket == bkt)) {
pcercuei 0:03b5121a232e 10330 /* Report self-imports/inclusions/redefinitions. */
pcercuei 0:03b5121a232e 10331
pcercuei 0:03b5121a232e 10332 xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
pcercuei 0:03b5121a232e 10333 invokingNode, NULL,
pcercuei 0:03b5121a232e 10334 "The schema must not import/include/redefine itself",
pcercuei 0:03b5121a232e 10335 NULL, NULL);
pcercuei 0:03b5121a232e 10336 goto exit;
pcercuei 0:03b5121a232e 10337 }
pcercuei 0:03b5121a232e 10338 }
pcercuei 0:03b5121a232e 10339 /*
pcercuei 0:03b5121a232e 10340 * Create a relation for the graph of schemas.
pcercuei 0:03b5121a232e 10341 */
pcercuei 0:03b5121a232e 10342 relation = xmlSchemaSchemaRelationCreate();
pcercuei 0:03b5121a232e 10343 if (relation == NULL)
pcercuei 0:03b5121a232e 10344 return(-1);
pcercuei 0:03b5121a232e 10345 xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
pcercuei 0:03b5121a232e 10346 relation);
pcercuei 0:03b5121a232e 10347 relation->type = type;
pcercuei 0:03b5121a232e 10348
pcercuei 0:03b5121a232e 10349 /*
pcercuei 0:03b5121a232e 10350 * Save the namespace import information.
pcercuei 0:03b5121a232e 10351 */
pcercuei 0:03b5121a232e 10352 if (WXS_IS_BUCKET_IMPMAIN(type)) {
pcercuei 0:03b5121a232e 10353 relation->importNamespace = importNamespace;
pcercuei 0:03b5121a232e 10354 if (schemaLocation == NULL) {
pcercuei 0:03b5121a232e 10355 /*
pcercuei 0:03b5121a232e 10356 * No location; this is just an import of the namespace.
pcercuei 0:03b5121a232e 10357 * Note that we don't assign a bucket to the relation
pcercuei 0:03b5121a232e 10358 * in this case.
pcercuei 0:03b5121a232e 10359 */
pcercuei 0:03b5121a232e 10360 goto exit;
pcercuei 0:03b5121a232e 10361 }
pcercuei 0:03b5121a232e 10362 targetNamespace = importNamespace;
pcercuei 0:03b5121a232e 10363 }
pcercuei 0:03b5121a232e 10364
pcercuei 0:03b5121a232e 10365 /* Did we already fetch the doc? */
pcercuei 0:03b5121a232e 10366 if (bkt != NULL) {
pcercuei 0:03b5121a232e 10367 if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
pcercuei 0:03b5121a232e 10368 /*
pcercuei 0:03b5121a232e 10369 * We included/redefined and then try to import a schema,
pcercuei 0:03b5121a232e 10370 * but the new location provided for import was different.
pcercuei 0:03b5121a232e 10371 */
pcercuei 0:03b5121a232e 10372 if (schemaLocation == NULL)
pcercuei 0:03b5121a232e 10373 schemaLocation = BAD_CAST "in_memory_buffer";
pcercuei 0:03b5121a232e 10374 if (!xmlStrEqual(schemaLocation,
pcercuei 0:03b5121a232e 10375 bkt->schemaLocation)) {
pcercuei 0:03b5121a232e 10376 xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
pcercuei 0:03b5121a232e 10377 invokingNode, NULL,
pcercuei 0:03b5121a232e 10378 "The schema document '%s' cannot be imported, since "
pcercuei 0:03b5121a232e 10379 "it was already included or redefined",
pcercuei 0:03b5121a232e 10380 schemaLocation, NULL);
pcercuei 0:03b5121a232e 10381 goto exit;
pcercuei 0:03b5121a232e 10382 }
pcercuei 0:03b5121a232e 10383 } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
pcercuei 0:03b5121a232e 10384 /*
pcercuei 0:03b5121a232e 10385 * We imported and then try to include/redefine a schema,
pcercuei 0:03b5121a232e 10386 * but the new location provided for the include/redefine
pcercuei 0:03b5121a232e 10387 * was different.
pcercuei 0:03b5121a232e 10388 */
pcercuei 0:03b5121a232e 10389 if (schemaLocation == NULL)
pcercuei 0:03b5121a232e 10390 schemaLocation = BAD_CAST "in_memory_buffer";
pcercuei 0:03b5121a232e 10391 if (!xmlStrEqual(schemaLocation,
pcercuei 0:03b5121a232e 10392 bkt->schemaLocation)) {
pcercuei 0:03b5121a232e 10393 xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
pcercuei 0:03b5121a232e 10394 invokingNode, NULL,
pcercuei 0:03b5121a232e 10395 "The schema document '%s' cannot be included or "
pcercuei 0:03b5121a232e 10396 "redefined, since it was already imported",
pcercuei 0:03b5121a232e 10397 schemaLocation, NULL);
pcercuei 0:03b5121a232e 10398 goto exit;
pcercuei 0:03b5121a232e 10399 }
pcercuei 0:03b5121a232e 10400 }
pcercuei 0:03b5121a232e 10401 }
pcercuei 0:03b5121a232e 10402
pcercuei 0:03b5121a232e 10403 if (WXS_IS_BUCKET_IMPMAIN(type)) {
pcercuei 0:03b5121a232e 10404 /*
pcercuei 0:03b5121a232e 10405 * Given that the schemaLocation [attribute] is only a hint, it is open
pcercuei 0:03b5121a232e 10406 * to applications to ignore all but the first <import> for a given
pcercuei 0:03b5121a232e 10407 * namespace, regardless of the `actual value` of schemaLocation, but
pcercuei 0:03b5121a232e 10408 * such a strategy risks missing useful information when new
pcercuei 0:03b5121a232e 10409 * schemaLocations are offered.
pcercuei 0:03b5121a232e 10410 *
pcercuei 0:03b5121a232e 10411 * We will use the first <import> that comes with a location.
pcercuei 0:03b5121a232e 10412 * Further <import>s *with* a location, will result in an error.
pcercuei 0:03b5121a232e 10413 * TODO: Better would be to just report a warning here, but
pcercuei 0:03b5121a232e 10414 * we'll try it this way until someone complains.
pcercuei 0:03b5121a232e 10415 *
pcercuei 0:03b5121a232e 10416 * Schema Document Location Strategy:
pcercuei 0:03b5121a232e 10417 * 3 Based on the namespace name, identify an existing schema document,
pcercuei 0:03b5121a232e 10418 * either as a resource which is an XML document or a <schema> element
pcercuei 0:03b5121a232e 10419 * information item, in some local schema repository;
pcercuei 0:03b5121a232e 10420 * 5 Attempt to resolve the namespace name to locate such a resource.
pcercuei 0:03b5121a232e 10421 *
pcercuei 0:03b5121a232e 10422 * NOTE: (3) and (5) are not supported.
pcercuei 0:03b5121a232e 10423 */
pcercuei 0:03b5121a232e 10424 if (bkt != NULL) {
pcercuei 0:03b5121a232e 10425 relation->bucket = bkt;
pcercuei 0:03b5121a232e 10426 goto exit;
pcercuei 0:03b5121a232e 10427 }
pcercuei 0:03b5121a232e 10428 bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
pcercuei 0:03b5121a232e 10429 importNamespace, 1);
pcercuei 0:03b5121a232e 10430
pcercuei 0:03b5121a232e 10431 if (bkt != NULL) {
pcercuei 0:03b5121a232e 10432 relation->bucket = bkt;
pcercuei 0:03b5121a232e 10433 if (bkt->schemaLocation == NULL) {
pcercuei 0:03b5121a232e 10434 /* First given location of the schema; load the doc. */
pcercuei 0:03b5121a232e 10435 bkt->schemaLocation = schemaLocation;
pcercuei 0:03b5121a232e 10436 } else {
pcercuei 0:03b5121a232e 10437 if (!xmlStrEqual(schemaLocation,
pcercuei 0:03b5121a232e 10438 bkt->schemaLocation)) {
pcercuei 0:03b5121a232e 10439 /*
pcercuei 0:03b5121a232e 10440 * Additional location given; just skip it.
pcercuei 0:03b5121a232e 10441 * URGENT TODO: We should report a warning here.
pcercuei 0:03b5121a232e 10442 * res = XML_SCHEMAP_SRC_IMPORT;
pcercuei 0:03b5121a232e 10443 */
pcercuei 0:03b5121a232e 10444 if (schemaLocation == NULL)
pcercuei 0:03b5121a232e 10445 schemaLocation = BAD_CAST "in_memory_buffer";
pcercuei 0:03b5121a232e 10446
pcercuei 0:03b5121a232e 10447 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 10448 XML_SCHEMAP_WARN_SKIP_SCHEMA,
pcercuei 0:03b5121a232e 10449 invokingNode, NULL,
pcercuei 0:03b5121a232e 10450 "Skipping import of schema located at '%s' for the "
pcercuei 0:03b5121a232e 10451 "namespace '%s', since this namespace was already "
pcercuei 0:03b5121a232e 10452 "imported with the schema located at '%s'",
pcercuei 0:03b5121a232e 10453 schemaLocation, importNamespace, bkt->schemaLocation);
pcercuei 0:03b5121a232e 10454 }
pcercuei 0:03b5121a232e 10455 goto exit;
pcercuei 0:03b5121a232e 10456 }
pcercuei 0:03b5121a232e 10457 }
pcercuei 0:03b5121a232e 10458 /*
pcercuei 0:03b5121a232e 10459 * No bucket + first location: load the doc and create a
pcercuei 0:03b5121a232e 10460 * bucket.
pcercuei 0:03b5121a232e 10461 */
pcercuei 0:03b5121a232e 10462 } else {
pcercuei 0:03b5121a232e 10463 /* <include> and <redefine> */
pcercuei 0:03b5121a232e 10464 if (bkt != NULL) {
pcercuei 0:03b5121a232e 10465
pcercuei 0:03b5121a232e 10466 if ((bkt->origTargetNamespace == NULL) &&
pcercuei 0:03b5121a232e 10467 (bkt->targetNamespace != sourceTargetNamespace)) {
pcercuei 0:03b5121a232e 10468 xmlSchemaBucketPtr chamel;
pcercuei 0:03b5121a232e 10469
pcercuei 0:03b5121a232e 10470 /*
pcercuei 0:03b5121a232e 10471 * Chameleon include/redefine: skip loading only if it was
pcercuei 0:03b5121a232e 10472 * aleady build for the targetNamespace of the including
pcercuei 0:03b5121a232e 10473 * schema.
pcercuei 0:03b5121a232e 10474 */
pcercuei 0:03b5121a232e 10475 /*
pcercuei 0:03b5121a232e 10476 * URGENT TODO: If the schema is a chameleon-include then copy
pcercuei 0:03b5121a232e 10477 * the components into the including schema and modify the
pcercuei 0:03b5121a232e 10478 * targetNamespace of those components, do nothing otherwise.
pcercuei 0:03b5121a232e 10479 * NOTE: This is currently worked-around by compiling the
pcercuei 0:03b5121a232e 10480 * chameleon for every destinct including targetNamespace; thus
pcercuei 0:03b5121a232e 10481 * not performant at the moment.
pcercuei 0:03b5121a232e 10482 * TODO: Check when the namespace in wildcards for chameleons
pcercuei 0:03b5121a232e 10483 * needs to be converted: before we built wildcard intersections
pcercuei 0:03b5121a232e 10484 * or after.
pcercuei 0:03b5121a232e 10485 * Answer: after!
pcercuei 0:03b5121a232e 10486 */
pcercuei 0:03b5121a232e 10487 chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
pcercuei 0:03b5121a232e 10488 schemaLocation, sourceTargetNamespace);
pcercuei 0:03b5121a232e 10489 if (chamel != NULL) {
pcercuei 0:03b5121a232e 10490 /* A fitting chameleon was already parsed; NOP. */
pcercuei 0:03b5121a232e 10491 relation->bucket = chamel;
pcercuei 0:03b5121a232e 10492 goto exit;
pcercuei 0:03b5121a232e 10493 }
pcercuei 0:03b5121a232e 10494 /*
pcercuei 0:03b5121a232e 10495 * We need to parse the chameleon again for a different
pcercuei 0:03b5121a232e 10496 * targetNamespace.
pcercuei 0:03b5121a232e 10497 * CHAMELEON TODO: Optimize this by only parsing the
pcercuei 0:03b5121a232e 10498 * chameleon once, and then copying the components to
pcercuei 0:03b5121a232e 10499 * the new targetNamespace.
pcercuei 0:03b5121a232e 10500 */
pcercuei 0:03b5121a232e 10501 bkt = NULL;
pcercuei 0:03b5121a232e 10502 } else {
pcercuei 0:03b5121a232e 10503 relation->bucket = bkt;
pcercuei 0:03b5121a232e 10504 goto exit;
pcercuei 0:03b5121a232e 10505 }
pcercuei 0:03b5121a232e 10506 }
pcercuei 0:03b5121a232e 10507 }
pcercuei 0:03b5121a232e 10508 if ((bkt != NULL) && (bkt->doc != NULL)) {
pcercuei 0:03b5121a232e 10509 PERROR_INT("xmlSchemaAddSchemaDoc",
pcercuei 0:03b5121a232e 10510 "trying to load a schema doc, but a doc is already "
pcercuei 0:03b5121a232e 10511 "assigned to the schema bucket");
pcercuei 0:03b5121a232e 10512 goto exit_failure;
pcercuei 0:03b5121a232e 10513 }
pcercuei 0:03b5121a232e 10514
pcercuei 0:03b5121a232e 10515 doc_load:
pcercuei 0:03b5121a232e 10516 /*
pcercuei 0:03b5121a232e 10517 * Load the document.
pcercuei 0:03b5121a232e 10518 */
pcercuei 0:03b5121a232e 10519 if (schemaDoc != NULL) {
pcercuei 0:03b5121a232e 10520 doc = schemaDoc;
pcercuei 0:03b5121a232e 10521 /* Don' free this one, since it was provided by the caller. */
pcercuei 0:03b5121a232e 10522 preserveDoc = 1;
pcercuei 0:03b5121a232e 10523 /* TODO: Does the context or the doc hold the location? */
pcercuei 0:03b5121a232e 10524 if (schemaDoc->URL != NULL)
pcercuei 0:03b5121a232e 10525 schemaLocation = xmlDictLookup(pctxt->dict,
pcercuei 0:03b5121a232e 10526 schemaDoc->URL, -1);
pcercuei 0:03b5121a232e 10527 else
pcercuei 0:03b5121a232e 10528 schemaLocation = BAD_CAST "in_memory_buffer";
pcercuei 0:03b5121a232e 10529 } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
pcercuei 0:03b5121a232e 10530 xmlParserCtxtPtr parserCtxt;
pcercuei 0:03b5121a232e 10531
pcercuei 0:03b5121a232e 10532 parserCtxt = xmlNewParserCtxt();
pcercuei 0:03b5121a232e 10533 if (parserCtxt == NULL) {
pcercuei 0:03b5121a232e 10534 xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
pcercuei 0:03b5121a232e 10535 "allocating a parser context", NULL);
pcercuei 0:03b5121a232e 10536 goto exit_failure;
pcercuei 0:03b5121a232e 10537 }
pcercuei 0:03b5121a232e 10538 if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
pcercuei 0:03b5121a232e 10539 /*
pcercuei 0:03b5121a232e 10540 * TODO: Do we have to burden the schema parser dict with all
pcercuei 0:03b5121a232e 10541 * the content of the schema doc?
pcercuei 0:03b5121a232e 10542 */
pcercuei 0:03b5121a232e 10543 xmlDictFree(parserCtxt->dict);
pcercuei 0:03b5121a232e 10544 parserCtxt->dict = pctxt->dict;
pcercuei 0:03b5121a232e 10545 xmlDictReference(parserCtxt->dict);
pcercuei 0:03b5121a232e 10546 }
pcercuei 0:03b5121a232e 10547 if (schemaLocation != NULL) {
pcercuei 0:03b5121a232e 10548 /* Parse from file. */
pcercuei 0:03b5121a232e 10549 doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
pcercuei 0:03b5121a232e 10550 NULL, SCHEMAS_PARSE_OPTIONS);
pcercuei 0:03b5121a232e 10551 } else if (schemaBuffer != NULL) {
pcercuei 0:03b5121a232e 10552 /* Parse from memory buffer. */
pcercuei 0:03b5121a232e 10553 doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
pcercuei 0:03b5121a232e 10554 NULL, NULL, SCHEMAS_PARSE_OPTIONS);
pcercuei 0:03b5121a232e 10555 schemaLocation = BAD_CAST "in_memory_buffer";
pcercuei 0:03b5121a232e 10556 if (doc != NULL)
pcercuei 0:03b5121a232e 10557 doc->URL = xmlStrdup(schemaLocation);
pcercuei 0:03b5121a232e 10558 }
pcercuei 0:03b5121a232e 10559 /*
pcercuei 0:03b5121a232e 10560 * For <import>:
pcercuei 0:03b5121a232e 10561 * 2.1 The referent is (a fragment of) a resource which is an
pcercuei 0:03b5121a232e 10562 * XML document (see clause 1.1), which in turn corresponds to
pcercuei 0:03b5121a232e 10563 * a <schema> element information item in a well-formed information
pcercuei 0:03b5121a232e 10564 * set, which in turn corresponds to a valid schema.
pcercuei 0:03b5121a232e 10565 * TODO: (2.1) fragments of XML documents are not supported.
pcercuei 0:03b5121a232e 10566 *
pcercuei 0:03b5121a232e 10567 * 2.2 The referent is a <schema> element information item in
pcercuei 0:03b5121a232e 10568 * a well-formed information set, which in turn corresponds
pcercuei 0:03b5121a232e 10569 * to a valid schema.
pcercuei 0:03b5121a232e 10570 * TODO: (2.2) is not supported.
pcercuei 0:03b5121a232e 10571 */
pcercuei 0:03b5121a232e 10572 if (doc == NULL) {
pcercuei 0:03b5121a232e 10573 xmlErrorPtr lerr;
pcercuei 0:03b5121a232e 10574 lerr = xmlGetLastError();
pcercuei 0:03b5121a232e 10575 /*
pcercuei 0:03b5121a232e 10576 * Check if this a parser error, or if the document could
pcercuei 0:03b5121a232e 10577 * just not be located.
pcercuei 0:03b5121a232e 10578 * TODO: Try to find specific error codes to react only on
pcercuei 0:03b5121a232e 10579 * localisation failures.
pcercuei 0:03b5121a232e 10580 */
pcercuei 0:03b5121a232e 10581 if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
pcercuei 0:03b5121a232e 10582 /*
pcercuei 0:03b5121a232e 10583 * We assume a parser error here.
pcercuei 0:03b5121a232e 10584 */
pcercuei 0:03b5121a232e 10585 located = 1;
pcercuei 0:03b5121a232e 10586 /* TODO: Error code ?? */
pcercuei 0:03b5121a232e 10587 res = XML_SCHEMAP_SRC_IMPORT_2_1;
pcercuei 0:03b5121a232e 10588 xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
pcercuei 0:03b5121a232e 10589 invokingNode, NULL,
pcercuei 0:03b5121a232e 10590 "Failed to parse the XML resource '%s'",
pcercuei 0:03b5121a232e 10591 schemaLocation, NULL);
pcercuei 0:03b5121a232e 10592 }
pcercuei 0:03b5121a232e 10593 }
pcercuei 0:03b5121a232e 10594 xmlFreeParserCtxt(parserCtxt);
pcercuei 0:03b5121a232e 10595 if ((doc == NULL) && located)
pcercuei 0:03b5121a232e 10596 goto exit_error;
pcercuei 0:03b5121a232e 10597 } else {
pcercuei 0:03b5121a232e 10598 xmlSchemaPErr(pctxt, NULL,
pcercuei 0:03b5121a232e 10599 XML_SCHEMAP_NOTHING_TO_PARSE,
pcercuei 0:03b5121a232e 10600 "No information for parsing was provided with the "
pcercuei 0:03b5121a232e 10601 "given schema parser context.\n",
pcercuei 0:03b5121a232e 10602 NULL, NULL);
pcercuei 0:03b5121a232e 10603 goto exit_failure;
pcercuei 0:03b5121a232e 10604 }
pcercuei 0:03b5121a232e 10605 /*
pcercuei 0:03b5121a232e 10606 * Preprocess the document.
pcercuei 0:03b5121a232e 10607 */
pcercuei 0:03b5121a232e 10608 if (doc != NULL) {
pcercuei 0:03b5121a232e 10609 xmlNodePtr docElem = NULL;
pcercuei 0:03b5121a232e 10610
pcercuei 0:03b5121a232e 10611 located = 1;
pcercuei 0:03b5121a232e 10612 docElem = xmlDocGetRootElement(doc);
pcercuei 0:03b5121a232e 10613 if (docElem == NULL) {
pcercuei 0:03b5121a232e 10614 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
pcercuei 0:03b5121a232e 10615 invokingNode, NULL,
pcercuei 0:03b5121a232e 10616 "The document '%s' has no document element",
pcercuei 0:03b5121a232e 10617 schemaLocation, NULL);
pcercuei 0:03b5121a232e 10618 goto exit_error;
pcercuei 0:03b5121a232e 10619 }
pcercuei 0:03b5121a232e 10620 /*
pcercuei 0:03b5121a232e 10621 * Remove all the blank text nodes.
pcercuei 0:03b5121a232e 10622 */
pcercuei 0:03b5121a232e 10623 xmlSchemaCleanupDoc(pctxt, docElem);
pcercuei 0:03b5121a232e 10624 /*
pcercuei 0:03b5121a232e 10625 * Check the schema's top level element.
pcercuei 0:03b5121a232e 10626 */
pcercuei 0:03b5121a232e 10627 if (!IS_SCHEMA(docElem, "schema")) {
pcercuei 0:03b5121a232e 10628 xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
pcercuei 0:03b5121a232e 10629 invokingNode, NULL,
pcercuei 0:03b5121a232e 10630 "The XML document '%s' is not a schema document",
pcercuei 0:03b5121a232e 10631 schemaLocation, NULL);
pcercuei 0:03b5121a232e 10632 goto exit_error;
pcercuei 0:03b5121a232e 10633 }
pcercuei 0:03b5121a232e 10634 /*
pcercuei 0:03b5121a232e 10635 * Note that we don't apply a type check for the
pcercuei 0:03b5121a232e 10636 * targetNamespace value here.
pcercuei 0:03b5121a232e 10637 */
pcercuei 0:03b5121a232e 10638 targetNamespace = xmlSchemaGetProp(pctxt, docElem,
pcercuei 0:03b5121a232e 10639 "targetNamespace");
pcercuei 0:03b5121a232e 10640 }
pcercuei 0:03b5121a232e 10641
pcercuei 0:03b5121a232e 10642 /* after_doc_loading: */
pcercuei 0:03b5121a232e 10643 if ((bkt == NULL) && located) {
pcercuei 0:03b5121a232e 10644 /* Only create a bucket if the schema was located. */
pcercuei 0:03b5121a232e 10645 bkt = xmlSchemaBucketCreate(pctxt, type,
pcercuei 0:03b5121a232e 10646 targetNamespace);
pcercuei 0:03b5121a232e 10647 if (bkt == NULL)
pcercuei 0:03b5121a232e 10648 goto exit_failure;
pcercuei 0:03b5121a232e 10649 }
pcercuei 0:03b5121a232e 10650 if (bkt != NULL) {
pcercuei 0:03b5121a232e 10651 bkt->schemaLocation = schemaLocation;
pcercuei 0:03b5121a232e 10652 bkt->located = located;
pcercuei 0:03b5121a232e 10653 if (doc != NULL) {
pcercuei 0:03b5121a232e 10654 bkt->doc = doc;
pcercuei 0:03b5121a232e 10655 bkt->targetNamespace = targetNamespace;
pcercuei 0:03b5121a232e 10656 bkt->origTargetNamespace = targetNamespace;
pcercuei 0:03b5121a232e 10657 if (preserveDoc)
pcercuei 0:03b5121a232e 10658 bkt->preserveDoc = 1;
pcercuei 0:03b5121a232e 10659 }
pcercuei 0:03b5121a232e 10660 if (WXS_IS_BUCKET_IMPMAIN(type))
pcercuei 0:03b5121a232e 10661 bkt->imported++;
pcercuei 0:03b5121a232e 10662 /*
pcercuei 0:03b5121a232e 10663 * Add it to the graph of schemas.
pcercuei 0:03b5121a232e 10664 */
pcercuei 0:03b5121a232e 10665 if (relation != NULL)
pcercuei 0:03b5121a232e 10666 relation->bucket = bkt;
pcercuei 0:03b5121a232e 10667 }
pcercuei 0:03b5121a232e 10668
pcercuei 0:03b5121a232e 10669 exit:
pcercuei 0:03b5121a232e 10670 /*
pcercuei 0:03b5121a232e 10671 * Return the bucket explicitely; this is needed for the
pcercuei 0:03b5121a232e 10672 * main schema.
pcercuei 0:03b5121a232e 10673 */
pcercuei 0:03b5121a232e 10674 if (bucket != NULL)
pcercuei 0:03b5121a232e 10675 *bucket = bkt;
pcercuei 0:03b5121a232e 10676 return (0);
pcercuei 0:03b5121a232e 10677
pcercuei 0:03b5121a232e 10678 exit_error:
pcercuei 0:03b5121a232e 10679 if ((doc != NULL) && (! preserveDoc)) {
pcercuei 0:03b5121a232e 10680 xmlFreeDoc(doc);
pcercuei 0:03b5121a232e 10681 if (bkt != NULL)
pcercuei 0:03b5121a232e 10682 bkt->doc = NULL;
pcercuei 0:03b5121a232e 10683 }
pcercuei 0:03b5121a232e 10684 return(pctxt->err);
pcercuei 0:03b5121a232e 10685
pcercuei 0:03b5121a232e 10686 exit_failure:
pcercuei 0:03b5121a232e 10687 if ((doc != NULL) && (! preserveDoc)) {
pcercuei 0:03b5121a232e 10688 xmlFreeDoc(doc);
pcercuei 0:03b5121a232e 10689 if (bkt != NULL)
pcercuei 0:03b5121a232e 10690 bkt->doc = NULL;
pcercuei 0:03b5121a232e 10691 }
pcercuei 0:03b5121a232e 10692 return (-1);
pcercuei 0:03b5121a232e 10693 }
pcercuei 0:03b5121a232e 10694
pcercuei 0:03b5121a232e 10695 /**
pcercuei 0:03b5121a232e 10696 * xmlSchemaParseImport:
pcercuei 0:03b5121a232e 10697 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 10698 * @schema: the schema being built
pcercuei 0:03b5121a232e 10699 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 10700 *
pcercuei 0:03b5121a232e 10701 * parse a XML schema Import definition
pcercuei 0:03b5121a232e 10702 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 10703 *
pcercuei 0:03b5121a232e 10704 * Returns 0 in case of success, a positive error code if
pcercuei 0:03b5121a232e 10705 * not valid and -1 in case of an internal error.
pcercuei 0:03b5121a232e 10706 */
pcercuei 0:03b5121a232e 10707 static int
pcercuei 0:03b5121a232e 10708 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 10709 xmlNodePtr node)
pcercuei 0:03b5121a232e 10710 {
pcercuei 0:03b5121a232e 10711 xmlNodePtr child;
pcercuei 0:03b5121a232e 10712 const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
pcercuei 0:03b5121a232e 10713 const xmlChar *thisTargetNamespace;
pcercuei 0:03b5121a232e 10714 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 10715 int ret = 0;
pcercuei 0:03b5121a232e 10716 xmlSchemaBucketPtr bucket = NULL;
pcercuei 0:03b5121a232e 10717
pcercuei 0:03b5121a232e 10718 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 10719 return (-1);
pcercuei 0:03b5121a232e 10720
pcercuei 0:03b5121a232e 10721 /*
pcercuei 0:03b5121a232e 10722 * Check for illegal attributes.
pcercuei 0:03b5121a232e 10723 */
pcercuei 0:03b5121a232e 10724 attr = node->properties;
pcercuei 0:03b5121a232e 10725 while (attr != NULL) {
pcercuei 0:03b5121a232e 10726 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 10727 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 10728 (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
pcercuei 0:03b5121a232e 10729 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
pcercuei 0:03b5121a232e 10730 xmlSchemaPIllegalAttrErr(pctxt,
pcercuei 0:03b5121a232e 10731 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 10732 }
pcercuei 0:03b5121a232e 10733 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 10734 xmlSchemaPIllegalAttrErr(pctxt,
pcercuei 0:03b5121a232e 10735 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 10736 }
pcercuei 0:03b5121a232e 10737 attr = attr->next;
pcercuei 0:03b5121a232e 10738 }
pcercuei 0:03b5121a232e 10739 /*
pcercuei 0:03b5121a232e 10740 * Extract and validate attributes.
pcercuei 0:03b5121a232e 10741 */
pcercuei 0:03b5121a232e 10742 if (xmlSchemaPValAttr(pctxt, NULL, node,
pcercuei 0:03b5121a232e 10743 "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
pcercuei 0:03b5121a232e 10744 &namespaceName) != 0) {
pcercuei 0:03b5121a232e 10745 xmlSchemaPSimpleTypeErr(pctxt,
pcercuei 0:03b5121a232e 10746 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 10747 NULL, node,
pcercuei 0:03b5121a232e 10748 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
pcercuei 0:03b5121a232e 10749 NULL, namespaceName, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 10750 return (pctxt->err);
pcercuei 0:03b5121a232e 10751 }
pcercuei 0:03b5121a232e 10752
pcercuei 0:03b5121a232e 10753 if (xmlSchemaPValAttr(pctxt, NULL, node,
pcercuei 0:03b5121a232e 10754 "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
pcercuei 0:03b5121a232e 10755 &schemaLocation) != 0) {
pcercuei 0:03b5121a232e 10756 xmlSchemaPSimpleTypeErr(pctxt,
pcercuei 0:03b5121a232e 10757 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 10758 NULL, node,
pcercuei 0:03b5121a232e 10759 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
pcercuei 0:03b5121a232e 10760 NULL, schemaLocation, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 10761 return (pctxt->err);
pcercuei 0:03b5121a232e 10762 }
pcercuei 0:03b5121a232e 10763 /*
pcercuei 0:03b5121a232e 10764 * And now for the children...
pcercuei 0:03b5121a232e 10765 */
pcercuei 0:03b5121a232e 10766 child = node->children;
pcercuei 0:03b5121a232e 10767 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 10768 /*
pcercuei 0:03b5121a232e 10769 * the annotation here is simply discarded ...
pcercuei 0:03b5121a232e 10770 * TODO: really?
pcercuei 0:03b5121a232e 10771 */
pcercuei 0:03b5121a232e 10772 child = child->next;
pcercuei 0:03b5121a232e 10773 }
pcercuei 0:03b5121a232e 10774 if (child != NULL) {
pcercuei 0:03b5121a232e 10775 xmlSchemaPContentErr(pctxt,
pcercuei 0:03b5121a232e 10776 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 10777 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 10778 "(annotation?)");
pcercuei 0:03b5121a232e 10779 }
pcercuei 0:03b5121a232e 10780 /*
pcercuei 0:03b5121a232e 10781 * Apply additional constraints.
pcercuei 0:03b5121a232e 10782 *
pcercuei 0:03b5121a232e 10783 * Note that it is important to use the original @targetNamespace
pcercuei 0:03b5121a232e 10784 * (or none at all), to rule out imports of schemas _with_ a
pcercuei 0:03b5121a232e 10785 * @targetNamespace if the importing schema is a chameleon schema
pcercuei 0:03b5121a232e 10786 * (with no @targetNamespace).
pcercuei 0:03b5121a232e 10787 */
pcercuei 0:03b5121a232e 10788 thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
pcercuei 0:03b5121a232e 10789 if (namespaceName != NULL) {
pcercuei 0:03b5121a232e 10790 /*
pcercuei 0:03b5121a232e 10791 * 1.1 If the namespace [attribute] is present, then its `actual value`
pcercuei 0:03b5121a232e 10792 * must not match the `actual value` of the enclosing <schema>'s
pcercuei 0:03b5121a232e 10793 * targetNamespace [attribute].
pcercuei 0:03b5121a232e 10794 */
pcercuei 0:03b5121a232e 10795 if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
pcercuei 0:03b5121a232e 10796 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 10797 XML_SCHEMAP_SRC_IMPORT_1_1,
pcercuei 0:03b5121a232e 10798 NULL, node,
pcercuei 0:03b5121a232e 10799 "The value of the attribute 'namespace' must not match "
pcercuei 0:03b5121a232e 10800 "the target namespace '%s' of the importing schema",
pcercuei 0:03b5121a232e 10801 thisTargetNamespace);
pcercuei 0:03b5121a232e 10802 return (pctxt->err);
pcercuei 0:03b5121a232e 10803 }
pcercuei 0:03b5121a232e 10804 } else {
pcercuei 0:03b5121a232e 10805 /*
pcercuei 0:03b5121a232e 10806 * 1.2 If the namespace [attribute] is not present, then the enclosing
pcercuei 0:03b5121a232e 10807 * <schema> must have a targetNamespace [attribute].
pcercuei 0:03b5121a232e 10808 */
pcercuei 0:03b5121a232e 10809 if (thisTargetNamespace == NULL) {
pcercuei 0:03b5121a232e 10810 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 10811 XML_SCHEMAP_SRC_IMPORT_1_2,
pcercuei 0:03b5121a232e 10812 NULL, node,
pcercuei 0:03b5121a232e 10813 "The attribute 'namespace' must be existent if "
pcercuei 0:03b5121a232e 10814 "the importing schema has no target namespace",
pcercuei 0:03b5121a232e 10815 NULL);
pcercuei 0:03b5121a232e 10816 return (pctxt->err);
pcercuei 0:03b5121a232e 10817 }
pcercuei 0:03b5121a232e 10818 }
pcercuei 0:03b5121a232e 10819 /*
pcercuei 0:03b5121a232e 10820 * Locate and acquire the schema document.
pcercuei 0:03b5121a232e 10821 */
pcercuei 0:03b5121a232e 10822 if (schemaLocation != NULL)
pcercuei 0:03b5121a232e 10823 schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
pcercuei 0:03b5121a232e 10824 schemaLocation, node);
pcercuei 0:03b5121a232e 10825 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
pcercuei 0:03b5121a232e 10826 schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
pcercuei 0:03b5121a232e 10827 namespaceName, &bucket);
pcercuei 0:03b5121a232e 10828
pcercuei 0:03b5121a232e 10829 if (ret != 0)
pcercuei 0:03b5121a232e 10830 return(ret);
pcercuei 0:03b5121a232e 10831
pcercuei 0:03b5121a232e 10832 /*
pcercuei 0:03b5121a232e 10833 * For <import>: "It is *not* an error for the application
pcercuei 0:03b5121a232e 10834 * schema reference strategy to fail."
pcercuei 0:03b5121a232e 10835 * So just don't parse if no schema document was found.
pcercuei 0:03b5121a232e 10836 * Note that we will get no bucket if the schema could not be
pcercuei 0:03b5121a232e 10837 * located or if there was no schemaLocation.
pcercuei 0:03b5121a232e 10838 */
pcercuei 0:03b5121a232e 10839 if ((bucket == NULL) && (schemaLocation != NULL)) {
pcercuei 0:03b5121a232e 10840 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 10841 XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
pcercuei 0:03b5121a232e 10842 node, NULL,
pcercuei 0:03b5121a232e 10843 "Failed to locate a schema at location '%s'. "
pcercuei 0:03b5121a232e 10844 "Skipping the import", schemaLocation, NULL, NULL);
pcercuei 0:03b5121a232e 10845 }
pcercuei 0:03b5121a232e 10846
pcercuei 0:03b5121a232e 10847 if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
pcercuei 0:03b5121a232e 10848 ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
pcercuei 0:03b5121a232e 10849 }
pcercuei 0:03b5121a232e 10850
pcercuei 0:03b5121a232e 10851 return (ret);
pcercuei 0:03b5121a232e 10852 }
pcercuei 0:03b5121a232e 10853
pcercuei 0:03b5121a232e 10854 static int
pcercuei 0:03b5121a232e 10855 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 10856 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 10857 xmlNodePtr node,
pcercuei 0:03b5121a232e 10858 xmlChar **schemaLocation,
pcercuei 0:03b5121a232e 10859 int type)
pcercuei 0:03b5121a232e 10860 {
pcercuei 0:03b5121a232e 10861 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 10862
pcercuei 0:03b5121a232e 10863 if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
pcercuei 0:03b5121a232e 10864 (schemaLocation == NULL))
pcercuei 0:03b5121a232e 10865 return (-1);
pcercuei 0:03b5121a232e 10866
pcercuei 0:03b5121a232e 10867 *schemaLocation = NULL;
pcercuei 0:03b5121a232e 10868 /*
pcercuei 0:03b5121a232e 10869 * Check for illegal attributes.
pcercuei 0:03b5121a232e 10870 * Applies for both <include> and <redefine>.
pcercuei 0:03b5121a232e 10871 */
pcercuei 0:03b5121a232e 10872 attr = node->properties;
pcercuei 0:03b5121a232e 10873 while (attr != NULL) {
pcercuei 0:03b5121a232e 10874 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 10875 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 10876 (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
pcercuei 0:03b5121a232e 10877 xmlSchemaPIllegalAttrErr(pctxt,
pcercuei 0:03b5121a232e 10878 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 10879 }
pcercuei 0:03b5121a232e 10880 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 10881 xmlSchemaPIllegalAttrErr(pctxt,
pcercuei 0:03b5121a232e 10882 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 10883 }
pcercuei 0:03b5121a232e 10884 attr = attr->next;
pcercuei 0:03b5121a232e 10885 }
pcercuei 0:03b5121a232e 10886 xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 10887 /*
pcercuei 0:03b5121a232e 10888 * Preliminary step, extract the URI-Reference and make an URI
pcercuei 0:03b5121a232e 10889 * from the base.
pcercuei 0:03b5121a232e 10890 */
pcercuei 0:03b5121a232e 10891 /*
pcercuei 0:03b5121a232e 10892 * Attribute "schemaLocation" is mandatory.
pcercuei 0:03b5121a232e 10893 */
pcercuei 0:03b5121a232e 10894 attr = xmlSchemaGetPropNode(node, "schemaLocation");
pcercuei 0:03b5121a232e 10895 if (attr != NULL) {
pcercuei 0:03b5121a232e 10896 xmlChar *base = NULL;
pcercuei 0:03b5121a232e 10897 xmlChar *uri = NULL;
pcercuei 0:03b5121a232e 10898
pcercuei 0:03b5121a232e 10899 if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
pcercuei 0:03b5121a232e 10900 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
pcercuei 0:03b5121a232e 10901 (const xmlChar **) schemaLocation) != 0)
pcercuei 0:03b5121a232e 10902 goto exit_error;
pcercuei 0:03b5121a232e 10903 base = xmlNodeGetBase(node->doc, node);
pcercuei 0:03b5121a232e 10904 if (base == NULL) {
pcercuei 0:03b5121a232e 10905 uri = xmlBuildURI(*schemaLocation, node->doc->URL);
pcercuei 0:03b5121a232e 10906 } else {
pcercuei 0:03b5121a232e 10907 uri = xmlBuildURI(*schemaLocation, base);
pcercuei 0:03b5121a232e 10908 xmlFree(base);
pcercuei 0:03b5121a232e 10909 }
pcercuei 0:03b5121a232e 10910 if (uri == NULL) {
pcercuei 0:03b5121a232e 10911 PERROR_INT("xmlSchemaParseIncludeOrRedefine",
pcercuei 0:03b5121a232e 10912 "could not build an URI from the schemaLocation")
pcercuei 0:03b5121a232e 10913 goto exit_failure;
pcercuei 0:03b5121a232e 10914 }
pcercuei 0:03b5121a232e 10915 (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
pcercuei 0:03b5121a232e 10916 xmlFree(uri);
pcercuei 0:03b5121a232e 10917 } else {
pcercuei 0:03b5121a232e 10918 xmlSchemaPMissingAttrErr(pctxt,
pcercuei 0:03b5121a232e 10919 XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 10920 NULL, node, "schemaLocation", NULL);
pcercuei 0:03b5121a232e 10921 goto exit_error;
pcercuei 0:03b5121a232e 10922 }
pcercuei 0:03b5121a232e 10923 /*
pcercuei 0:03b5121a232e 10924 * Report self-inclusion and self-redefinition.
pcercuei 0:03b5121a232e 10925 */
pcercuei 0:03b5121a232e 10926 if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
pcercuei 0:03b5121a232e 10927 if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
pcercuei 0:03b5121a232e 10928 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 10929 XML_SCHEMAP_SRC_REDEFINE,
pcercuei 0:03b5121a232e 10930 NULL, node,
pcercuei 0:03b5121a232e 10931 "The schema document '%s' cannot redefine itself.",
pcercuei 0:03b5121a232e 10932 *schemaLocation);
pcercuei 0:03b5121a232e 10933 } else {
pcercuei 0:03b5121a232e 10934 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 10935 XML_SCHEMAP_SRC_INCLUDE,
pcercuei 0:03b5121a232e 10936 NULL, node,
pcercuei 0:03b5121a232e 10937 "The schema document '%s' cannot include itself.",
pcercuei 0:03b5121a232e 10938 *schemaLocation);
pcercuei 0:03b5121a232e 10939 }
pcercuei 0:03b5121a232e 10940 goto exit_error;
pcercuei 0:03b5121a232e 10941 }
pcercuei 0:03b5121a232e 10942
pcercuei 0:03b5121a232e 10943 return(0);
pcercuei 0:03b5121a232e 10944 exit_error:
pcercuei 0:03b5121a232e 10945 return(pctxt->err);
pcercuei 0:03b5121a232e 10946 exit_failure:
pcercuei 0:03b5121a232e 10947 return(-1);
pcercuei 0:03b5121a232e 10948 }
pcercuei 0:03b5121a232e 10949
pcercuei 0:03b5121a232e 10950 static int
pcercuei 0:03b5121a232e 10951 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 10952 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 10953 xmlNodePtr node,
pcercuei 0:03b5121a232e 10954 int type)
pcercuei 0:03b5121a232e 10955 {
pcercuei 0:03b5121a232e 10956 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 10957 const xmlChar *schemaLocation = NULL;
pcercuei 0:03b5121a232e 10958 int res = 0; /* hasRedefinitions = 0 */
pcercuei 0:03b5121a232e 10959 int isChameleon = 0, wasChameleon = 0;
pcercuei 0:03b5121a232e 10960 xmlSchemaBucketPtr bucket = NULL;
pcercuei 0:03b5121a232e 10961
pcercuei 0:03b5121a232e 10962 if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 10963 return (-1);
pcercuei 0:03b5121a232e 10964
pcercuei 0:03b5121a232e 10965 /*
pcercuei 0:03b5121a232e 10966 * Parse attributes. Note that the returned schemaLocation will
pcercuei 0:03b5121a232e 10967 * be already converted to an absolute URI.
pcercuei 0:03b5121a232e 10968 */
pcercuei 0:03b5121a232e 10969 res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
pcercuei 0:03b5121a232e 10970 node, (xmlChar **) (&schemaLocation), type);
pcercuei 0:03b5121a232e 10971 if (res != 0)
pcercuei 0:03b5121a232e 10972 return(res);
pcercuei 0:03b5121a232e 10973 /*
pcercuei 0:03b5121a232e 10974 * Load and add the schema document.
pcercuei 0:03b5121a232e 10975 */
pcercuei 0:03b5121a232e 10976 res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
pcercuei 0:03b5121a232e 10977 NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
pcercuei 0:03b5121a232e 10978 if (res != 0)
pcercuei 0:03b5121a232e 10979 return(res);
pcercuei 0:03b5121a232e 10980 /*
pcercuei 0:03b5121a232e 10981 * If we get no schema bucket back, then this means that the schema
pcercuei 0:03b5121a232e 10982 * document could not be located or was broken XML or was not
pcercuei 0:03b5121a232e 10983 * a schema document.
pcercuei 0:03b5121a232e 10984 */
pcercuei 0:03b5121a232e 10985 if ((bucket == NULL) || (bucket->doc == NULL)) {
pcercuei 0:03b5121a232e 10986 if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
pcercuei 0:03b5121a232e 10987 /*
pcercuei 0:03b5121a232e 10988 * WARNING for <include>:
pcercuei 0:03b5121a232e 10989 * We will raise an error if the schema cannot be located
pcercuei 0:03b5121a232e 10990 * for inclusions, since the that was the feedback from the
pcercuei 0:03b5121a232e 10991 * schema people. I.e. the following spec piece will *not* be
pcercuei 0:03b5121a232e 10992 * satisfied:
pcercuei 0:03b5121a232e 10993 * SPEC src-include: "It is not an error for the `actual value` of the
pcercuei 0:03b5121a232e 10994 * schemaLocation [attribute] to fail to resolve it all, in which
pcercuei 0:03b5121a232e 10995 * case no corresponding inclusion is performed.
pcercuei 0:03b5121a232e 10996 * So do we need a warning report here?"
pcercuei 0:03b5121a232e 10997 */
pcercuei 0:03b5121a232e 10998 res = XML_SCHEMAP_SRC_INCLUDE;
pcercuei 0:03b5121a232e 10999 xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
pcercuei 0:03b5121a232e 11000 node, NULL,
pcercuei 0:03b5121a232e 11001 "Failed to load the document '%s' for inclusion",
pcercuei 0:03b5121a232e 11002 schemaLocation, NULL);
pcercuei 0:03b5121a232e 11003 } else {
pcercuei 0:03b5121a232e 11004 /*
pcercuei 0:03b5121a232e 11005 * NOTE: This was changed to raise an error even if no redefinitions
pcercuei 0:03b5121a232e 11006 * are specified.
pcercuei 0:03b5121a232e 11007 *
pcercuei 0:03b5121a232e 11008 * SPEC src-redefine (1)
pcercuei 0:03b5121a232e 11009 * "If there are any element information items among the [children]
pcercuei 0:03b5121a232e 11010 * other than <annotation> then the `actual value` of the
pcercuei 0:03b5121a232e 11011 * schemaLocation [attribute] must successfully resolve."
pcercuei 0:03b5121a232e 11012 * TODO: Ask the WG if a the location has always to resolve
pcercuei 0:03b5121a232e 11013 * here as well!
pcercuei 0:03b5121a232e 11014 */
pcercuei 0:03b5121a232e 11015 res = XML_SCHEMAP_SRC_REDEFINE;
pcercuei 0:03b5121a232e 11016 xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
pcercuei 0:03b5121a232e 11017 node, NULL,
pcercuei 0:03b5121a232e 11018 "Failed to load the document '%s' for redefinition",
pcercuei 0:03b5121a232e 11019 schemaLocation, NULL);
pcercuei 0:03b5121a232e 11020 }
pcercuei 0:03b5121a232e 11021 } else {
pcercuei 0:03b5121a232e 11022 /*
pcercuei 0:03b5121a232e 11023 * Check targetNamespace sanity before parsing the new schema.
pcercuei 0:03b5121a232e 11024 * TODO: Note that we won't check further content if the
pcercuei 0:03b5121a232e 11025 * targetNamespace was bad.
pcercuei 0:03b5121a232e 11026 */
pcercuei 0:03b5121a232e 11027 if (bucket->origTargetNamespace != NULL) {
pcercuei 0:03b5121a232e 11028 /*
pcercuei 0:03b5121a232e 11029 * SPEC src-include (2.1)
pcercuei 0:03b5121a232e 11030 * "SII has a targetNamespace [attribute], and its `actual
pcercuei 0:03b5121a232e 11031 * value` is identical to the `actual value` of the targetNamespace
pcercuei 0:03b5121a232e 11032 * [attribute] of SII' (which must have such an [attribute])."
pcercuei 0:03b5121a232e 11033 */
pcercuei 0:03b5121a232e 11034 if (pctxt->targetNamespace == NULL) {
pcercuei 0:03b5121a232e 11035 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 11036 XML_SCHEMAP_SRC_INCLUDE,
pcercuei 0:03b5121a232e 11037 node, NULL,
pcercuei 0:03b5121a232e 11038 "The target namespace of the included/redefined schema "
pcercuei 0:03b5121a232e 11039 "'%s' has to be absent, since the including/redefining "
pcercuei 0:03b5121a232e 11040 "schema has no target namespace",
pcercuei 0:03b5121a232e 11041 schemaLocation, NULL);
pcercuei 0:03b5121a232e 11042 goto exit_error;
pcercuei 0:03b5121a232e 11043 } else if (!xmlStrEqual(bucket->origTargetNamespace,
pcercuei 0:03b5121a232e 11044 pctxt->targetNamespace)) {
pcercuei 0:03b5121a232e 11045 /* TODO: Change error function. */
pcercuei 0:03b5121a232e 11046 xmlSchemaPCustomErrExt(pctxt,
pcercuei 0:03b5121a232e 11047 XML_SCHEMAP_SRC_INCLUDE,
pcercuei 0:03b5121a232e 11048 NULL, node,
pcercuei 0:03b5121a232e 11049 "The target namespace '%s' of the included/redefined "
pcercuei 0:03b5121a232e 11050 "schema '%s' differs from '%s' of the "
pcercuei 0:03b5121a232e 11051 "including/redefining schema",
pcercuei 0:03b5121a232e 11052 bucket->origTargetNamespace, schemaLocation,
pcercuei 0:03b5121a232e 11053 pctxt->targetNamespace);
pcercuei 0:03b5121a232e 11054 goto exit_error;
pcercuei 0:03b5121a232e 11055 }
pcercuei 0:03b5121a232e 11056 } else if (pctxt->targetNamespace != NULL) {
pcercuei 0:03b5121a232e 11057 /*
pcercuei 0:03b5121a232e 11058 * Chameleons: the original target namespace will
pcercuei 0:03b5121a232e 11059 * differ from the resulting namespace.
pcercuei 0:03b5121a232e 11060 */
pcercuei 0:03b5121a232e 11061 isChameleon = 1;
pcercuei 0:03b5121a232e 11062 if (bucket->parsed &&
pcercuei 0:03b5121a232e 11063 bucket->origTargetNamespace != NULL) {
pcercuei 0:03b5121a232e 11064 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 11065 XML_SCHEMAP_SRC_INCLUDE,
pcercuei 0:03b5121a232e 11066 node, NULL,
pcercuei 0:03b5121a232e 11067 "The target namespace of the included/redefined schema "
pcercuei 0:03b5121a232e 11068 "'%s' has to be absent or the same as the "
pcercuei 0:03b5121a232e 11069 "including/redefining schema's target namespace",
pcercuei 0:03b5121a232e 11070 schemaLocation, NULL);
pcercuei 0:03b5121a232e 11071 goto exit_error;
pcercuei 0:03b5121a232e 11072 }
pcercuei 0:03b5121a232e 11073 bucket->targetNamespace = pctxt->targetNamespace;
pcercuei 0:03b5121a232e 11074 }
pcercuei 0:03b5121a232e 11075 }
pcercuei 0:03b5121a232e 11076 /*
pcercuei 0:03b5121a232e 11077 * Parse the schema.
pcercuei 0:03b5121a232e 11078 */
pcercuei 0:03b5121a232e 11079 if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
pcercuei 0:03b5121a232e 11080 if (isChameleon) {
pcercuei 0:03b5121a232e 11081 /* TODO: Get rid of this flag on the schema itself. */
pcercuei 0:03b5121a232e 11082 if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
pcercuei 0:03b5121a232e 11083 schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
pcercuei 0:03b5121a232e 11084 } else
pcercuei 0:03b5121a232e 11085 wasChameleon = 1;
pcercuei 0:03b5121a232e 11086 }
pcercuei 0:03b5121a232e 11087 xmlSchemaParseNewDoc(pctxt, schema, bucket);
pcercuei 0:03b5121a232e 11088 /* Restore chameleon flag. */
pcercuei 0:03b5121a232e 11089 if (isChameleon && (!wasChameleon))
pcercuei 0:03b5121a232e 11090 schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
pcercuei 0:03b5121a232e 11091 }
pcercuei 0:03b5121a232e 11092 /*
pcercuei 0:03b5121a232e 11093 * And now for the children...
pcercuei 0:03b5121a232e 11094 */
pcercuei 0:03b5121a232e 11095 child = node->children;
pcercuei 0:03b5121a232e 11096 if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
pcercuei 0:03b5121a232e 11097 /*
pcercuei 0:03b5121a232e 11098 * Parse (simpleType | complexType | group | attributeGroup))*
pcercuei 0:03b5121a232e 11099 */
pcercuei 0:03b5121a232e 11100 pctxt->redefined = bucket;
pcercuei 0:03b5121a232e 11101 /*
pcercuei 0:03b5121a232e 11102 * How to proceed if the redefined schema was not located?
pcercuei 0:03b5121a232e 11103 */
pcercuei 0:03b5121a232e 11104 pctxt->isRedefine = 1;
pcercuei 0:03b5121a232e 11105 while (IS_SCHEMA(child, "annotation") ||
pcercuei 0:03b5121a232e 11106 IS_SCHEMA(child, "simpleType") ||
pcercuei 0:03b5121a232e 11107 IS_SCHEMA(child, "complexType") ||
pcercuei 0:03b5121a232e 11108 IS_SCHEMA(child, "group") ||
pcercuei 0:03b5121a232e 11109 IS_SCHEMA(child, "attributeGroup")) {
pcercuei 0:03b5121a232e 11110 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 11111 /*
pcercuei 0:03b5121a232e 11112 * TODO: discard or not?
pcercuei 0:03b5121a232e 11113 */
pcercuei 0:03b5121a232e 11114 } else if (IS_SCHEMA(child, "simpleType")) {
pcercuei 0:03b5121a232e 11115 xmlSchemaParseSimpleType(pctxt, schema, child, 1);
pcercuei 0:03b5121a232e 11116 } else if (IS_SCHEMA(child, "complexType")) {
pcercuei 0:03b5121a232e 11117 xmlSchemaParseComplexType(pctxt, schema, child, 1);
pcercuei 0:03b5121a232e 11118 /* hasRedefinitions = 1; */
pcercuei 0:03b5121a232e 11119 } else if (IS_SCHEMA(child, "group")) {
pcercuei 0:03b5121a232e 11120 /* hasRedefinitions = 1; */
pcercuei 0:03b5121a232e 11121 xmlSchemaParseModelGroupDefinition(pctxt,
pcercuei 0:03b5121a232e 11122 schema, child);
pcercuei 0:03b5121a232e 11123 } else if (IS_SCHEMA(child, "attributeGroup")) {
pcercuei 0:03b5121a232e 11124 /* hasRedefinitions = 1; */
pcercuei 0:03b5121a232e 11125 xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
pcercuei 0:03b5121a232e 11126 child);
pcercuei 0:03b5121a232e 11127 }
pcercuei 0:03b5121a232e 11128 child = child->next;
pcercuei 0:03b5121a232e 11129 }
pcercuei 0:03b5121a232e 11130 pctxt->redefined = NULL;
pcercuei 0:03b5121a232e 11131 pctxt->isRedefine = 0;
pcercuei 0:03b5121a232e 11132 } else {
pcercuei 0:03b5121a232e 11133 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 11134 /*
pcercuei 0:03b5121a232e 11135 * TODO: discard or not?
pcercuei 0:03b5121a232e 11136 */
pcercuei 0:03b5121a232e 11137 child = child->next;
pcercuei 0:03b5121a232e 11138 }
pcercuei 0:03b5121a232e 11139 }
pcercuei 0:03b5121a232e 11140 if (child != NULL) {
pcercuei 0:03b5121a232e 11141 res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
pcercuei 0:03b5121a232e 11142 if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
pcercuei 0:03b5121a232e 11143 xmlSchemaPContentErr(pctxt, res,
pcercuei 0:03b5121a232e 11144 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 11145 "(annotation | (simpleType | complexType | group | attributeGroup))*");
pcercuei 0:03b5121a232e 11146 } else {
pcercuei 0:03b5121a232e 11147 xmlSchemaPContentErr(pctxt, res,
pcercuei 0:03b5121a232e 11148 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 11149 "(annotation?)");
pcercuei 0:03b5121a232e 11150 }
pcercuei 0:03b5121a232e 11151 }
pcercuei 0:03b5121a232e 11152 return(res);
pcercuei 0:03b5121a232e 11153
pcercuei 0:03b5121a232e 11154 exit_error:
pcercuei 0:03b5121a232e 11155 return(pctxt->err);
pcercuei 0:03b5121a232e 11156 }
pcercuei 0:03b5121a232e 11157
pcercuei 0:03b5121a232e 11158 static int
pcercuei 0:03b5121a232e 11159 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 11160 xmlNodePtr node)
pcercuei 0:03b5121a232e 11161 {
pcercuei 0:03b5121a232e 11162 int res;
pcercuei 0:03b5121a232e 11163 #ifndef ENABLE_REDEFINE
pcercuei 0:03b5121a232e 11164 TODO
pcercuei 0:03b5121a232e 11165 return(0);
pcercuei 0:03b5121a232e 11166 #endif
pcercuei 0:03b5121a232e 11167 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
pcercuei 0:03b5121a232e 11168 XML_SCHEMA_SCHEMA_REDEFINE);
pcercuei 0:03b5121a232e 11169 if (res != 0)
pcercuei 0:03b5121a232e 11170 return(res);
pcercuei 0:03b5121a232e 11171 return(0);
pcercuei 0:03b5121a232e 11172 }
pcercuei 0:03b5121a232e 11173
pcercuei 0:03b5121a232e 11174 static int
pcercuei 0:03b5121a232e 11175 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 11176 xmlNodePtr node)
pcercuei 0:03b5121a232e 11177 {
pcercuei 0:03b5121a232e 11178 int res;
pcercuei 0:03b5121a232e 11179
pcercuei 0:03b5121a232e 11180 res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
pcercuei 0:03b5121a232e 11181 XML_SCHEMA_SCHEMA_INCLUDE);
pcercuei 0:03b5121a232e 11182 if (res != 0)
pcercuei 0:03b5121a232e 11183 return(res);
pcercuei 0:03b5121a232e 11184 return(0);
pcercuei 0:03b5121a232e 11185 }
pcercuei 0:03b5121a232e 11186
pcercuei 0:03b5121a232e 11187 /**
pcercuei 0:03b5121a232e 11188 * xmlSchemaParseModelGroup:
pcercuei 0:03b5121a232e 11189 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 11190 * @schema: the schema being built
pcercuei 0:03b5121a232e 11191 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 11192 * @type: the "compositor" type
pcercuei 0:03b5121a232e 11193 * @particleNeeded: if a a model group with a particle
pcercuei 0:03b5121a232e 11194 *
pcercuei 0:03b5121a232e 11195 * parse a XML schema Sequence definition.
pcercuei 0:03b5121a232e 11196 * Applies parts of:
pcercuei 0:03b5121a232e 11197 * Schema Representation Constraint:
pcercuei 0:03b5121a232e 11198 * Redefinition Constraints and Semantics (src-redefine)
pcercuei 0:03b5121a232e 11199 * (6.1), (6.1.1), (6.1.2)
pcercuei 0:03b5121a232e 11200 *
pcercuei 0:03b5121a232e 11201 * Schema Component Constraint:
pcercuei 0:03b5121a232e 11202 * All Group Limited (cos-all-limited) (2)
pcercuei 0:03b5121a232e 11203 * TODO: Actually this should go to component-level checks,
pcercuei 0:03b5121a232e 11204 * but is done here due to performance. Move it to an other layer
pcercuei 0:03b5121a232e 11205 * is schema construction via an API is implemented.
pcercuei 0:03b5121a232e 11206 *
pcercuei 0:03b5121a232e 11207 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 11208 *
pcercuei 0:03b5121a232e 11209 * Returns -1 in case of error, 0 if the declaration is improper and
pcercuei 0:03b5121a232e 11210 * 1 in case of success.
pcercuei 0:03b5121a232e 11211 */
pcercuei 0:03b5121a232e 11212 static xmlSchemaTreeItemPtr
pcercuei 0:03b5121a232e 11213 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 11214 xmlNodePtr node, xmlSchemaTypeType type,
pcercuei 0:03b5121a232e 11215 int withParticle)
pcercuei 0:03b5121a232e 11216 {
pcercuei 0:03b5121a232e 11217 xmlSchemaModelGroupPtr item;
pcercuei 0:03b5121a232e 11218 xmlSchemaParticlePtr particle = NULL;
pcercuei 0:03b5121a232e 11219 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 11220 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 11221 int min = 1, max = 1, isElemRef, hasRefs = 0;
pcercuei 0:03b5121a232e 11222
pcercuei 0:03b5121a232e 11223 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 11224 return (NULL);
pcercuei 0:03b5121a232e 11225 /*
pcercuei 0:03b5121a232e 11226 * Create a model group with the given compositor.
pcercuei 0:03b5121a232e 11227 */
pcercuei 0:03b5121a232e 11228 item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
pcercuei 0:03b5121a232e 11229 if (item == NULL)
pcercuei 0:03b5121a232e 11230 return (NULL);
pcercuei 0:03b5121a232e 11231
pcercuei 0:03b5121a232e 11232 if (withParticle) {
pcercuei 0:03b5121a232e 11233 if (type == XML_SCHEMA_TYPE_ALL) {
pcercuei 0:03b5121a232e 11234 min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
pcercuei 0:03b5121a232e 11235 max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
pcercuei 0:03b5121a232e 11236 } else {
pcercuei 0:03b5121a232e 11237 /* choice + sequence */
pcercuei 0:03b5121a232e 11238 min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
pcercuei 0:03b5121a232e 11239 max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
pcercuei 0:03b5121a232e 11240 "(xs:nonNegativeInteger | unbounded)");
pcercuei 0:03b5121a232e 11241 }
pcercuei 0:03b5121a232e 11242 xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
pcercuei 0:03b5121a232e 11243 /*
pcercuei 0:03b5121a232e 11244 * Create a particle
pcercuei 0:03b5121a232e 11245 */
pcercuei 0:03b5121a232e 11246 particle = xmlSchemaAddParticle(ctxt, node, min, max);
pcercuei 0:03b5121a232e 11247 if (particle == NULL)
pcercuei 0:03b5121a232e 11248 return (NULL);
pcercuei 0:03b5121a232e 11249 particle->children = (xmlSchemaTreeItemPtr) item;
pcercuei 0:03b5121a232e 11250 /*
pcercuei 0:03b5121a232e 11251 * Check for illegal attributes.
pcercuei 0:03b5121a232e 11252 */
pcercuei 0:03b5121a232e 11253 attr = node->properties;
pcercuei 0:03b5121a232e 11254 while (attr != NULL) {
pcercuei 0:03b5121a232e 11255 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 11256 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 11257 (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
pcercuei 0:03b5121a232e 11258 (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
pcercuei 0:03b5121a232e 11259 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 11260 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 11261 }
pcercuei 0:03b5121a232e 11262 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 11263 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 11264 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 11265 }
pcercuei 0:03b5121a232e 11266 attr = attr->next;
pcercuei 0:03b5121a232e 11267 }
pcercuei 0:03b5121a232e 11268 } else {
pcercuei 0:03b5121a232e 11269 /*
pcercuei 0:03b5121a232e 11270 * Check for illegal attributes.
pcercuei 0:03b5121a232e 11271 */
pcercuei 0:03b5121a232e 11272 attr = node->properties;
pcercuei 0:03b5121a232e 11273 while (attr != NULL) {
pcercuei 0:03b5121a232e 11274 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 11275 if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
pcercuei 0:03b5121a232e 11276 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 11277 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 11278 }
pcercuei 0:03b5121a232e 11279 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 11280 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 11281 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 11282 }
pcercuei 0:03b5121a232e 11283 attr = attr->next;
pcercuei 0:03b5121a232e 11284 }
pcercuei 0:03b5121a232e 11285 }
pcercuei 0:03b5121a232e 11286
pcercuei 0:03b5121a232e 11287 /*
pcercuei 0:03b5121a232e 11288 * Extract and validate attributes.
pcercuei 0:03b5121a232e 11289 */
pcercuei 0:03b5121a232e 11290 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 11291 /*
pcercuei 0:03b5121a232e 11292 * And now for the children...
pcercuei 0:03b5121a232e 11293 */
pcercuei 0:03b5121a232e 11294 child = node->children;
pcercuei 0:03b5121a232e 11295 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 11296 item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
pcercuei 0:03b5121a232e 11297 child = child->next;
pcercuei 0:03b5121a232e 11298 }
pcercuei 0:03b5121a232e 11299 if (type == XML_SCHEMA_TYPE_ALL) {
pcercuei 0:03b5121a232e 11300 xmlSchemaParticlePtr part, last = NULL;
pcercuei 0:03b5121a232e 11301
pcercuei 0:03b5121a232e 11302 while (IS_SCHEMA(child, "element")) {
pcercuei 0:03b5121a232e 11303 part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
pcercuei 0:03b5121a232e 11304 schema, child, &isElemRef, 0);
pcercuei 0:03b5121a232e 11305 /*
pcercuei 0:03b5121a232e 11306 * SPEC cos-all-limited (2)
pcercuei 0:03b5121a232e 11307 * "The {max occurs} of all the particles in the {particles}
pcercuei 0:03b5121a232e 11308 * of the ('all') group must be 0 or 1.
pcercuei 0:03b5121a232e 11309 */
pcercuei 0:03b5121a232e 11310 if (part != NULL) {
pcercuei 0:03b5121a232e 11311 if (isElemRef)
pcercuei 0:03b5121a232e 11312 hasRefs++;
pcercuei 0:03b5121a232e 11313 if (part->minOccurs > 1) {
pcercuei 0:03b5121a232e 11314 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 11315 XML_SCHEMAP_COS_ALL_LIMITED,
pcercuei 0:03b5121a232e 11316 NULL, child,
pcercuei 0:03b5121a232e 11317 "Invalid value for minOccurs (must be 0 or 1)",
pcercuei 0:03b5121a232e 11318 NULL);
pcercuei 0:03b5121a232e 11319 /* Reset to 1. */
pcercuei 0:03b5121a232e 11320 part->minOccurs = 1;
pcercuei 0:03b5121a232e 11321 }
pcercuei 0:03b5121a232e 11322 if (part->maxOccurs > 1) {
pcercuei 0:03b5121a232e 11323 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 11324 XML_SCHEMAP_COS_ALL_LIMITED,
pcercuei 0:03b5121a232e 11325 NULL, child,
pcercuei 0:03b5121a232e 11326 "Invalid value for maxOccurs (must be 0 or 1)",
pcercuei 0:03b5121a232e 11327 NULL);
pcercuei 0:03b5121a232e 11328 /* Reset to 1. */
pcercuei 0:03b5121a232e 11329 part->maxOccurs = 1;
pcercuei 0:03b5121a232e 11330 }
pcercuei 0:03b5121a232e 11331 if (last == NULL)
pcercuei 0:03b5121a232e 11332 item->children = (xmlSchemaTreeItemPtr) part;
pcercuei 0:03b5121a232e 11333 else
pcercuei 0:03b5121a232e 11334 last->next = (xmlSchemaTreeItemPtr) part;
pcercuei 0:03b5121a232e 11335 last = part;
pcercuei 0:03b5121a232e 11336 }
pcercuei 0:03b5121a232e 11337 child = child->next;
pcercuei 0:03b5121a232e 11338 }
pcercuei 0:03b5121a232e 11339 if (child != NULL) {
pcercuei 0:03b5121a232e 11340 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 11341 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 11342 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 11343 "(annotation?, (annotation?, element*)");
pcercuei 0:03b5121a232e 11344 }
pcercuei 0:03b5121a232e 11345 } else {
pcercuei 0:03b5121a232e 11346 /* choice + sequence */
pcercuei 0:03b5121a232e 11347 xmlSchemaTreeItemPtr part = NULL, last = NULL;
pcercuei 0:03b5121a232e 11348
pcercuei 0:03b5121a232e 11349 while ((IS_SCHEMA(child, "element")) ||
pcercuei 0:03b5121a232e 11350 (IS_SCHEMA(child, "group")) ||
pcercuei 0:03b5121a232e 11351 (IS_SCHEMA(child, "any")) ||
pcercuei 0:03b5121a232e 11352 (IS_SCHEMA(child, "choice")) ||
pcercuei 0:03b5121a232e 11353 (IS_SCHEMA(child, "sequence"))) {
pcercuei 0:03b5121a232e 11354
pcercuei 0:03b5121a232e 11355 if (IS_SCHEMA(child, "element")) {
pcercuei 0:03b5121a232e 11356 part = (xmlSchemaTreeItemPtr)
pcercuei 0:03b5121a232e 11357 xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
pcercuei 0:03b5121a232e 11358 if (part && isElemRef)
pcercuei 0:03b5121a232e 11359 hasRefs++;
pcercuei 0:03b5121a232e 11360 } else if (IS_SCHEMA(child, "group")) {
pcercuei 0:03b5121a232e 11361 part =
pcercuei 0:03b5121a232e 11362 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
pcercuei 0:03b5121a232e 11363 if (part != NULL)
pcercuei 0:03b5121a232e 11364 hasRefs++;
pcercuei 0:03b5121a232e 11365 /*
pcercuei 0:03b5121a232e 11366 * Handle redefinitions.
pcercuei 0:03b5121a232e 11367 */
pcercuei 0:03b5121a232e 11368 if (ctxt->isRedefine && ctxt->redef &&
pcercuei 0:03b5121a232e 11369 (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
pcercuei 0:03b5121a232e 11370 part && part->children)
pcercuei 0:03b5121a232e 11371 {
pcercuei 0:03b5121a232e 11372 if ((xmlSchemaGetQNameRefName(part->children) ==
pcercuei 0:03b5121a232e 11373 ctxt->redef->refName) &&
pcercuei 0:03b5121a232e 11374 (xmlSchemaGetQNameRefTargetNs(part->children) ==
pcercuei 0:03b5121a232e 11375 ctxt->redef->refTargetNs))
pcercuei 0:03b5121a232e 11376 {
pcercuei 0:03b5121a232e 11377 /*
pcercuei 0:03b5121a232e 11378 * SPEC src-redefine:
pcercuei 0:03b5121a232e 11379 * (6.1) "If it has a <group> among its contents at
pcercuei 0:03b5121a232e 11380 * some level the `actual value` of whose ref
pcercuei 0:03b5121a232e 11381 * [attribute] is the same as the `actual value` of
pcercuei 0:03b5121a232e 11382 * its own name attribute plus target namespace, then
pcercuei 0:03b5121a232e 11383 * all of the following must be true:"
pcercuei 0:03b5121a232e 11384 * (6.1.1) "It must have exactly one such group."
pcercuei 0:03b5121a232e 11385 */
pcercuei 0:03b5121a232e 11386 if (ctxt->redefCounter != 0) {
pcercuei 0:03b5121a232e 11387 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 11388
pcercuei 0:03b5121a232e 11389 xmlSchemaCustomErr(ACTXT_CAST ctxt,
pcercuei 0:03b5121a232e 11390 XML_SCHEMAP_SRC_REDEFINE, child, NULL,
pcercuei 0:03b5121a232e 11391 "The redefining model group definition "
pcercuei 0:03b5121a232e 11392 "'%s' must not contain more than one "
pcercuei 0:03b5121a232e 11393 "reference to the redefined definition",
pcercuei 0:03b5121a232e 11394 xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 11395 ctxt->redef->refTargetNs,
pcercuei 0:03b5121a232e 11396 ctxt->redef->refName),
pcercuei 0:03b5121a232e 11397 NULL);
pcercuei 0:03b5121a232e 11398 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 11399 part = NULL;
pcercuei 0:03b5121a232e 11400 } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
pcercuei 0:03b5121a232e 11401 ((WXS_PARTICLE(part))->maxOccurs != 1))
pcercuei 0:03b5121a232e 11402 {
pcercuei 0:03b5121a232e 11403 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 11404 /*
pcercuei 0:03b5121a232e 11405 * SPEC src-redefine:
pcercuei 0:03b5121a232e 11406 * (6.1.2) "The `actual value` of both that
pcercuei 0:03b5121a232e 11407 * group's minOccurs and maxOccurs [attribute]
pcercuei 0:03b5121a232e 11408 * must be 1 (or `absent`).
pcercuei 0:03b5121a232e 11409 */
pcercuei 0:03b5121a232e 11410 xmlSchemaCustomErr(ACTXT_CAST ctxt,
pcercuei 0:03b5121a232e 11411 XML_SCHEMAP_SRC_REDEFINE, child, NULL,
pcercuei 0:03b5121a232e 11412 "The redefining model group definition "
pcercuei 0:03b5121a232e 11413 "'%s' must not contain a reference to the "
pcercuei 0:03b5121a232e 11414 "redefined definition with a "
pcercuei 0:03b5121a232e 11415 "maxOccurs/minOccurs other than 1",
pcercuei 0:03b5121a232e 11416 xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 11417 ctxt->redef->refTargetNs,
pcercuei 0:03b5121a232e 11418 ctxt->redef->refName),
pcercuei 0:03b5121a232e 11419 NULL);
pcercuei 0:03b5121a232e 11420 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 11421 part = NULL;
pcercuei 0:03b5121a232e 11422 }
pcercuei 0:03b5121a232e 11423 ctxt->redef->reference = WXS_BASIC_CAST part;
pcercuei 0:03b5121a232e 11424 ctxt->redefCounter++;
pcercuei 0:03b5121a232e 11425 }
pcercuei 0:03b5121a232e 11426 }
pcercuei 0:03b5121a232e 11427 } else if (IS_SCHEMA(child, "any")) {
pcercuei 0:03b5121a232e 11428 part = (xmlSchemaTreeItemPtr)
pcercuei 0:03b5121a232e 11429 xmlSchemaParseAny(ctxt, schema, child);
pcercuei 0:03b5121a232e 11430 } else if (IS_SCHEMA(child, "choice")) {
pcercuei 0:03b5121a232e 11431 part = xmlSchemaParseModelGroup(ctxt, schema, child,
pcercuei 0:03b5121a232e 11432 XML_SCHEMA_TYPE_CHOICE, 1);
pcercuei 0:03b5121a232e 11433 } else if (IS_SCHEMA(child, "sequence")) {
pcercuei 0:03b5121a232e 11434 part = xmlSchemaParseModelGroup(ctxt, schema, child,
pcercuei 0:03b5121a232e 11435 XML_SCHEMA_TYPE_SEQUENCE, 1);
pcercuei 0:03b5121a232e 11436 }
pcercuei 0:03b5121a232e 11437 if (part != NULL) {
pcercuei 0:03b5121a232e 11438 if (last == NULL)
pcercuei 0:03b5121a232e 11439 item->children = part;
pcercuei 0:03b5121a232e 11440 else
pcercuei 0:03b5121a232e 11441 last->next = part;
pcercuei 0:03b5121a232e 11442 last = part;
pcercuei 0:03b5121a232e 11443 }
pcercuei 0:03b5121a232e 11444 child = child->next;
pcercuei 0:03b5121a232e 11445 }
pcercuei 0:03b5121a232e 11446 if (child != NULL) {
pcercuei 0:03b5121a232e 11447 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 11448 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 11449 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 11450 "(annotation?, (element | group | choice | sequence | any)*)");
pcercuei 0:03b5121a232e 11451 }
pcercuei 0:03b5121a232e 11452 }
pcercuei 0:03b5121a232e 11453 if ((max == 0) && (min == 0))
pcercuei 0:03b5121a232e 11454 return (NULL);
pcercuei 0:03b5121a232e 11455 if (hasRefs) {
pcercuei 0:03b5121a232e 11456 /*
pcercuei 0:03b5121a232e 11457 * We need to resolve references.
pcercuei 0:03b5121a232e 11458 */
pcercuei 0:03b5121a232e 11459 WXS_ADD_PENDING(ctxt, item);
pcercuei 0:03b5121a232e 11460 }
pcercuei 0:03b5121a232e 11461 if (withParticle)
pcercuei 0:03b5121a232e 11462 return ((xmlSchemaTreeItemPtr) particle);
pcercuei 0:03b5121a232e 11463 else
pcercuei 0:03b5121a232e 11464 return ((xmlSchemaTreeItemPtr) item);
pcercuei 0:03b5121a232e 11465 }
pcercuei 0:03b5121a232e 11466
pcercuei 0:03b5121a232e 11467 /**
pcercuei 0:03b5121a232e 11468 * xmlSchemaParseRestriction:
pcercuei 0:03b5121a232e 11469 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 11470 * @schema: the schema being built
pcercuei 0:03b5121a232e 11471 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 11472 *
pcercuei 0:03b5121a232e 11473 * parse a XML schema Restriction definition
pcercuei 0:03b5121a232e 11474 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 11475 *
pcercuei 0:03b5121a232e 11476 * Returns the type definition or NULL in case of error
pcercuei 0:03b5121a232e 11477 */
pcercuei 0:03b5121a232e 11478 static xmlSchemaTypePtr
pcercuei 0:03b5121a232e 11479 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 11480 xmlNodePtr node, xmlSchemaTypeType parentType)
pcercuei 0:03b5121a232e 11481 {
pcercuei 0:03b5121a232e 11482 xmlSchemaTypePtr type;
pcercuei 0:03b5121a232e 11483 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 11484 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 11485
pcercuei 0:03b5121a232e 11486 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 11487 return (NULL);
pcercuei 0:03b5121a232e 11488 /* Not a component, don't create it. */
pcercuei 0:03b5121a232e 11489 type = ctxt->ctxtType;
pcercuei 0:03b5121a232e 11490 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
pcercuei 0:03b5121a232e 11491
pcercuei 0:03b5121a232e 11492 /*
pcercuei 0:03b5121a232e 11493 * Check for illegal attributes.
pcercuei 0:03b5121a232e 11494 */
pcercuei 0:03b5121a232e 11495 attr = node->properties;
pcercuei 0:03b5121a232e 11496 while (attr != NULL) {
pcercuei 0:03b5121a232e 11497 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 11498 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 11499 (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
pcercuei 0:03b5121a232e 11500 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 11501 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 11502 }
pcercuei 0:03b5121a232e 11503 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 11504 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 11505 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 11506 }
pcercuei 0:03b5121a232e 11507 attr = attr->next;
pcercuei 0:03b5121a232e 11508 }
pcercuei 0:03b5121a232e 11509 /*
pcercuei 0:03b5121a232e 11510 * Extract and validate attributes.
pcercuei 0:03b5121a232e 11511 */
pcercuei 0:03b5121a232e 11512 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 11513 /*
pcercuei 0:03b5121a232e 11514 * Attribute
pcercuei 0:03b5121a232e 11515 */
pcercuei 0:03b5121a232e 11516 /*
pcercuei 0:03b5121a232e 11517 * Extract the base type. The "base" attribute is mandatory if inside
pcercuei 0:03b5121a232e 11518 * a complex type or if redefining.
pcercuei 0:03b5121a232e 11519 *
pcercuei 0:03b5121a232e 11520 * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
pcercuei 0:03b5121a232e 11521 * among its [children]), the simple type definition which is
pcercuei 0:03b5121a232e 11522 * the {content type} of the type definition `resolved` to by
pcercuei 0:03b5121a232e 11523 * the `actual value` of the base [attribute]"
pcercuei 0:03b5121a232e 11524 */
pcercuei 0:03b5121a232e 11525 if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
pcercuei 0:03b5121a232e 11526 &(type->baseNs), &(type->base)) == 0)
pcercuei 0:03b5121a232e 11527 {
pcercuei 0:03b5121a232e 11528 if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
pcercuei 0:03b5121a232e 11529 xmlSchemaPMissingAttrErr(ctxt,
pcercuei 0:03b5121a232e 11530 XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 11531 NULL, node, "base", NULL);
pcercuei 0:03b5121a232e 11532 } else if ((ctxt->isRedefine) &&
pcercuei 0:03b5121a232e 11533 (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
pcercuei 0:03b5121a232e 11534 {
pcercuei 0:03b5121a232e 11535 if (type->base == NULL) {
pcercuei 0:03b5121a232e 11536 xmlSchemaPMissingAttrErr(ctxt,
pcercuei 0:03b5121a232e 11537 XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 11538 NULL, node, "base", NULL);
pcercuei 0:03b5121a232e 11539 } else if ((! xmlStrEqual(type->base, type->name)) ||
pcercuei 0:03b5121a232e 11540 (! xmlStrEqual(type->baseNs, type->targetNamespace)))
pcercuei 0:03b5121a232e 11541 {
pcercuei 0:03b5121a232e 11542 xmlChar *str1 = NULL, *str2 = NULL;
pcercuei 0:03b5121a232e 11543 /*
pcercuei 0:03b5121a232e 11544 * REDEFINE: SPEC src-redefine (5)
pcercuei 0:03b5121a232e 11545 * "Within the [children], each <simpleType> must have a
pcercuei 0:03b5121a232e 11546 * <restriction> among its [children] ... the `actual value` of
pcercuei 0:03b5121a232e 11547 * whose base [attribute] must be the same as the `actual value`
pcercuei 0:03b5121a232e 11548 * of its own name attribute plus target namespace;"
pcercuei 0:03b5121a232e 11549 */
pcercuei 0:03b5121a232e 11550 xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
pcercuei 0:03b5121a232e 11551 NULL, node, "This is a redefinition, but the QName "
pcercuei 0:03b5121a232e 11552 "value '%s' of the 'base' attribute does not match the "
pcercuei 0:03b5121a232e 11553 "type's designation '%s'",
pcercuei 0:03b5121a232e 11554 xmlSchemaFormatQName(&str1, type->baseNs, type->base),
pcercuei 0:03b5121a232e 11555 xmlSchemaFormatQName(&str2, type->targetNamespace,
pcercuei 0:03b5121a232e 11556 type->name), NULL);
pcercuei 0:03b5121a232e 11557 FREE_AND_NULL(str1);
pcercuei 0:03b5121a232e 11558 FREE_AND_NULL(str2);
pcercuei 0:03b5121a232e 11559 /* Avoid confusion and erase the values. */
pcercuei 0:03b5121a232e 11560 type->base = NULL;
pcercuei 0:03b5121a232e 11561 type->baseNs = NULL;
pcercuei 0:03b5121a232e 11562 }
pcercuei 0:03b5121a232e 11563 }
pcercuei 0:03b5121a232e 11564 }
pcercuei 0:03b5121a232e 11565 /*
pcercuei 0:03b5121a232e 11566 * And now for the children...
pcercuei 0:03b5121a232e 11567 */
pcercuei 0:03b5121a232e 11568 child = node->children;
pcercuei 0:03b5121a232e 11569 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 11570 /*
pcercuei 0:03b5121a232e 11571 * Add the annotation to the simple type ancestor.
pcercuei 0:03b5121a232e 11572 */
pcercuei 0:03b5121a232e 11573 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
pcercuei 0:03b5121a232e 11574 xmlSchemaParseAnnotation(ctxt, child, 1));
pcercuei 0:03b5121a232e 11575 child = child->next;
pcercuei 0:03b5121a232e 11576 }
pcercuei 0:03b5121a232e 11577 if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
pcercuei 0:03b5121a232e 11578 /*
pcercuei 0:03b5121a232e 11579 * Corresponds to <simpleType><restriction><simpleType>.
pcercuei 0:03b5121a232e 11580 */
pcercuei 0:03b5121a232e 11581 if (IS_SCHEMA(child, "simpleType")) {
pcercuei 0:03b5121a232e 11582 if (type->base != NULL) {
pcercuei 0:03b5121a232e 11583 /*
pcercuei 0:03b5121a232e 11584 * src-restriction-base-or-simpleType
pcercuei 0:03b5121a232e 11585 * Either the base [attribute] or the simpleType [child] of the
pcercuei 0:03b5121a232e 11586 * <restriction> element must be present, but not both.
pcercuei 0:03b5121a232e 11587 */
pcercuei 0:03b5121a232e 11588 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 11589 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
pcercuei 0:03b5121a232e 11590 NULL, node, child,
pcercuei 0:03b5121a232e 11591 "The attribute 'base' and the <simpleType> child are "
pcercuei 0:03b5121a232e 11592 "mutually exclusive", NULL);
pcercuei 0:03b5121a232e 11593 } else {
pcercuei 0:03b5121a232e 11594 type->baseType = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 11595 xmlSchemaParseSimpleType(ctxt, schema, child, 0);
pcercuei 0:03b5121a232e 11596 }
pcercuei 0:03b5121a232e 11597 child = child->next;
pcercuei 0:03b5121a232e 11598 } else if (type->base == NULL) {
pcercuei 0:03b5121a232e 11599 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 11600 XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
pcercuei 0:03b5121a232e 11601 NULL, node, child,
pcercuei 0:03b5121a232e 11602 "Either the attribute 'base' or a <simpleType> child "
pcercuei 0:03b5121a232e 11603 "must be present", NULL);
pcercuei 0:03b5121a232e 11604 }
pcercuei 0:03b5121a232e 11605 } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
pcercuei 0:03b5121a232e 11606 /*
pcercuei 0:03b5121a232e 11607 * Corresponds to <complexType><complexContent><restriction>...
pcercuei 0:03b5121a232e 11608 * followed by:
pcercuei 0:03b5121a232e 11609 *
pcercuei 0:03b5121a232e 11610 * Model groups <all>, <choice> and <sequence>.
pcercuei 0:03b5121a232e 11611 */
pcercuei 0:03b5121a232e 11612 if (IS_SCHEMA(child, "all")) {
pcercuei 0:03b5121a232e 11613 type->subtypes = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 11614 xmlSchemaParseModelGroup(ctxt, schema, child,
pcercuei 0:03b5121a232e 11615 XML_SCHEMA_TYPE_ALL, 1);
pcercuei 0:03b5121a232e 11616 child = child->next;
pcercuei 0:03b5121a232e 11617 } else if (IS_SCHEMA(child, "choice")) {
pcercuei 0:03b5121a232e 11618 type->subtypes = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 11619 xmlSchemaParseModelGroup(ctxt,
pcercuei 0:03b5121a232e 11620 schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
pcercuei 0:03b5121a232e 11621 child = child->next;
pcercuei 0:03b5121a232e 11622 } else if (IS_SCHEMA(child, "sequence")) {
pcercuei 0:03b5121a232e 11623 type->subtypes = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 11624 xmlSchemaParseModelGroup(ctxt, schema, child,
pcercuei 0:03b5121a232e 11625 XML_SCHEMA_TYPE_SEQUENCE, 1);
pcercuei 0:03b5121a232e 11626 child = child->next;
pcercuei 0:03b5121a232e 11627 /*
pcercuei 0:03b5121a232e 11628 * Model group reference <group>.
pcercuei 0:03b5121a232e 11629 */
pcercuei 0:03b5121a232e 11630 } else if (IS_SCHEMA(child, "group")) {
pcercuei 0:03b5121a232e 11631 type->subtypes = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 11632 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
pcercuei 0:03b5121a232e 11633 /*
pcercuei 0:03b5121a232e 11634 * Note that the reference will be resolved in
pcercuei 0:03b5121a232e 11635 * xmlSchemaResolveTypeReferences();
pcercuei 0:03b5121a232e 11636 */
pcercuei 0:03b5121a232e 11637 child = child->next;
pcercuei 0:03b5121a232e 11638 }
pcercuei 0:03b5121a232e 11639 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
pcercuei 0:03b5121a232e 11640 /*
pcercuei 0:03b5121a232e 11641 * Corresponds to <complexType><simpleContent><restriction>...
pcercuei 0:03b5121a232e 11642 *
pcercuei 0:03b5121a232e 11643 * "1.1 the simple type definition corresponding to the <simpleType>
pcercuei 0:03b5121a232e 11644 * among the [children] of <restriction> if there is one;"
pcercuei 0:03b5121a232e 11645 */
pcercuei 0:03b5121a232e 11646 if (IS_SCHEMA(child, "simpleType")) {
pcercuei 0:03b5121a232e 11647 /*
pcercuei 0:03b5121a232e 11648 * We will store the to-be-restricted simple type in
pcercuei 0:03b5121a232e 11649 * type->contentTypeDef *temporarily*.
pcercuei 0:03b5121a232e 11650 */
pcercuei 0:03b5121a232e 11651 type->contentTypeDef = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 11652 xmlSchemaParseSimpleType(ctxt, schema, child, 0);
pcercuei 0:03b5121a232e 11653 if ( type->contentTypeDef == NULL)
pcercuei 0:03b5121a232e 11654 return (NULL);
pcercuei 0:03b5121a232e 11655 child = child->next;
pcercuei 0:03b5121a232e 11656 }
pcercuei 0:03b5121a232e 11657 }
pcercuei 0:03b5121a232e 11658
pcercuei 0:03b5121a232e 11659 if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
pcercuei 0:03b5121a232e 11660 (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
pcercuei 0:03b5121a232e 11661 xmlSchemaFacetPtr facet, lastfacet = NULL;
pcercuei 0:03b5121a232e 11662 /*
pcercuei 0:03b5121a232e 11663 * Corresponds to <complexType><simpleContent><restriction>...
pcercuei 0:03b5121a232e 11664 * <simpleType><restriction>...
pcercuei 0:03b5121a232e 11665 */
pcercuei 0:03b5121a232e 11666
pcercuei 0:03b5121a232e 11667 /*
pcercuei 0:03b5121a232e 11668 * Add the facets to the simple type ancestor.
pcercuei 0:03b5121a232e 11669 */
pcercuei 0:03b5121a232e 11670 /*
pcercuei 0:03b5121a232e 11671 * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
pcercuei 0:03b5121a232e 11672 * Simple Type Definition Schema Representation Constraint:
pcercuei 0:03b5121a232e 11673 * *Single Facet Value*
pcercuei 0:03b5121a232e 11674 */
pcercuei 0:03b5121a232e 11675 while ((IS_SCHEMA(child, "minInclusive")) ||
pcercuei 0:03b5121a232e 11676 (IS_SCHEMA(child, "minExclusive")) ||
pcercuei 0:03b5121a232e 11677 (IS_SCHEMA(child, "maxInclusive")) ||
pcercuei 0:03b5121a232e 11678 (IS_SCHEMA(child, "maxExclusive")) ||
pcercuei 0:03b5121a232e 11679 (IS_SCHEMA(child, "totalDigits")) ||
pcercuei 0:03b5121a232e 11680 (IS_SCHEMA(child, "fractionDigits")) ||
pcercuei 0:03b5121a232e 11681 (IS_SCHEMA(child, "pattern")) ||
pcercuei 0:03b5121a232e 11682 (IS_SCHEMA(child, "enumeration")) ||
pcercuei 0:03b5121a232e 11683 (IS_SCHEMA(child, "whiteSpace")) ||
pcercuei 0:03b5121a232e 11684 (IS_SCHEMA(child, "length")) ||
pcercuei 0:03b5121a232e 11685 (IS_SCHEMA(child, "maxLength")) ||
pcercuei 0:03b5121a232e 11686 (IS_SCHEMA(child, "minLength"))) {
pcercuei 0:03b5121a232e 11687 facet = xmlSchemaParseFacet(ctxt, schema, child);
pcercuei 0:03b5121a232e 11688 if (facet != NULL) {
pcercuei 0:03b5121a232e 11689 if (lastfacet == NULL)
pcercuei 0:03b5121a232e 11690 type->facets = facet;
pcercuei 0:03b5121a232e 11691 else
pcercuei 0:03b5121a232e 11692 lastfacet->next = facet;
pcercuei 0:03b5121a232e 11693 lastfacet = facet;
pcercuei 0:03b5121a232e 11694 lastfacet->next = NULL;
pcercuei 0:03b5121a232e 11695 }
pcercuei 0:03b5121a232e 11696 child = child->next;
pcercuei 0:03b5121a232e 11697 }
pcercuei 0:03b5121a232e 11698 /*
pcercuei 0:03b5121a232e 11699 * Create links for derivation and validation.
pcercuei 0:03b5121a232e 11700 */
pcercuei 0:03b5121a232e 11701 if (type->facets != NULL) {
pcercuei 0:03b5121a232e 11702 xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
pcercuei 0:03b5121a232e 11703
pcercuei 0:03b5121a232e 11704 facet = type->facets;
pcercuei 0:03b5121a232e 11705 do {
pcercuei 0:03b5121a232e 11706 facetLink = (xmlSchemaFacetLinkPtr)
pcercuei 0:03b5121a232e 11707 xmlMalloc(sizeof(xmlSchemaFacetLink));
pcercuei 0:03b5121a232e 11708 if (facetLink == NULL) {
pcercuei 0:03b5121a232e 11709 xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
pcercuei 0:03b5121a232e 11710 xmlFree(facetLink);
pcercuei 0:03b5121a232e 11711 return (NULL);
pcercuei 0:03b5121a232e 11712 }
pcercuei 0:03b5121a232e 11713 facetLink->facet = facet;
pcercuei 0:03b5121a232e 11714 facetLink->next = NULL;
pcercuei 0:03b5121a232e 11715 if (lastFacetLink == NULL)
pcercuei 0:03b5121a232e 11716 type->facetSet = facetLink;
pcercuei 0:03b5121a232e 11717 else
pcercuei 0:03b5121a232e 11718 lastFacetLink->next = facetLink;
pcercuei 0:03b5121a232e 11719 lastFacetLink = facetLink;
pcercuei 0:03b5121a232e 11720 facet = facet->next;
pcercuei 0:03b5121a232e 11721 } while (facet != NULL);
pcercuei 0:03b5121a232e 11722 }
pcercuei 0:03b5121a232e 11723 }
pcercuei 0:03b5121a232e 11724 if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
pcercuei 0:03b5121a232e 11725 /*
pcercuei 0:03b5121a232e 11726 * Attribute uses/declarations.
pcercuei 0:03b5121a232e 11727 */
pcercuei 0:03b5121a232e 11728 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
pcercuei 0:03b5121a232e 11729 (xmlSchemaItemListPtr *) &(type->attrUses),
pcercuei 0:03b5121a232e 11730 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
pcercuei 0:03b5121a232e 11731 return(NULL);
pcercuei 0:03b5121a232e 11732 /*
pcercuei 0:03b5121a232e 11733 * Attribute wildcard.
pcercuei 0:03b5121a232e 11734 */
pcercuei 0:03b5121a232e 11735 if (IS_SCHEMA(child, "anyAttribute")) {
pcercuei 0:03b5121a232e 11736 type->attributeWildcard =
pcercuei 0:03b5121a232e 11737 xmlSchemaParseAnyAttribute(ctxt, schema, child);
pcercuei 0:03b5121a232e 11738 child = child->next;
pcercuei 0:03b5121a232e 11739 }
pcercuei 0:03b5121a232e 11740 }
pcercuei 0:03b5121a232e 11741 if (child != NULL) {
pcercuei 0:03b5121a232e 11742 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
pcercuei 0:03b5121a232e 11743 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 11744 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 11745 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 11746 "annotation?, (group | all | choice | sequence)?, "
pcercuei 0:03b5121a232e 11747 "((attribute | attributeGroup)*, anyAttribute?))");
pcercuei 0:03b5121a232e 11748 } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
pcercuei 0:03b5121a232e 11749 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 11750 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 11751 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 11752 "(annotation?, (simpleType?, (minExclusive | minInclusive | "
pcercuei 0:03b5121a232e 11753 "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
pcercuei 0:03b5121a232e 11754 "length | minLength | maxLength | enumeration | whiteSpace | "
pcercuei 0:03b5121a232e 11755 "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
pcercuei 0:03b5121a232e 11756 } else {
pcercuei 0:03b5121a232e 11757 /* Simple type */
pcercuei 0:03b5121a232e 11758 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 11759 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 11760 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 11761 "(annotation?, (simpleType?, (minExclusive | minInclusive | "
pcercuei 0:03b5121a232e 11762 "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
pcercuei 0:03b5121a232e 11763 "length | minLength | maxLength | enumeration | whiteSpace | "
pcercuei 0:03b5121a232e 11764 "pattern)*))");
pcercuei 0:03b5121a232e 11765 }
pcercuei 0:03b5121a232e 11766 }
pcercuei 0:03b5121a232e 11767 return (NULL);
pcercuei 0:03b5121a232e 11768 }
pcercuei 0:03b5121a232e 11769
pcercuei 0:03b5121a232e 11770 /**
pcercuei 0:03b5121a232e 11771 * xmlSchemaParseExtension:
pcercuei 0:03b5121a232e 11772 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 11773 * @schema: the schema being built
pcercuei 0:03b5121a232e 11774 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 11775 *
pcercuei 0:03b5121a232e 11776 * Parses an <extension>, which is found inside a
pcercuei 0:03b5121a232e 11777 * <simpleContent> or <complexContent>.
pcercuei 0:03b5121a232e 11778 * *WARNING* this interface is highly subject to change.
pcercuei 0:03b5121a232e 11779 *
pcercuei 0:03b5121a232e 11780 * TODO: Returns the type definition or NULL in case of error
pcercuei 0:03b5121a232e 11781 */
pcercuei 0:03b5121a232e 11782 static xmlSchemaTypePtr
pcercuei 0:03b5121a232e 11783 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 11784 xmlNodePtr node, xmlSchemaTypeType parentType)
pcercuei 0:03b5121a232e 11785 {
pcercuei 0:03b5121a232e 11786 xmlSchemaTypePtr type;
pcercuei 0:03b5121a232e 11787 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 11788 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 11789
pcercuei 0:03b5121a232e 11790 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 11791 return (NULL);
pcercuei 0:03b5121a232e 11792 /* Not a component, don't create it. */
pcercuei 0:03b5121a232e 11793 type = ctxt->ctxtType;
pcercuei 0:03b5121a232e 11794 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
pcercuei 0:03b5121a232e 11795
pcercuei 0:03b5121a232e 11796 /*
pcercuei 0:03b5121a232e 11797 * Check for illegal attributes.
pcercuei 0:03b5121a232e 11798 */
pcercuei 0:03b5121a232e 11799 attr = node->properties;
pcercuei 0:03b5121a232e 11800 while (attr != NULL) {
pcercuei 0:03b5121a232e 11801 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 11802 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 11803 (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
pcercuei 0:03b5121a232e 11804 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 11805 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 11806 }
pcercuei 0:03b5121a232e 11807 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 11808 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 11809 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 11810 }
pcercuei 0:03b5121a232e 11811 attr = attr->next;
pcercuei 0:03b5121a232e 11812 }
pcercuei 0:03b5121a232e 11813
pcercuei 0:03b5121a232e 11814 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 11815
pcercuei 0:03b5121a232e 11816 /*
pcercuei 0:03b5121a232e 11817 * Attribute "base" - mandatory.
pcercuei 0:03b5121a232e 11818 */
pcercuei 0:03b5121a232e 11819 if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
pcercuei 0:03b5121a232e 11820 "base", &(type->baseNs), &(type->base)) == 0) &&
pcercuei 0:03b5121a232e 11821 (type->base == NULL)) {
pcercuei 0:03b5121a232e 11822 xmlSchemaPMissingAttrErr(ctxt,
pcercuei 0:03b5121a232e 11823 XML_SCHEMAP_S4S_ATTR_MISSING,
pcercuei 0:03b5121a232e 11824 NULL, node, "base", NULL);
pcercuei 0:03b5121a232e 11825 }
pcercuei 0:03b5121a232e 11826 /*
pcercuei 0:03b5121a232e 11827 * And now for the children...
pcercuei 0:03b5121a232e 11828 */
pcercuei 0:03b5121a232e 11829 child = node->children;
pcercuei 0:03b5121a232e 11830 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 11831 /*
pcercuei 0:03b5121a232e 11832 * Add the annotation to the type ancestor.
pcercuei 0:03b5121a232e 11833 */
pcercuei 0:03b5121a232e 11834 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
pcercuei 0:03b5121a232e 11835 xmlSchemaParseAnnotation(ctxt, child, 1));
pcercuei 0:03b5121a232e 11836 child = child->next;
pcercuei 0:03b5121a232e 11837 }
pcercuei 0:03b5121a232e 11838 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
pcercuei 0:03b5121a232e 11839 /*
pcercuei 0:03b5121a232e 11840 * Corresponds to <complexType><complexContent><extension>... and:
pcercuei 0:03b5121a232e 11841 *
pcercuei 0:03b5121a232e 11842 * Model groups <all>, <choice>, <sequence> and <group>.
pcercuei 0:03b5121a232e 11843 */
pcercuei 0:03b5121a232e 11844 if (IS_SCHEMA(child, "all")) {
pcercuei 0:03b5121a232e 11845 type->subtypes = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 11846 xmlSchemaParseModelGroup(ctxt, schema,
pcercuei 0:03b5121a232e 11847 child, XML_SCHEMA_TYPE_ALL, 1);
pcercuei 0:03b5121a232e 11848 child = child->next;
pcercuei 0:03b5121a232e 11849 } else if (IS_SCHEMA(child, "choice")) {
pcercuei 0:03b5121a232e 11850 type->subtypes = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 11851 xmlSchemaParseModelGroup(ctxt, schema,
pcercuei 0:03b5121a232e 11852 child, XML_SCHEMA_TYPE_CHOICE, 1);
pcercuei 0:03b5121a232e 11853 child = child->next;
pcercuei 0:03b5121a232e 11854 } else if (IS_SCHEMA(child, "sequence")) {
pcercuei 0:03b5121a232e 11855 type->subtypes = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 11856 xmlSchemaParseModelGroup(ctxt, schema,
pcercuei 0:03b5121a232e 11857 child, XML_SCHEMA_TYPE_SEQUENCE, 1);
pcercuei 0:03b5121a232e 11858 child = child->next;
pcercuei 0:03b5121a232e 11859 } else if (IS_SCHEMA(child, "group")) {
pcercuei 0:03b5121a232e 11860 type->subtypes = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 11861 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
pcercuei 0:03b5121a232e 11862 /*
pcercuei 0:03b5121a232e 11863 * Note that the reference will be resolved in
pcercuei 0:03b5121a232e 11864 * xmlSchemaResolveTypeReferences();
pcercuei 0:03b5121a232e 11865 */
pcercuei 0:03b5121a232e 11866 child = child->next;
pcercuei 0:03b5121a232e 11867 }
pcercuei 0:03b5121a232e 11868 }
pcercuei 0:03b5121a232e 11869 if (child != NULL) {
pcercuei 0:03b5121a232e 11870 /*
pcercuei 0:03b5121a232e 11871 * Attribute uses/declarations.
pcercuei 0:03b5121a232e 11872 */
pcercuei 0:03b5121a232e 11873 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
pcercuei 0:03b5121a232e 11874 (xmlSchemaItemListPtr *) &(type->attrUses),
pcercuei 0:03b5121a232e 11875 XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
pcercuei 0:03b5121a232e 11876 return(NULL);
pcercuei 0:03b5121a232e 11877 /*
pcercuei 0:03b5121a232e 11878 * Attribute wildcard.
pcercuei 0:03b5121a232e 11879 */
pcercuei 0:03b5121a232e 11880 if (IS_SCHEMA(child, "anyAttribute")) {
pcercuei 0:03b5121a232e 11881 ctxt->ctxtType->attributeWildcard =
pcercuei 0:03b5121a232e 11882 xmlSchemaParseAnyAttribute(ctxt, schema, child);
pcercuei 0:03b5121a232e 11883 child = child->next;
pcercuei 0:03b5121a232e 11884 }
pcercuei 0:03b5121a232e 11885 }
pcercuei 0:03b5121a232e 11886 if (child != NULL) {
pcercuei 0:03b5121a232e 11887 if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
pcercuei 0:03b5121a232e 11888 /* Complex content extension. */
pcercuei 0:03b5121a232e 11889 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 11890 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 11891 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 11892 "(annotation?, ((group | all | choice | sequence)?, "
pcercuei 0:03b5121a232e 11893 "((attribute | attributeGroup)*, anyAttribute?)))");
pcercuei 0:03b5121a232e 11894 } else {
pcercuei 0:03b5121a232e 11895 /* Simple content extension. */
pcercuei 0:03b5121a232e 11896 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 11897 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 11898 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 11899 "(annotation?, ((attribute | attributeGroup)*, "
pcercuei 0:03b5121a232e 11900 "anyAttribute?))");
pcercuei 0:03b5121a232e 11901 }
pcercuei 0:03b5121a232e 11902 }
pcercuei 0:03b5121a232e 11903 return (NULL);
pcercuei 0:03b5121a232e 11904 }
pcercuei 0:03b5121a232e 11905
pcercuei 0:03b5121a232e 11906 /**
pcercuei 0:03b5121a232e 11907 * xmlSchemaParseSimpleContent:
pcercuei 0:03b5121a232e 11908 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 11909 * @schema: the schema being built
pcercuei 0:03b5121a232e 11910 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 11911 *
pcercuei 0:03b5121a232e 11912 * parse a XML schema SimpleContent definition
pcercuei 0:03b5121a232e 11913 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 11914 *
pcercuei 0:03b5121a232e 11915 * Returns the type definition or NULL in case of error
pcercuei 0:03b5121a232e 11916 */
pcercuei 0:03b5121a232e 11917 static int
pcercuei 0:03b5121a232e 11918 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 11919 xmlSchemaPtr schema, xmlNodePtr node,
pcercuei 0:03b5121a232e 11920 int *hasRestrictionOrExtension)
pcercuei 0:03b5121a232e 11921 {
pcercuei 0:03b5121a232e 11922 xmlSchemaTypePtr type;
pcercuei 0:03b5121a232e 11923 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 11924 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 11925
pcercuei 0:03b5121a232e 11926 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
pcercuei 0:03b5121a232e 11927 (hasRestrictionOrExtension == NULL))
pcercuei 0:03b5121a232e 11928 return (-1);
pcercuei 0:03b5121a232e 11929 *hasRestrictionOrExtension = 0;
pcercuei 0:03b5121a232e 11930 /* Not a component, don't create it. */
pcercuei 0:03b5121a232e 11931 type = ctxt->ctxtType;
pcercuei 0:03b5121a232e 11932 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
pcercuei 0:03b5121a232e 11933 /*
pcercuei 0:03b5121a232e 11934 * Check for illegal attributes.
pcercuei 0:03b5121a232e 11935 */
pcercuei 0:03b5121a232e 11936 attr = node->properties;
pcercuei 0:03b5121a232e 11937 while (attr != NULL) {
pcercuei 0:03b5121a232e 11938 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 11939 if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
pcercuei 0:03b5121a232e 11940 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 11941 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 11942 }
pcercuei 0:03b5121a232e 11943 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 11944 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 11945 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 11946 }
pcercuei 0:03b5121a232e 11947 attr = attr->next;
pcercuei 0:03b5121a232e 11948 }
pcercuei 0:03b5121a232e 11949
pcercuei 0:03b5121a232e 11950 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 11951
pcercuei 0:03b5121a232e 11952 /*
pcercuei 0:03b5121a232e 11953 * And now for the children...
pcercuei 0:03b5121a232e 11954 */
pcercuei 0:03b5121a232e 11955 child = node->children;
pcercuei 0:03b5121a232e 11956 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 11957 /*
pcercuei 0:03b5121a232e 11958 * Add the annotation to the complex type ancestor.
pcercuei 0:03b5121a232e 11959 */
pcercuei 0:03b5121a232e 11960 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
pcercuei 0:03b5121a232e 11961 xmlSchemaParseAnnotation(ctxt, child, 1));
pcercuei 0:03b5121a232e 11962 child = child->next;
pcercuei 0:03b5121a232e 11963 }
pcercuei 0:03b5121a232e 11964 if (child == NULL) {
pcercuei 0:03b5121a232e 11965 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 11966 XML_SCHEMAP_S4S_ELEM_MISSING,
pcercuei 0:03b5121a232e 11967 NULL, node, NULL, NULL,
pcercuei 0:03b5121a232e 11968 "(annotation?, (restriction | extension))");
pcercuei 0:03b5121a232e 11969 }
pcercuei 0:03b5121a232e 11970 if (child == NULL) {
pcercuei 0:03b5121a232e 11971 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 11972 XML_SCHEMAP_S4S_ELEM_MISSING,
pcercuei 0:03b5121a232e 11973 NULL, node, NULL, NULL,
pcercuei 0:03b5121a232e 11974 "(annotation?, (restriction | extension))");
pcercuei 0:03b5121a232e 11975 }
pcercuei 0:03b5121a232e 11976 if (IS_SCHEMA(child, "restriction")) {
pcercuei 0:03b5121a232e 11977 xmlSchemaParseRestriction(ctxt, schema, child,
pcercuei 0:03b5121a232e 11978 XML_SCHEMA_TYPE_SIMPLE_CONTENT);
pcercuei 0:03b5121a232e 11979 (*hasRestrictionOrExtension) = 1;
pcercuei 0:03b5121a232e 11980 child = child->next;
pcercuei 0:03b5121a232e 11981 } else if (IS_SCHEMA(child, "extension")) {
pcercuei 0:03b5121a232e 11982 xmlSchemaParseExtension(ctxt, schema, child,
pcercuei 0:03b5121a232e 11983 XML_SCHEMA_TYPE_SIMPLE_CONTENT);
pcercuei 0:03b5121a232e 11984 (*hasRestrictionOrExtension) = 1;
pcercuei 0:03b5121a232e 11985 child = child->next;
pcercuei 0:03b5121a232e 11986 }
pcercuei 0:03b5121a232e 11987 if (child != NULL) {
pcercuei 0:03b5121a232e 11988 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 11989 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 11990 NULL, node, child, NULL,
pcercuei 0:03b5121a232e 11991 "(annotation?, (restriction | extension))");
pcercuei 0:03b5121a232e 11992 }
pcercuei 0:03b5121a232e 11993 return (0);
pcercuei 0:03b5121a232e 11994 }
pcercuei 0:03b5121a232e 11995
pcercuei 0:03b5121a232e 11996 /**
pcercuei 0:03b5121a232e 11997 * xmlSchemaParseComplexContent:
pcercuei 0:03b5121a232e 11998 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 11999 * @schema: the schema being built
pcercuei 0:03b5121a232e 12000 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 12001 *
pcercuei 0:03b5121a232e 12002 * parse a XML schema ComplexContent definition
pcercuei 0:03b5121a232e 12003 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 12004 *
pcercuei 0:03b5121a232e 12005 * Returns the type definition or NULL in case of error
pcercuei 0:03b5121a232e 12006 */
pcercuei 0:03b5121a232e 12007 static int
pcercuei 0:03b5121a232e 12008 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 12009 xmlSchemaPtr schema, xmlNodePtr node,
pcercuei 0:03b5121a232e 12010 int *hasRestrictionOrExtension)
pcercuei 0:03b5121a232e 12011 {
pcercuei 0:03b5121a232e 12012 xmlSchemaTypePtr type;
pcercuei 0:03b5121a232e 12013 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 12014 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 12015
pcercuei 0:03b5121a232e 12016 if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
pcercuei 0:03b5121a232e 12017 (hasRestrictionOrExtension == NULL))
pcercuei 0:03b5121a232e 12018 return (-1);
pcercuei 0:03b5121a232e 12019 *hasRestrictionOrExtension = 0;
pcercuei 0:03b5121a232e 12020 /* Not a component, don't create it. */
pcercuei 0:03b5121a232e 12021 type = ctxt->ctxtType;
pcercuei 0:03b5121a232e 12022 /*
pcercuei 0:03b5121a232e 12023 * Check for illegal attributes.
pcercuei 0:03b5121a232e 12024 */
pcercuei 0:03b5121a232e 12025 attr = node->properties;
pcercuei 0:03b5121a232e 12026 while (attr != NULL) {
pcercuei 0:03b5121a232e 12027 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 12028 if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
pcercuei 0:03b5121a232e 12029 (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
pcercuei 0:03b5121a232e 12030 {
pcercuei 0:03b5121a232e 12031 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 12032 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 12033 }
pcercuei 0:03b5121a232e 12034 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 12035 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 12036 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 12037 }
pcercuei 0:03b5121a232e 12038 attr = attr->next;
pcercuei 0:03b5121a232e 12039 }
pcercuei 0:03b5121a232e 12040
pcercuei 0:03b5121a232e 12041 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 12042
pcercuei 0:03b5121a232e 12043 /*
pcercuei 0:03b5121a232e 12044 * Set the 'mixed' on the complex type ancestor.
pcercuei 0:03b5121a232e 12045 */
pcercuei 0:03b5121a232e 12046 if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) {
pcercuei 0:03b5121a232e 12047 if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
pcercuei 0:03b5121a232e 12048 type->flags |= XML_SCHEMAS_TYPE_MIXED;
pcercuei 0:03b5121a232e 12049 }
pcercuei 0:03b5121a232e 12050 child = node->children;
pcercuei 0:03b5121a232e 12051 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 12052 /*
pcercuei 0:03b5121a232e 12053 * Add the annotation to the complex type ancestor.
pcercuei 0:03b5121a232e 12054 */
pcercuei 0:03b5121a232e 12055 xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
pcercuei 0:03b5121a232e 12056 xmlSchemaParseAnnotation(ctxt, child, 1));
pcercuei 0:03b5121a232e 12057 child = child->next;
pcercuei 0:03b5121a232e 12058 }
pcercuei 0:03b5121a232e 12059 if (child == NULL) {
pcercuei 0:03b5121a232e 12060 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 12061 XML_SCHEMAP_S4S_ELEM_MISSING,
pcercuei 0:03b5121a232e 12062 NULL, node, NULL,
pcercuei 0:03b5121a232e 12063 NULL, "(annotation?, (restriction | extension))");
pcercuei 0:03b5121a232e 12064 }
pcercuei 0:03b5121a232e 12065 if (child == NULL) {
pcercuei 0:03b5121a232e 12066 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 12067 XML_SCHEMAP_S4S_ELEM_MISSING,
pcercuei 0:03b5121a232e 12068 NULL, node, NULL,
pcercuei 0:03b5121a232e 12069 NULL, "(annotation?, (restriction | extension))");
pcercuei 0:03b5121a232e 12070 }
pcercuei 0:03b5121a232e 12071 if (IS_SCHEMA(child, "restriction")) {
pcercuei 0:03b5121a232e 12072 xmlSchemaParseRestriction(ctxt, schema, child,
pcercuei 0:03b5121a232e 12073 XML_SCHEMA_TYPE_COMPLEX_CONTENT);
pcercuei 0:03b5121a232e 12074 (*hasRestrictionOrExtension) = 1;
pcercuei 0:03b5121a232e 12075 child = child->next;
pcercuei 0:03b5121a232e 12076 } else if (IS_SCHEMA(child, "extension")) {
pcercuei 0:03b5121a232e 12077 xmlSchemaParseExtension(ctxt, schema, child,
pcercuei 0:03b5121a232e 12078 XML_SCHEMA_TYPE_COMPLEX_CONTENT);
pcercuei 0:03b5121a232e 12079 (*hasRestrictionOrExtension) = 1;
pcercuei 0:03b5121a232e 12080 child = child->next;
pcercuei 0:03b5121a232e 12081 }
pcercuei 0:03b5121a232e 12082 if (child != NULL) {
pcercuei 0:03b5121a232e 12083 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 12084 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 12085 NULL, node, child,
pcercuei 0:03b5121a232e 12086 NULL, "(annotation?, (restriction | extension))");
pcercuei 0:03b5121a232e 12087 }
pcercuei 0:03b5121a232e 12088 return (0);
pcercuei 0:03b5121a232e 12089 }
pcercuei 0:03b5121a232e 12090
pcercuei 0:03b5121a232e 12091 /**
pcercuei 0:03b5121a232e 12092 * xmlSchemaParseComplexType:
pcercuei 0:03b5121a232e 12093 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 12094 * @schema: the schema being built
pcercuei 0:03b5121a232e 12095 * @node: a subtree containing XML Schema informations
pcercuei 0:03b5121a232e 12096 *
pcercuei 0:03b5121a232e 12097 * parse a XML schema Complex Type definition
pcercuei 0:03b5121a232e 12098 * *WARNING* this interface is highly subject to change
pcercuei 0:03b5121a232e 12099 *
pcercuei 0:03b5121a232e 12100 * Returns the type definition or NULL in case of error
pcercuei 0:03b5121a232e 12101 */
pcercuei 0:03b5121a232e 12102 static xmlSchemaTypePtr
pcercuei 0:03b5121a232e 12103 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 12104 xmlNodePtr node, int topLevel)
pcercuei 0:03b5121a232e 12105 {
pcercuei 0:03b5121a232e 12106 xmlSchemaTypePtr type, ctxtType;
pcercuei 0:03b5121a232e 12107 xmlNodePtr child = NULL;
pcercuei 0:03b5121a232e 12108 const xmlChar *name = NULL;
pcercuei 0:03b5121a232e 12109 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 12110 const xmlChar *attrValue;
pcercuei 0:03b5121a232e 12111 #ifdef ENABLE_NAMED_LOCALS
pcercuei 0:03b5121a232e 12112 char buf[40];
pcercuei 0:03b5121a232e 12113 #endif
pcercuei 0:03b5121a232e 12114 int final = 0, block = 0, hasRestrictionOrExtension = 0;
pcercuei 0:03b5121a232e 12115
pcercuei 0:03b5121a232e 12116
pcercuei 0:03b5121a232e 12117 if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
pcercuei 0:03b5121a232e 12118 return (NULL);
pcercuei 0:03b5121a232e 12119
pcercuei 0:03b5121a232e 12120 ctxtType = ctxt->ctxtType;
pcercuei 0:03b5121a232e 12121
pcercuei 0:03b5121a232e 12122 if (topLevel) {
pcercuei 0:03b5121a232e 12123 attr = xmlSchemaGetPropNode(node, "name");
pcercuei 0:03b5121a232e 12124 if (attr == NULL) {
pcercuei 0:03b5121a232e 12125 xmlSchemaPMissingAttrErr(ctxt,
pcercuei 0:03b5121a232e 12126 XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
pcercuei 0:03b5121a232e 12127 return (NULL);
pcercuei 0:03b5121a232e 12128 } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
pcercuei 0:03b5121a232e 12129 xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
pcercuei 0:03b5121a232e 12130 return (NULL);
pcercuei 0:03b5121a232e 12131 }
pcercuei 0:03b5121a232e 12132 }
pcercuei 0:03b5121a232e 12133
pcercuei 0:03b5121a232e 12134 if (topLevel == 0) {
pcercuei 0:03b5121a232e 12135 /*
pcercuei 0:03b5121a232e 12136 * Parse as local complex type definition.
pcercuei 0:03b5121a232e 12137 */
pcercuei 0:03b5121a232e 12138 #ifdef ENABLE_NAMED_LOCALS
pcercuei 0:03b5121a232e 12139 snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
pcercuei 0:03b5121a232e 12140 type = xmlSchemaAddType(ctxt, schema,
pcercuei 0:03b5121a232e 12141 XML_SCHEMA_TYPE_COMPLEX,
pcercuei 0:03b5121a232e 12142 xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
pcercuei 0:03b5121a232e 12143 ctxt->targetNamespace, node, 0);
pcercuei 0:03b5121a232e 12144 #else
pcercuei 0:03b5121a232e 12145 type = xmlSchemaAddType(ctxt, schema,
pcercuei 0:03b5121a232e 12146 XML_SCHEMA_TYPE_COMPLEX,
pcercuei 0:03b5121a232e 12147 NULL, ctxt->targetNamespace, node, 0);
pcercuei 0:03b5121a232e 12148 #endif
pcercuei 0:03b5121a232e 12149 if (type == NULL)
pcercuei 0:03b5121a232e 12150 return (NULL);
pcercuei 0:03b5121a232e 12151 name = type->name;
pcercuei 0:03b5121a232e 12152 type->node = node;
pcercuei 0:03b5121a232e 12153 type->type = XML_SCHEMA_TYPE_COMPLEX;
pcercuei 0:03b5121a232e 12154 /*
pcercuei 0:03b5121a232e 12155 * TODO: We need the target namespace.
pcercuei 0:03b5121a232e 12156 */
pcercuei 0:03b5121a232e 12157 } else {
pcercuei 0:03b5121a232e 12158 /*
pcercuei 0:03b5121a232e 12159 * Parse as global complex type definition.
pcercuei 0:03b5121a232e 12160 */
pcercuei 0:03b5121a232e 12161 type = xmlSchemaAddType(ctxt, schema,
pcercuei 0:03b5121a232e 12162 XML_SCHEMA_TYPE_COMPLEX,
pcercuei 0:03b5121a232e 12163 name, ctxt->targetNamespace, node, 1);
pcercuei 0:03b5121a232e 12164 if (type == NULL)
pcercuei 0:03b5121a232e 12165 return (NULL);
pcercuei 0:03b5121a232e 12166 type->node = node;
pcercuei 0:03b5121a232e 12167 type->type = XML_SCHEMA_TYPE_COMPLEX;
pcercuei 0:03b5121a232e 12168 type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
pcercuei 0:03b5121a232e 12169 }
pcercuei 0:03b5121a232e 12170 type->targetNamespace = ctxt->targetNamespace;
pcercuei 0:03b5121a232e 12171 /*
pcercuei 0:03b5121a232e 12172 * Handle attributes.
pcercuei 0:03b5121a232e 12173 */
pcercuei 0:03b5121a232e 12174 attr = node->properties;
pcercuei 0:03b5121a232e 12175 while (attr != NULL) {
pcercuei 0:03b5121a232e 12176 if (attr->ns == NULL) {
pcercuei 0:03b5121a232e 12177 if (xmlStrEqual(attr->name, BAD_CAST "id")) {
pcercuei 0:03b5121a232e 12178 /*
pcercuei 0:03b5121a232e 12179 * Attribute "id".
pcercuei 0:03b5121a232e 12180 */
pcercuei 0:03b5121a232e 12181 xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
pcercuei 0:03b5121a232e 12182 } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
pcercuei 0:03b5121a232e 12183 /*
pcercuei 0:03b5121a232e 12184 * Attribute "mixed".
pcercuei 0:03b5121a232e 12185 */
pcercuei 0:03b5121a232e 12186 if (xmlSchemaPGetBoolNodeValue(ctxt,
pcercuei 0:03b5121a232e 12187 NULL, (xmlNodePtr) attr))
pcercuei 0:03b5121a232e 12188 type->flags |= XML_SCHEMAS_TYPE_MIXED;
pcercuei 0:03b5121a232e 12189 } else if (topLevel) {
pcercuei 0:03b5121a232e 12190 /*
pcercuei 0:03b5121a232e 12191 * Attributes of global complex type definitions.
pcercuei 0:03b5121a232e 12192 */
pcercuei 0:03b5121a232e 12193 if (xmlStrEqual(attr->name, BAD_CAST "name")) {
pcercuei 0:03b5121a232e 12194 /* Pass. */
pcercuei 0:03b5121a232e 12195 } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
pcercuei 0:03b5121a232e 12196 /*
pcercuei 0:03b5121a232e 12197 * Attribute "abstract".
pcercuei 0:03b5121a232e 12198 */
pcercuei 0:03b5121a232e 12199 if (xmlSchemaPGetBoolNodeValue(ctxt,
pcercuei 0:03b5121a232e 12200 NULL, (xmlNodePtr) attr))
pcercuei 0:03b5121a232e 12201 type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
pcercuei 0:03b5121a232e 12202 } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
pcercuei 0:03b5121a232e 12203 /*
pcercuei 0:03b5121a232e 12204 * Attribute "final".
pcercuei 0:03b5121a232e 12205 */
pcercuei 0:03b5121a232e 12206 attrValue = xmlSchemaGetNodeContent(ctxt,
pcercuei 0:03b5121a232e 12207 (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 12208 if (xmlSchemaPValAttrBlockFinal(attrValue,
pcercuei 0:03b5121a232e 12209 &(type->flags),
pcercuei 0:03b5121a232e 12210 -1,
pcercuei 0:03b5121a232e 12211 XML_SCHEMAS_TYPE_FINAL_EXTENSION,
pcercuei 0:03b5121a232e 12212 XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
pcercuei 0:03b5121a232e 12213 -1, -1, -1) != 0)
pcercuei 0:03b5121a232e 12214 {
pcercuei 0:03b5121a232e 12215 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 12216 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 12217 NULL, (xmlNodePtr) attr, NULL,
pcercuei 0:03b5121a232e 12218 "(#all | List of (extension | restriction))",
pcercuei 0:03b5121a232e 12219 attrValue, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 12220 } else
pcercuei 0:03b5121a232e 12221 final = 1;
pcercuei 0:03b5121a232e 12222 } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
pcercuei 0:03b5121a232e 12223 /*
pcercuei 0:03b5121a232e 12224 * Attribute "block".
pcercuei 0:03b5121a232e 12225 */
pcercuei 0:03b5121a232e 12226 attrValue = xmlSchemaGetNodeContent(ctxt,
pcercuei 0:03b5121a232e 12227 (xmlNodePtr) attr);
pcercuei 0:03b5121a232e 12228 if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
pcercuei 0:03b5121a232e 12229 -1,
pcercuei 0:03b5121a232e 12230 XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
pcercuei 0:03b5121a232e 12231 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
pcercuei 0:03b5121a232e 12232 -1, -1, -1) != 0) {
pcercuei 0:03b5121a232e 12233 xmlSchemaPSimpleTypeErr(ctxt,
pcercuei 0:03b5121a232e 12234 XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
pcercuei 0:03b5121a232e 12235 NULL, (xmlNodePtr) attr, NULL,
pcercuei 0:03b5121a232e 12236 "(#all | List of (extension | restriction)) ",
pcercuei 0:03b5121a232e 12237 attrValue, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 12238 } else
pcercuei 0:03b5121a232e 12239 block = 1;
pcercuei 0:03b5121a232e 12240 } else {
pcercuei 0:03b5121a232e 12241 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 12242 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 12243 }
pcercuei 0:03b5121a232e 12244 } else {
pcercuei 0:03b5121a232e 12245 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 12246 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 12247 }
pcercuei 0:03b5121a232e 12248 } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
pcercuei 0:03b5121a232e 12249 xmlSchemaPIllegalAttrErr(ctxt,
pcercuei 0:03b5121a232e 12250 XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
pcercuei 0:03b5121a232e 12251 }
pcercuei 0:03b5121a232e 12252 attr = attr->next;
pcercuei 0:03b5121a232e 12253 }
pcercuei 0:03b5121a232e 12254 if (! block) {
pcercuei 0:03b5121a232e 12255 /*
pcercuei 0:03b5121a232e 12256 * Apply default "block" values.
pcercuei 0:03b5121a232e 12257 */
pcercuei 0:03b5121a232e 12258 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
pcercuei 0:03b5121a232e 12259 type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
pcercuei 0:03b5121a232e 12260 if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
pcercuei 0:03b5121a232e 12261 type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
pcercuei 0:03b5121a232e 12262 }
pcercuei 0:03b5121a232e 12263 if (! final) {
pcercuei 0:03b5121a232e 12264 /*
pcercuei 0:03b5121a232e 12265 * Apply default "block" values.
pcercuei 0:03b5121a232e 12266 */
pcercuei 0:03b5121a232e 12267 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
pcercuei 0:03b5121a232e 12268 type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
pcercuei 0:03b5121a232e 12269 if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
pcercuei 0:03b5121a232e 12270 type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
pcercuei 0:03b5121a232e 12271 }
pcercuei 0:03b5121a232e 12272 /*
pcercuei 0:03b5121a232e 12273 * And now for the children...
pcercuei 0:03b5121a232e 12274 */
pcercuei 0:03b5121a232e 12275 child = node->children;
pcercuei 0:03b5121a232e 12276 if (IS_SCHEMA(child, "annotation")) {
pcercuei 0:03b5121a232e 12277 type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
pcercuei 0:03b5121a232e 12278 child = child->next;
pcercuei 0:03b5121a232e 12279 }
pcercuei 0:03b5121a232e 12280 ctxt->ctxtType = type;
pcercuei 0:03b5121a232e 12281 if (IS_SCHEMA(child, "simpleContent")) {
pcercuei 0:03b5121a232e 12282 /*
pcercuei 0:03b5121a232e 12283 * <complexType><simpleContent>...
pcercuei 0:03b5121a232e 12284 * 3.4.3 : 2.2
pcercuei 0:03b5121a232e 12285 * Specifying mixed='true' when the <simpleContent>
pcercuei 0:03b5121a232e 12286 * alternative is chosen has no effect
pcercuei 0:03b5121a232e 12287 */
pcercuei 0:03b5121a232e 12288 if (type->flags & XML_SCHEMAS_TYPE_MIXED)
pcercuei 0:03b5121a232e 12289 type->flags ^= XML_SCHEMAS_TYPE_MIXED;
pcercuei 0:03b5121a232e 12290 xmlSchemaParseSimpleContent(ctxt, schema, child,
pcercuei 0:03b5121a232e 12291 &hasRestrictionOrExtension);
pcercuei 0:03b5121a232e 12292 child = child->next;
pcercuei 0:03b5121a232e 12293 } else if (IS_SCHEMA(child, "complexContent")) {
pcercuei 0:03b5121a232e 12294 /*
pcercuei 0:03b5121a232e 12295 * <complexType><complexContent>...
pcercuei 0:03b5121a232e 12296 */
pcercuei 0:03b5121a232e 12297 type->contentType = XML_SCHEMA_CONTENT_EMPTY;
pcercuei 0:03b5121a232e 12298 xmlSchemaParseComplexContent(ctxt, schema, child,
pcercuei 0:03b5121a232e 12299 &hasRestrictionOrExtension);
pcercuei 0:03b5121a232e 12300 child = child->next;
pcercuei 0:03b5121a232e 12301 } else {
pcercuei 0:03b5121a232e 12302 /*
pcercuei 0:03b5121a232e 12303 * E.g <complexType><sequence>... or <complexType><attribute>... etc.
pcercuei 0:03b5121a232e 12304 *
pcercuei 0:03b5121a232e 12305 * SPEC
pcercuei 0:03b5121a232e 12306 * "...the third alternative (neither <simpleContent> nor
pcercuei 0:03b5121a232e 12307 * <complexContent>) is chosen. This case is understood as shorthand
pcercuei 0:03b5121a232e 12308 * for complex content restricting the `ur-type definition`, and the
pcercuei 0:03b5121a232e 12309 * details of the mappings should be modified as necessary.
pcercuei 0:03b5121a232e 12310 */
pcercuei 0:03b5121a232e 12311 type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
pcercuei 0:03b5121a232e 12312 type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
pcercuei 0:03b5121a232e 12313 /*
pcercuei 0:03b5121a232e 12314 * Parse model groups.
pcercuei 0:03b5121a232e 12315 */
pcercuei 0:03b5121a232e 12316 if (IS_SCHEMA(child, "all")) {
pcercuei 0:03b5121a232e 12317 type->subtypes = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 12318 xmlSchemaParseModelGroup(ctxt, schema, child,
pcercuei 0:03b5121a232e 12319 XML_SCHEMA_TYPE_ALL, 1);
pcercuei 0:03b5121a232e 12320 child = child->next;
pcercuei 0:03b5121a232e 12321 } else if (IS_SCHEMA(child, "choice")) {
pcercuei 0:03b5121a232e 12322 type->subtypes = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 12323 xmlSchemaParseModelGroup(ctxt, schema, child,
pcercuei 0:03b5121a232e 12324 XML_SCHEMA_TYPE_CHOICE, 1);
pcercuei 0:03b5121a232e 12325 child = child->next;
pcercuei 0:03b5121a232e 12326 } else if (IS_SCHEMA(child, "sequence")) {
pcercuei 0:03b5121a232e 12327 type->subtypes = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 12328 xmlSchemaParseModelGroup(ctxt, schema, child,
pcercuei 0:03b5121a232e 12329 XML_SCHEMA_TYPE_SEQUENCE, 1);
pcercuei 0:03b5121a232e 12330 child = child->next;
pcercuei 0:03b5121a232e 12331 } else if (IS_SCHEMA(child, "group")) {
pcercuei 0:03b5121a232e 12332 type->subtypes = (xmlSchemaTypePtr)
pcercuei 0:03b5121a232e 12333 xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
pcercuei 0:03b5121a232e 12334 /*
pcercuei 0:03b5121a232e 12335 * Note that the reference will be resolved in
pcercuei 0:03b5121a232e 12336 * xmlSchemaResolveTypeReferences();
pcercuei 0:03b5121a232e 12337 */
pcercuei 0:03b5121a232e 12338 child = child->next;
pcercuei 0:03b5121a232e 12339 }
pcercuei 0:03b5121a232e 12340 /*
pcercuei 0:03b5121a232e 12341 * Parse attribute decls/refs.
pcercuei 0:03b5121a232e 12342 */
pcercuei 0:03b5121a232e 12343 if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
pcercuei 0:03b5121a232e 12344 (xmlSchemaItemListPtr *) &(type->attrUses),
pcercuei 0:03b5121a232e 12345 XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
pcercuei 0:03b5121a232e 12346 return(NULL);
pcercuei 0:03b5121a232e 12347 /*
pcercuei 0:03b5121a232e 12348 * Parse attribute wildcard.
pcercuei 0:03b5121a232e 12349 */
pcercuei 0:03b5121a232e 12350 if (IS_SCHEMA(child, "anyAttribute")) {
pcercuei 0:03b5121a232e 12351 type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
pcercuei 0:03b5121a232e 12352 child = child->next;
pcercuei 0:03b5121a232e 12353 }
pcercuei 0:03b5121a232e 12354 }
pcercuei 0:03b5121a232e 12355 if (child != NULL) {
pcercuei 0:03b5121a232e 12356 xmlSchemaPContentErr(ctxt,
pcercuei 0:03b5121a232e 12357 XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
pcercuei 0:03b5121a232e 12358 NULL, node, child,
pcercuei 0:03b5121a232e 12359 NULL, "(annotation?, (simpleContent | complexContent | "
pcercuei 0:03b5121a232e 12360 "((group | all | choice | sequence)?, ((attribute | "
pcercuei 0:03b5121a232e 12361 "attributeGroup)*, anyAttribute?))))");
pcercuei 0:03b5121a232e 12362 }
pcercuei 0:03b5121a232e 12363 /*
pcercuei 0:03b5121a232e 12364 * REDEFINE: SPEC src-redefine (5)
pcercuei 0:03b5121a232e 12365 */
pcercuei 0:03b5121a232e 12366 if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
pcercuei 0:03b5121a232e 12367 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
pcercuei 0:03b5121a232e 12368 NULL, node, "This is a redefinition, thus the "
pcercuei 0:03b5121a232e 12369 "<complexType> must have a <restriction> or <extension> "
pcercuei 0:03b5121a232e 12370 "grand-child", NULL);
pcercuei 0:03b5121a232e 12371 }
pcercuei 0:03b5121a232e 12372 ctxt->ctxtType = ctxtType;
pcercuei 0:03b5121a232e 12373 return (type);
pcercuei 0:03b5121a232e 12374 }
pcercuei 0:03b5121a232e 12375
pcercuei 0:03b5121a232e 12376 /************************************************************************
pcercuei 0:03b5121a232e 12377 * *
pcercuei 0:03b5121a232e 12378 * Validating using Schemas *
pcercuei 0:03b5121a232e 12379 * *
pcercuei 0:03b5121a232e 12380 ************************************************************************/
pcercuei 0:03b5121a232e 12381
pcercuei 0:03b5121a232e 12382 /************************************************************************
pcercuei 0:03b5121a232e 12383 * *
pcercuei 0:03b5121a232e 12384 * Reading/Writing Schemas *
pcercuei 0:03b5121a232e 12385 * *
pcercuei 0:03b5121a232e 12386 ************************************************************************/
pcercuei 0:03b5121a232e 12387
pcercuei 0:03b5121a232e 12388 #if 0 /* Will be enabled if it is clear what options are needed. */
pcercuei 0:03b5121a232e 12389 /**
pcercuei 0:03b5121a232e 12390 * xmlSchemaParserCtxtSetOptions:
pcercuei 0:03b5121a232e 12391 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 12392 * @options: a combination of xmlSchemaParserOption
pcercuei 0:03b5121a232e 12393 *
pcercuei 0:03b5121a232e 12394 * Sets the options to be used during the parse.
pcercuei 0:03b5121a232e 12395 *
pcercuei 0:03b5121a232e 12396 * Returns 0 in case of success, -1 in case of an
pcercuei 0:03b5121a232e 12397 * API error.
pcercuei 0:03b5121a232e 12398 */
pcercuei 0:03b5121a232e 12399 static int
pcercuei 0:03b5121a232e 12400 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 12401 int options)
pcercuei 0:03b5121a232e 12402
pcercuei 0:03b5121a232e 12403 {
pcercuei 0:03b5121a232e 12404 int i;
pcercuei 0:03b5121a232e 12405
pcercuei 0:03b5121a232e 12406 if (ctxt == NULL)
pcercuei 0:03b5121a232e 12407 return (-1);
pcercuei 0:03b5121a232e 12408 /*
pcercuei 0:03b5121a232e 12409 * WARNING: Change the start value if adding to the
pcercuei 0:03b5121a232e 12410 * xmlSchemaParseOption.
pcercuei 0:03b5121a232e 12411 */
pcercuei 0:03b5121a232e 12412 for (i = 1; i < (int) sizeof(int) * 8; i++) {
pcercuei 0:03b5121a232e 12413 if (options & 1<<i) {
pcercuei 0:03b5121a232e 12414 return (-1);
pcercuei 0:03b5121a232e 12415 }
pcercuei 0:03b5121a232e 12416 }
pcercuei 0:03b5121a232e 12417 ctxt->options = options;
pcercuei 0:03b5121a232e 12418 return (0);
pcercuei 0:03b5121a232e 12419 }
pcercuei 0:03b5121a232e 12420
pcercuei 0:03b5121a232e 12421 /**
pcercuei 0:03b5121a232e 12422 * xmlSchemaValidCtxtGetOptions:
pcercuei 0:03b5121a232e 12423 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 12424 *
pcercuei 0:03b5121a232e 12425 * Returns the option combination of the parser context.
pcercuei 0:03b5121a232e 12426 */
pcercuei 0:03b5121a232e 12427 static int
pcercuei 0:03b5121a232e 12428 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 12429
pcercuei 0:03b5121a232e 12430 {
pcercuei 0:03b5121a232e 12431 if (ctxt == NULL)
pcercuei 0:03b5121a232e 12432 return (-1);
pcercuei 0:03b5121a232e 12433 else
pcercuei 0:03b5121a232e 12434 return (ctxt->options);
pcercuei 0:03b5121a232e 12435 }
pcercuei 0:03b5121a232e 12436 #endif
pcercuei 0:03b5121a232e 12437
pcercuei 0:03b5121a232e 12438 /**
pcercuei 0:03b5121a232e 12439 * xmlSchemaNewParserCtxt:
pcercuei 0:03b5121a232e 12440 * @URL: the location of the schema
pcercuei 0:03b5121a232e 12441 *
pcercuei 0:03b5121a232e 12442 * Create an XML Schemas parse context for that file/resource expected
pcercuei 0:03b5121a232e 12443 * to contain an XML Schemas file.
pcercuei 0:03b5121a232e 12444 *
pcercuei 0:03b5121a232e 12445 * Returns the parser context or NULL in case of error
pcercuei 0:03b5121a232e 12446 */
pcercuei 0:03b5121a232e 12447 xmlSchemaParserCtxtPtr
pcercuei 0:03b5121a232e 12448 xmlSchemaNewParserCtxt(const char *URL)
pcercuei 0:03b5121a232e 12449 {
pcercuei 0:03b5121a232e 12450 xmlSchemaParserCtxtPtr ret;
pcercuei 0:03b5121a232e 12451
pcercuei 0:03b5121a232e 12452 if (URL == NULL)
pcercuei 0:03b5121a232e 12453 return (NULL);
pcercuei 0:03b5121a232e 12454
pcercuei 0:03b5121a232e 12455 ret = xmlSchemaParserCtxtCreate();
pcercuei 0:03b5121a232e 12456 if (ret == NULL)
pcercuei 0:03b5121a232e 12457 return(NULL);
pcercuei 0:03b5121a232e 12458 ret->dict = xmlDictCreate();
pcercuei 0:03b5121a232e 12459 ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
pcercuei 0:03b5121a232e 12460 return (ret);
pcercuei 0:03b5121a232e 12461 }
pcercuei 0:03b5121a232e 12462
pcercuei 0:03b5121a232e 12463 /**
pcercuei 0:03b5121a232e 12464 * xmlSchemaNewMemParserCtxt:
pcercuei 0:03b5121a232e 12465 * @buffer: a pointer to a char array containing the schemas
pcercuei 0:03b5121a232e 12466 * @size: the size of the array
pcercuei 0:03b5121a232e 12467 *
pcercuei 0:03b5121a232e 12468 * Create an XML Schemas parse context for that memory buffer expected
pcercuei 0:03b5121a232e 12469 * to contain an XML Schemas file.
pcercuei 0:03b5121a232e 12470 *
pcercuei 0:03b5121a232e 12471 * Returns the parser context or NULL in case of error
pcercuei 0:03b5121a232e 12472 */
pcercuei 0:03b5121a232e 12473 xmlSchemaParserCtxtPtr
pcercuei 0:03b5121a232e 12474 xmlSchemaNewMemParserCtxt(const char *buffer, int size)
pcercuei 0:03b5121a232e 12475 {
pcercuei 0:03b5121a232e 12476 xmlSchemaParserCtxtPtr ret;
pcercuei 0:03b5121a232e 12477
pcercuei 0:03b5121a232e 12478 if ((buffer == NULL) || (size <= 0))
pcercuei 0:03b5121a232e 12479 return (NULL);
pcercuei 0:03b5121a232e 12480 ret = xmlSchemaParserCtxtCreate();
pcercuei 0:03b5121a232e 12481 if (ret == NULL)
pcercuei 0:03b5121a232e 12482 return(NULL);
pcercuei 0:03b5121a232e 12483 ret->buffer = buffer;
pcercuei 0:03b5121a232e 12484 ret->size = size;
pcercuei 0:03b5121a232e 12485 ret->dict = xmlDictCreate();
pcercuei 0:03b5121a232e 12486 return (ret);
pcercuei 0:03b5121a232e 12487 }
pcercuei 0:03b5121a232e 12488
pcercuei 0:03b5121a232e 12489 /**
pcercuei 0:03b5121a232e 12490 * xmlSchemaNewDocParserCtxt:
pcercuei 0:03b5121a232e 12491 * @doc: a preparsed document tree
pcercuei 0:03b5121a232e 12492 *
pcercuei 0:03b5121a232e 12493 * Create an XML Schemas parse context for that document.
pcercuei 0:03b5121a232e 12494 * NB. The document may be modified during the parsing process.
pcercuei 0:03b5121a232e 12495 *
pcercuei 0:03b5121a232e 12496 * Returns the parser context or NULL in case of error
pcercuei 0:03b5121a232e 12497 */
pcercuei 0:03b5121a232e 12498 xmlSchemaParserCtxtPtr
pcercuei 0:03b5121a232e 12499 xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
pcercuei 0:03b5121a232e 12500 {
pcercuei 0:03b5121a232e 12501 xmlSchemaParserCtxtPtr ret;
pcercuei 0:03b5121a232e 12502
pcercuei 0:03b5121a232e 12503 if (doc == NULL)
pcercuei 0:03b5121a232e 12504 return (NULL);
pcercuei 0:03b5121a232e 12505 ret = xmlSchemaParserCtxtCreate();
pcercuei 0:03b5121a232e 12506 if (ret == NULL)
pcercuei 0:03b5121a232e 12507 return(NULL);
pcercuei 0:03b5121a232e 12508 ret->doc = doc;
pcercuei 0:03b5121a232e 12509 ret->dict = xmlDictCreate();
pcercuei 0:03b5121a232e 12510 /* The application has responsibility for the document */
pcercuei 0:03b5121a232e 12511 ret->preserve = 1;
pcercuei 0:03b5121a232e 12512
pcercuei 0:03b5121a232e 12513 return (ret);
pcercuei 0:03b5121a232e 12514 }
pcercuei 0:03b5121a232e 12515
pcercuei 0:03b5121a232e 12516 /**
pcercuei 0:03b5121a232e 12517 * xmlSchemaFreeParserCtxt:
pcercuei 0:03b5121a232e 12518 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 12519 *
pcercuei 0:03b5121a232e 12520 * Free the resources associated to the schema parser context
pcercuei 0:03b5121a232e 12521 */
pcercuei 0:03b5121a232e 12522 void
pcercuei 0:03b5121a232e 12523 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 12524 {
pcercuei 0:03b5121a232e 12525 if (ctxt == NULL)
pcercuei 0:03b5121a232e 12526 return;
pcercuei 0:03b5121a232e 12527 if (ctxt->doc != NULL && !ctxt->preserve)
pcercuei 0:03b5121a232e 12528 xmlFreeDoc(ctxt->doc);
pcercuei 0:03b5121a232e 12529 if (ctxt->vctxt != NULL) {
pcercuei 0:03b5121a232e 12530 xmlSchemaFreeValidCtxt(ctxt->vctxt);
pcercuei 0:03b5121a232e 12531 }
pcercuei 0:03b5121a232e 12532 if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
pcercuei 0:03b5121a232e 12533 xmlSchemaConstructionCtxtFree(ctxt->constructor);
pcercuei 0:03b5121a232e 12534 ctxt->constructor = NULL;
pcercuei 0:03b5121a232e 12535 ctxt->ownsConstructor = 0;
pcercuei 0:03b5121a232e 12536 }
pcercuei 0:03b5121a232e 12537 if (ctxt->attrProhibs != NULL)
pcercuei 0:03b5121a232e 12538 xmlSchemaItemListFree(ctxt->attrProhibs);
pcercuei 0:03b5121a232e 12539 xmlDictFree(ctxt->dict);
pcercuei 0:03b5121a232e 12540 xmlFree(ctxt);
pcercuei 0:03b5121a232e 12541 }
pcercuei 0:03b5121a232e 12542
pcercuei 0:03b5121a232e 12543 /************************************************************************
pcercuei 0:03b5121a232e 12544 * *
pcercuei 0:03b5121a232e 12545 * Building the content models *
pcercuei 0:03b5121a232e 12546 * *
pcercuei 0:03b5121a232e 12547 ************************************************************************/
pcercuei 0:03b5121a232e 12548
pcercuei 0:03b5121a232e 12549 /**
pcercuei 0:03b5121a232e 12550 * xmlSchemaBuildContentModelForSubstGroup:
pcercuei 0:03b5121a232e 12551 *
pcercuei 0:03b5121a232e 12552 * Returns 1 if nillable, 0 otherwise
pcercuei 0:03b5121a232e 12553 */
pcercuei 0:03b5121a232e 12554 static int
pcercuei 0:03b5121a232e 12555 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 12556 xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
pcercuei 0:03b5121a232e 12557 {
pcercuei 0:03b5121a232e 12558 xmlAutomataStatePtr start, tmp;
pcercuei 0:03b5121a232e 12559 xmlSchemaElementPtr elemDecl, member;
pcercuei 0:03b5121a232e 12560 xmlSchemaSubstGroupPtr substGroup;
pcercuei 0:03b5121a232e 12561 int i;
pcercuei 0:03b5121a232e 12562 int ret = 0;
pcercuei 0:03b5121a232e 12563
pcercuei 0:03b5121a232e 12564 elemDecl = (xmlSchemaElementPtr) particle->children;
pcercuei 0:03b5121a232e 12565 /*
pcercuei 0:03b5121a232e 12566 * Wrap the substitution group with a CHOICE.
pcercuei 0:03b5121a232e 12567 */
pcercuei 0:03b5121a232e 12568 start = pctxt->state;
pcercuei 0:03b5121a232e 12569 if (end == NULL)
pcercuei 0:03b5121a232e 12570 end = xmlAutomataNewState(pctxt->am);
pcercuei 0:03b5121a232e 12571 substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
pcercuei 0:03b5121a232e 12572 if (substGroup == NULL) {
pcercuei 0:03b5121a232e 12573 xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
pcercuei 0:03b5121a232e 12574 XML_SCHEMAP_INTERNAL,
pcercuei 0:03b5121a232e 12575 "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
pcercuei 0:03b5121a232e 12576 "declaration is marked having a subst. group but none "
pcercuei 0:03b5121a232e 12577 "available.\n", elemDecl->name, NULL);
pcercuei 0:03b5121a232e 12578 return(0);
pcercuei 0:03b5121a232e 12579 }
pcercuei 0:03b5121a232e 12580 if (counter >= 0) {
pcercuei 0:03b5121a232e 12581 /*
pcercuei 0:03b5121a232e 12582 * NOTE that we put the declaration in, even if it's abstract.
pcercuei 0:03b5121a232e 12583 * However, an error will be raised during *validation* if an element
pcercuei 0:03b5121a232e 12584 * information item shall be validated against an abstract element
pcercuei 0:03b5121a232e 12585 * declaration.
pcercuei 0:03b5121a232e 12586 */
pcercuei 0:03b5121a232e 12587 tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
pcercuei 0:03b5121a232e 12588 xmlAutomataNewTransition2(pctxt->am, tmp, end,
pcercuei 0:03b5121a232e 12589 elemDecl->name, elemDecl->targetNamespace, elemDecl);
pcercuei 0:03b5121a232e 12590 /*
pcercuei 0:03b5121a232e 12591 * Add subst. group members.
pcercuei 0:03b5121a232e 12592 */
pcercuei 0:03b5121a232e 12593 for (i = 0; i < substGroup->members->nbItems; i++) {
pcercuei 0:03b5121a232e 12594 member = (xmlSchemaElementPtr) substGroup->members->items[i];
pcercuei 0:03b5121a232e 12595 xmlAutomataNewTransition2(pctxt->am, tmp, end,
pcercuei 0:03b5121a232e 12596 member->name, member->targetNamespace, member);
pcercuei 0:03b5121a232e 12597 }
pcercuei 0:03b5121a232e 12598 } else if (particle->maxOccurs == 1) {
pcercuei 0:03b5121a232e 12599 /*
pcercuei 0:03b5121a232e 12600 * NOTE that we put the declaration in, even if it's abstract,
pcercuei 0:03b5121a232e 12601 */
pcercuei 0:03b5121a232e 12602 xmlAutomataNewEpsilon(pctxt->am,
pcercuei 0:03b5121a232e 12603 xmlAutomataNewTransition2(pctxt->am,
pcercuei 0:03b5121a232e 12604 start, NULL,
pcercuei 0:03b5121a232e 12605 elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
pcercuei 0:03b5121a232e 12606 /*
pcercuei 0:03b5121a232e 12607 * Add subst. group members.
pcercuei 0:03b5121a232e 12608 */
pcercuei 0:03b5121a232e 12609 for (i = 0; i < substGroup->members->nbItems; i++) {
pcercuei 0:03b5121a232e 12610 member = (xmlSchemaElementPtr) substGroup->members->items[i];
pcercuei 0:03b5121a232e 12611 /*
pcercuei 0:03b5121a232e 12612 * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
pcercuei 0:03b5121a232e 12613 * was incorrectly used instead of xmlAutomataNewTransition2()
pcercuei 0:03b5121a232e 12614 * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
pcercuei 0:03b5121a232e 12615 * section in xmlSchemaBuildAContentModel() ).
pcercuei 0:03b5121a232e 12616 * TODO: Check if xmlAutomataNewOnceTrans2() was instead
pcercuei 0:03b5121a232e 12617 * intended for the above "counter" section originally. I.e.,
pcercuei 0:03b5121a232e 12618 * check xs:all with subst-groups.
pcercuei 0:03b5121a232e 12619 *
pcercuei 0:03b5121a232e 12620 * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
pcercuei 0:03b5121a232e 12621 * member->name, member->targetNamespace,
pcercuei 0:03b5121a232e 12622 * 1, 1, member);
pcercuei 0:03b5121a232e 12623 */
pcercuei 0:03b5121a232e 12624 tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
pcercuei 0:03b5121a232e 12625 member->name, member->targetNamespace, member);
pcercuei 0:03b5121a232e 12626 xmlAutomataNewEpsilon(pctxt->am, tmp, end);
pcercuei 0:03b5121a232e 12627 }
pcercuei 0:03b5121a232e 12628 } else {
pcercuei 0:03b5121a232e 12629 xmlAutomataStatePtr hop;
pcercuei 0:03b5121a232e 12630 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
pcercuei 0:03b5121a232e 12631 UNBOUNDED : particle->maxOccurs - 1;
pcercuei 0:03b5121a232e 12632 int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
pcercuei 0:03b5121a232e 12633
pcercuei 0:03b5121a232e 12634 counter =
pcercuei 0:03b5121a232e 12635 xmlAutomataNewCounter(pctxt->am, minOccurs,
pcercuei 0:03b5121a232e 12636 maxOccurs);
pcercuei 0:03b5121a232e 12637 hop = xmlAutomataNewState(pctxt->am);
pcercuei 0:03b5121a232e 12638
pcercuei 0:03b5121a232e 12639 xmlAutomataNewEpsilon(pctxt->am,
pcercuei 0:03b5121a232e 12640 xmlAutomataNewTransition2(pctxt->am,
pcercuei 0:03b5121a232e 12641 start, NULL,
pcercuei 0:03b5121a232e 12642 elemDecl->name, elemDecl->targetNamespace, elemDecl),
pcercuei 0:03b5121a232e 12643 hop);
pcercuei 0:03b5121a232e 12644 /*
pcercuei 0:03b5121a232e 12645 * Add subst. group members.
pcercuei 0:03b5121a232e 12646 */
pcercuei 0:03b5121a232e 12647 for (i = 0; i < substGroup->members->nbItems; i++) {
pcercuei 0:03b5121a232e 12648 member = (xmlSchemaElementPtr) substGroup->members->items[i];
pcercuei 0:03b5121a232e 12649 xmlAutomataNewEpsilon(pctxt->am,
pcercuei 0:03b5121a232e 12650 xmlAutomataNewTransition2(pctxt->am,
pcercuei 0:03b5121a232e 12651 start, NULL,
pcercuei 0:03b5121a232e 12652 member->name, member->targetNamespace, member),
pcercuei 0:03b5121a232e 12653 hop);
pcercuei 0:03b5121a232e 12654 }
pcercuei 0:03b5121a232e 12655 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
pcercuei 0:03b5121a232e 12656 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
pcercuei 0:03b5121a232e 12657 }
pcercuei 0:03b5121a232e 12658 if (particle->minOccurs == 0) {
pcercuei 0:03b5121a232e 12659 xmlAutomataNewEpsilon(pctxt->am, start, end);
pcercuei 0:03b5121a232e 12660 ret = 1;
pcercuei 0:03b5121a232e 12661 }
pcercuei 0:03b5121a232e 12662 pctxt->state = end;
pcercuei 0:03b5121a232e 12663 return(ret);
pcercuei 0:03b5121a232e 12664 }
pcercuei 0:03b5121a232e 12665
pcercuei 0:03b5121a232e 12666 /**
pcercuei 0:03b5121a232e 12667 * xmlSchemaBuildContentModelForElement:
pcercuei 0:03b5121a232e 12668 *
pcercuei 0:03b5121a232e 12669 * Returns 1 if nillable, 0 otherwise
pcercuei 0:03b5121a232e 12670 */
pcercuei 0:03b5121a232e 12671 static int
pcercuei 0:03b5121a232e 12672 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 12673 xmlSchemaParticlePtr particle)
pcercuei 0:03b5121a232e 12674 {
pcercuei 0:03b5121a232e 12675 int ret = 0;
pcercuei 0:03b5121a232e 12676
pcercuei 0:03b5121a232e 12677 if (((xmlSchemaElementPtr) particle->children)->flags &
pcercuei 0:03b5121a232e 12678 XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
pcercuei 0:03b5121a232e 12679 /*
pcercuei 0:03b5121a232e 12680 * Substitution groups.
pcercuei 0:03b5121a232e 12681 */
pcercuei 0:03b5121a232e 12682 ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
pcercuei 0:03b5121a232e 12683 } else {
pcercuei 0:03b5121a232e 12684 xmlSchemaElementPtr elemDecl;
pcercuei 0:03b5121a232e 12685 xmlAutomataStatePtr start;
pcercuei 0:03b5121a232e 12686
pcercuei 0:03b5121a232e 12687 elemDecl = (xmlSchemaElementPtr) particle->children;
pcercuei 0:03b5121a232e 12688
pcercuei 0:03b5121a232e 12689 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
pcercuei 0:03b5121a232e 12690 return(0);
pcercuei 0:03b5121a232e 12691 if (particle->maxOccurs == 1) {
pcercuei 0:03b5121a232e 12692 start = ctxt->state;
pcercuei 0:03b5121a232e 12693 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
pcercuei 0:03b5121a232e 12694 elemDecl->name, elemDecl->targetNamespace, elemDecl);
pcercuei 0:03b5121a232e 12695 } else if ((particle->maxOccurs >= UNBOUNDED) &&
pcercuei 0:03b5121a232e 12696 (particle->minOccurs < 2)) {
pcercuei 0:03b5121a232e 12697 /* Special case. */
pcercuei 0:03b5121a232e 12698 start = ctxt->state;
pcercuei 0:03b5121a232e 12699 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
pcercuei 0:03b5121a232e 12700 elemDecl->name, elemDecl->targetNamespace, elemDecl);
pcercuei 0:03b5121a232e 12701 ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
pcercuei 0:03b5121a232e 12702 elemDecl->name, elemDecl->targetNamespace, elemDecl);
pcercuei 0:03b5121a232e 12703 } else {
pcercuei 0:03b5121a232e 12704 int counter;
pcercuei 0:03b5121a232e 12705 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
pcercuei 0:03b5121a232e 12706 UNBOUNDED : particle->maxOccurs - 1;
pcercuei 0:03b5121a232e 12707 int minOccurs = particle->minOccurs < 1 ?
pcercuei 0:03b5121a232e 12708 0 : particle->minOccurs - 1;
pcercuei 0:03b5121a232e 12709
pcercuei 0:03b5121a232e 12710 start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
pcercuei 0:03b5121a232e 12711 counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
pcercuei 0:03b5121a232e 12712 ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
pcercuei 0:03b5121a232e 12713 elemDecl->name, elemDecl->targetNamespace, elemDecl);
pcercuei 0:03b5121a232e 12714 xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
pcercuei 0:03b5121a232e 12715 ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
pcercuei 0:03b5121a232e 12716 NULL, counter);
pcercuei 0:03b5121a232e 12717 }
pcercuei 0:03b5121a232e 12718 if (particle->minOccurs == 0) {
pcercuei 0:03b5121a232e 12719 xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
pcercuei 0:03b5121a232e 12720 ret = 1;
pcercuei 0:03b5121a232e 12721 }
pcercuei 0:03b5121a232e 12722 }
pcercuei 0:03b5121a232e 12723 return(ret);
pcercuei 0:03b5121a232e 12724 }
pcercuei 0:03b5121a232e 12725
pcercuei 0:03b5121a232e 12726 /**
pcercuei 0:03b5121a232e 12727 * xmlSchemaBuildAContentModel:
pcercuei 0:03b5121a232e 12728 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 12729 * @particle: the particle component
pcercuei 0:03b5121a232e 12730 * @name: the complex type's name whose content is being built
pcercuei 0:03b5121a232e 12731 *
pcercuei 0:03b5121a232e 12732 * Create the automaton for the {content type} of a complex type.
pcercuei 0:03b5121a232e 12733 *
pcercuei 0:03b5121a232e 12734 * Returns 1 if the content is nillable, 0 otherwise
pcercuei 0:03b5121a232e 12735 */
pcercuei 0:03b5121a232e 12736 static int
pcercuei 0:03b5121a232e 12737 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 12738 xmlSchemaParticlePtr particle)
pcercuei 0:03b5121a232e 12739 {
pcercuei 0:03b5121a232e 12740 int ret = 0, tmp2;
pcercuei 0:03b5121a232e 12741
pcercuei 0:03b5121a232e 12742 if (particle == NULL) {
pcercuei 0:03b5121a232e 12743 PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
pcercuei 0:03b5121a232e 12744 return(1);
pcercuei 0:03b5121a232e 12745 }
pcercuei 0:03b5121a232e 12746 if (particle->children == NULL) {
pcercuei 0:03b5121a232e 12747 /*
pcercuei 0:03b5121a232e 12748 * Just return in this case. A missing "term" of the particle
pcercuei 0:03b5121a232e 12749 * might arise due to an invalid "term" component.
pcercuei 0:03b5121a232e 12750 */
pcercuei 0:03b5121a232e 12751 return(1);
pcercuei 0:03b5121a232e 12752 }
pcercuei 0:03b5121a232e 12753
pcercuei 0:03b5121a232e 12754 switch (particle->children->type) {
pcercuei 0:03b5121a232e 12755 case XML_SCHEMA_TYPE_ANY: {
pcercuei 0:03b5121a232e 12756 xmlAutomataStatePtr start, end;
pcercuei 0:03b5121a232e 12757 xmlSchemaWildcardPtr wild;
pcercuei 0:03b5121a232e 12758 xmlSchemaWildcardNsPtr ns;
pcercuei 0:03b5121a232e 12759
pcercuei 0:03b5121a232e 12760 wild = (xmlSchemaWildcardPtr) particle->children;
pcercuei 0:03b5121a232e 12761
pcercuei 0:03b5121a232e 12762 start = pctxt->state;
pcercuei 0:03b5121a232e 12763 end = xmlAutomataNewState(pctxt->am);
pcercuei 0:03b5121a232e 12764
pcercuei 0:03b5121a232e 12765 if (particle->maxOccurs == 1) {
pcercuei 0:03b5121a232e 12766 if (wild->any == 1) {
pcercuei 0:03b5121a232e 12767 /*
pcercuei 0:03b5121a232e 12768 * We need to add both transitions:
pcercuei 0:03b5121a232e 12769 *
pcercuei 0:03b5121a232e 12770 * 1. the {"*", "*"} for elements in a namespace.
pcercuei 0:03b5121a232e 12771 */
pcercuei 0:03b5121a232e 12772 pctxt->state =
pcercuei 0:03b5121a232e 12773 xmlAutomataNewTransition2(pctxt->am,
pcercuei 0:03b5121a232e 12774 start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
pcercuei 0:03b5121a232e 12775 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
pcercuei 0:03b5121a232e 12776 /*
pcercuei 0:03b5121a232e 12777 * 2. the {"*"} for elements in no namespace.
pcercuei 0:03b5121a232e 12778 */
pcercuei 0:03b5121a232e 12779 pctxt->state =
pcercuei 0:03b5121a232e 12780 xmlAutomataNewTransition2(pctxt->am,
pcercuei 0:03b5121a232e 12781 start, NULL, BAD_CAST "*", NULL, wild);
pcercuei 0:03b5121a232e 12782 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
pcercuei 0:03b5121a232e 12783
pcercuei 0:03b5121a232e 12784 } else if (wild->nsSet != NULL) {
pcercuei 0:03b5121a232e 12785 ns = wild->nsSet;
pcercuei 0:03b5121a232e 12786 do {
pcercuei 0:03b5121a232e 12787 pctxt->state = start;
pcercuei 0:03b5121a232e 12788 pctxt->state = xmlAutomataNewTransition2(pctxt->am,
pcercuei 0:03b5121a232e 12789 pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
pcercuei 0:03b5121a232e 12790 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
pcercuei 0:03b5121a232e 12791 ns = ns->next;
pcercuei 0:03b5121a232e 12792 } while (ns != NULL);
pcercuei 0:03b5121a232e 12793
pcercuei 0:03b5121a232e 12794 } else if (wild->negNsSet != NULL) {
pcercuei 0:03b5121a232e 12795 pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
pcercuei 0:03b5121a232e 12796 start, end, BAD_CAST "*", wild->negNsSet->value,
pcercuei 0:03b5121a232e 12797 wild);
pcercuei 0:03b5121a232e 12798 }
pcercuei 0:03b5121a232e 12799 } else {
pcercuei 0:03b5121a232e 12800 int counter;
pcercuei 0:03b5121a232e 12801 xmlAutomataStatePtr hop;
pcercuei 0:03b5121a232e 12802 int maxOccurs =
pcercuei 0:03b5121a232e 12803 particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
pcercuei 0:03b5121a232e 12804 particle->maxOccurs - 1;
pcercuei 0:03b5121a232e 12805 int minOccurs =
pcercuei 0:03b5121a232e 12806 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
pcercuei 0:03b5121a232e 12807
pcercuei 0:03b5121a232e 12808 counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
pcercuei 0:03b5121a232e 12809 hop = xmlAutomataNewState(pctxt->am);
pcercuei 0:03b5121a232e 12810 if (wild->any == 1) {
pcercuei 0:03b5121a232e 12811 pctxt->state =
pcercuei 0:03b5121a232e 12812 xmlAutomataNewTransition2(pctxt->am,
pcercuei 0:03b5121a232e 12813 start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
pcercuei 0:03b5121a232e 12814 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
pcercuei 0:03b5121a232e 12815 pctxt->state =
pcercuei 0:03b5121a232e 12816 xmlAutomataNewTransition2(pctxt->am,
pcercuei 0:03b5121a232e 12817 start, NULL, BAD_CAST "*", NULL, wild);
pcercuei 0:03b5121a232e 12818 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
pcercuei 0:03b5121a232e 12819 } else if (wild->nsSet != NULL) {
pcercuei 0:03b5121a232e 12820 ns = wild->nsSet;
pcercuei 0:03b5121a232e 12821 do {
pcercuei 0:03b5121a232e 12822 pctxt->state =
pcercuei 0:03b5121a232e 12823 xmlAutomataNewTransition2(pctxt->am,
pcercuei 0:03b5121a232e 12824 start, NULL, BAD_CAST "*", ns->value, wild);
pcercuei 0:03b5121a232e 12825 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
pcercuei 0:03b5121a232e 12826 ns = ns->next;
pcercuei 0:03b5121a232e 12827 } while (ns != NULL);
pcercuei 0:03b5121a232e 12828
pcercuei 0:03b5121a232e 12829 } else if (wild->negNsSet != NULL) {
pcercuei 0:03b5121a232e 12830 pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
pcercuei 0:03b5121a232e 12831 start, hop, BAD_CAST "*", wild->negNsSet->value,
pcercuei 0:03b5121a232e 12832 wild);
pcercuei 0:03b5121a232e 12833 }
pcercuei 0:03b5121a232e 12834 xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
pcercuei 0:03b5121a232e 12835 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
pcercuei 0:03b5121a232e 12836 }
pcercuei 0:03b5121a232e 12837 if (particle->minOccurs == 0) {
pcercuei 0:03b5121a232e 12838 xmlAutomataNewEpsilon(pctxt->am, start, end);
pcercuei 0:03b5121a232e 12839 ret = 1;
pcercuei 0:03b5121a232e 12840 }
pcercuei 0:03b5121a232e 12841 pctxt->state = end;
pcercuei 0:03b5121a232e 12842 break;
pcercuei 0:03b5121a232e 12843 }
pcercuei 0:03b5121a232e 12844 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 12845 ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
pcercuei 0:03b5121a232e 12846 break;
pcercuei 0:03b5121a232e 12847 case XML_SCHEMA_TYPE_SEQUENCE:{
pcercuei 0:03b5121a232e 12848 xmlSchemaTreeItemPtr sub;
pcercuei 0:03b5121a232e 12849
pcercuei 0:03b5121a232e 12850 ret = 1;
pcercuei 0:03b5121a232e 12851 /*
pcercuei 0:03b5121a232e 12852 * If max and min occurances are default (1) then
pcercuei 0:03b5121a232e 12853 * simply iterate over the particles of the <sequence>.
pcercuei 0:03b5121a232e 12854 */
pcercuei 0:03b5121a232e 12855 if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
pcercuei 0:03b5121a232e 12856 sub = particle->children->children;
pcercuei 0:03b5121a232e 12857
pcercuei 0:03b5121a232e 12858 while (sub != NULL) {
pcercuei 0:03b5121a232e 12859 tmp2 = xmlSchemaBuildAContentModel(pctxt,
pcercuei 0:03b5121a232e 12860 (xmlSchemaParticlePtr) sub);
pcercuei 0:03b5121a232e 12861 if (tmp2 != 1) ret = 0;
pcercuei 0:03b5121a232e 12862 sub = sub->next;
pcercuei 0:03b5121a232e 12863 }
pcercuei 0:03b5121a232e 12864 } else {
pcercuei 0:03b5121a232e 12865 xmlAutomataStatePtr oldstate = pctxt->state;
pcercuei 0:03b5121a232e 12866
pcercuei 0:03b5121a232e 12867 if (particle->maxOccurs >= UNBOUNDED) {
pcercuei 0:03b5121a232e 12868 if (particle->minOccurs > 1) {
pcercuei 0:03b5121a232e 12869 xmlAutomataStatePtr tmp;
pcercuei 0:03b5121a232e 12870 int counter;
pcercuei 0:03b5121a232e 12871
pcercuei 0:03b5121a232e 12872 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
pcercuei 0:03b5121a232e 12873 oldstate, NULL);
pcercuei 0:03b5121a232e 12874 oldstate = pctxt->state;
pcercuei 0:03b5121a232e 12875
pcercuei 0:03b5121a232e 12876 counter = xmlAutomataNewCounter(pctxt->am,
pcercuei 0:03b5121a232e 12877 particle->minOccurs - 1, UNBOUNDED);
pcercuei 0:03b5121a232e 12878
pcercuei 0:03b5121a232e 12879 sub = particle->children->children;
pcercuei 0:03b5121a232e 12880 while (sub != NULL) {
pcercuei 0:03b5121a232e 12881 tmp2 = xmlSchemaBuildAContentModel(pctxt,
pcercuei 0:03b5121a232e 12882 (xmlSchemaParticlePtr) sub);
pcercuei 0:03b5121a232e 12883 if (tmp2 != 1) ret = 0;
pcercuei 0:03b5121a232e 12884 sub = sub->next;
pcercuei 0:03b5121a232e 12885 }
pcercuei 0:03b5121a232e 12886 tmp = pctxt->state;
pcercuei 0:03b5121a232e 12887 xmlAutomataNewCountedTrans(pctxt->am, tmp,
pcercuei 0:03b5121a232e 12888 oldstate, counter);
pcercuei 0:03b5121a232e 12889 pctxt->state =
pcercuei 0:03b5121a232e 12890 xmlAutomataNewCounterTrans(pctxt->am, tmp,
pcercuei 0:03b5121a232e 12891 NULL, counter);
pcercuei 0:03b5121a232e 12892 if (ret == 1)
pcercuei 0:03b5121a232e 12893 xmlAutomataNewEpsilon(pctxt->am,
pcercuei 0:03b5121a232e 12894 oldstate, pctxt->state);
pcercuei 0:03b5121a232e 12895
pcercuei 0:03b5121a232e 12896 } else {
pcercuei 0:03b5121a232e 12897 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
pcercuei 0:03b5121a232e 12898 oldstate, NULL);
pcercuei 0:03b5121a232e 12899 oldstate = pctxt->state;
pcercuei 0:03b5121a232e 12900
pcercuei 0:03b5121a232e 12901 sub = particle->children->children;
pcercuei 0:03b5121a232e 12902 while (sub != NULL) {
pcercuei 0:03b5121a232e 12903 tmp2 = xmlSchemaBuildAContentModel(pctxt,
pcercuei 0:03b5121a232e 12904 (xmlSchemaParticlePtr) sub);
pcercuei 0:03b5121a232e 12905 if (tmp2 != 1) ret = 0;
pcercuei 0:03b5121a232e 12906 sub = sub->next;
pcercuei 0:03b5121a232e 12907 }
pcercuei 0:03b5121a232e 12908 xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
pcercuei 0:03b5121a232e 12909 oldstate);
pcercuei 0:03b5121a232e 12910 /*
pcercuei 0:03b5121a232e 12911 * epsilon needed to block previous trans from
pcercuei 0:03b5121a232e 12912 * being allowed to enter back from another
pcercuei 0:03b5121a232e 12913 * construct
pcercuei 0:03b5121a232e 12914 */
pcercuei 0:03b5121a232e 12915 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
pcercuei 0:03b5121a232e 12916 pctxt->state, NULL);
pcercuei 0:03b5121a232e 12917 if (particle->minOccurs == 0) {
pcercuei 0:03b5121a232e 12918 xmlAutomataNewEpsilon(pctxt->am,
pcercuei 0:03b5121a232e 12919 oldstate, pctxt->state);
pcercuei 0:03b5121a232e 12920 ret = 1;
pcercuei 0:03b5121a232e 12921 }
pcercuei 0:03b5121a232e 12922 }
pcercuei 0:03b5121a232e 12923 } else if ((particle->maxOccurs > 1)
pcercuei 0:03b5121a232e 12924 || (particle->minOccurs > 1)) {
pcercuei 0:03b5121a232e 12925 xmlAutomataStatePtr tmp;
pcercuei 0:03b5121a232e 12926 int counter;
pcercuei 0:03b5121a232e 12927
pcercuei 0:03b5121a232e 12928 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
pcercuei 0:03b5121a232e 12929 oldstate, NULL);
pcercuei 0:03b5121a232e 12930 oldstate = pctxt->state;
pcercuei 0:03b5121a232e 12931
pcercuei 0:03b5121a232e 12932 counter = xmlAutomataNewCounter(pctxt->am,
pcercuei 0:03b5121a232e 12933 particle->minOccurs - 1,
pcercuei 0:03b5121a232e 12934 particle->maxOccurs - 1);
pcercuei 0:03b5121a232e 12935
pcercuei 0:03b5121a232e 12936 sub = particle->children->children;
pcercuei 0:03b5121a232e 12937 while (sub != NULL) {
pcercuei 0:03b5121a232e 12938 tmp2 = xmlSchemaBuildAContentModel(pctxt,
pcercuei 0:03b5121a232e 12939 (xmlSchemaParticlePtr) sub);
pcercuei 0:03b5121a232e 12940 if (tmp2 != 1) ret = 0;
pcercuei 0:03b5121a232e 12941 sub = sub->next;
pcercuei 0:03b5121a232e 12942 }
pcercuei 0:03b5121a232e 12943 tmp = pctxt->state;
pcercuei 0:03b5121a232e 12944 xmlAutomataNewCountedTrans(pctxt->am,
pcercuei 0:03b5121a232e 12945 tmp, oldstate, counter);
pcercuei 0:03b5121a232e 12946 pctxt->state =
pcercuei 0:03b5121a232e 12947 xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
pcercuei 0:03b5121a232e 12948 counter);
pcercuei 0:03b5121a232e 12949 if ((particle->minOccurs == 0) || (ret == 1)) {
pcercuei 0:03b5121a232e 12950 xmlAutomataNewEpsilon(pctxt->am,
pcercuei 0:03b5121a232e 12951 oldstate, pctxt->state);
pcercuei 0:03b5121a232e 12952 ret = 1;
pcercuei 0:03b5121a232e 12953 }
pcercuei 0:03b5121a232e 12954 } else {
pcercuei 0:03b5121a232e 12955 sub = particle->children->children;
pcercuei 0:03b5121a232e 12956 while (sub != NULL) {
pcercuei 0:03b5121a232e 12957 tmp2 = xmlSchemaBuildAContentModel(pctxt,
pcercuei 0:03b5121a232e 12958 (xmlSchemaParticlePtr) sub);
pcercuei 0:03b5121a232e 12959 if (tmp2 != 1) ret = 0;
pcercuei 0:03b5121a232e 12960 sub = sub->next;
pcercuei 0:03b5121a232e 12961 }
pcercuei 0:03b5121a232e 12962
pcercuei 0:03b5121a232e 12963 /*
pcercuei 0:03b5121a232e 12964 * epsilon needed to block previous trans from
pcercuei 0:03b5121a232e 12965 * being allowed to enter back from another
pcercuei 0:03b5121a232e 12966 * construct
pcercuei 0:03b5121a232e 12967 */
pcercuei 0:03b5121a232e 12968 pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
pcercuei 0:03b5121a232e 12969 pctxt->state, NULL);
pcercuei 0:03b5121a232e 12970
pcercuei 0:03b5121a232e 12971 if (particle->minOccurs == 0) {
pcercuei 0:03b5121a232e 12972 xmlAutomataNewEpsilon(pctxt->am, oldstate,
pcercuei 0:03b5121a232e 12973 pctxt->state);
pcercuei 0:03b5121a232e 12974 ret = 1;
pcercuei 0:03b5121a232e 12975 }
pcercuei 0:03b5121a232e 12976 }
pcercuei 0:03b5121a232e 12977 }
pcercuei 0:03b5121a232e 12978 break;
pcercuei 0:03b5121a232e 12979 }
pcercuei 0:03b5121a232e 12980 case XML_SCHEMA_TYPE_CHOICE:{
pcercuei 0:03b5121a232e 12981 xmlSchemaTreeItemPtr sub;
pcercuei 0:03b5121a232e 12982 xmlAutomataStatePtr start, end;
pcercuei 0:03b5121a232e 12983
pcercuei 0:03b5121a232e 12984 ret = 0;
pcercuei 0:03b5121a232e 12985 start = pctxt->state;
pcercuei 0:03b5121a232e 12986 end = xmlAutomataNewState(pctxt->am);
pcercuei 0:03b5121a232e 12987
pcercuei 0:03b5121a232e 12988 /*
pcercuei 0:03b5121a232e 12989 * iterate over the subtypes and remerge the end with an
pcercuei 0:03b5121a232e 12990 * epsilon transition
pcercuei 0:03b5121a232e 12991 */
pcercuei 0:03b5121a232e 12992 if (particle->maxOccurs == 1) {
pcercuei 0:03b5121a232e 12993 sub = particle->children->children;
pcercuei 0:03b5121a232e 12994 while (sub != NULL) {
pcercuei 0:03b5121a232e 12995 pctxt->state = start;
pcercuei 0:03b5121a232e 12996 tmp2 = xmlSchemaBuildAContentModel(pctxt,
pcercuei 0:03b5121a232e 12997 (xmlSchemaParticlePtr) sub);
pcercuei 0:03b5121a232e 12998 if (tmp2 == 1) ret = 1;
pcercuei 0:03b5121a232e 12999 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
pcercuei 0:03b5121a232e 13000 sub = sub->next;
pcercuei 0:03b5121a232e 13001 }
pcercuei 0:03b5121a232e 13002 } else {
pcercuei 0:03b5121a232e 13003 int counter;
pcercuei 0:03b5121a232e 13004 xmlAutomataStatePtr hop, base;
pcercuei 0:03b5121a232e 13005 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
pcercuei 0:03b5121a232e 13006 UNBOUNDED : particle->maxOccurs - 1;
pcercuei 0:03b5121a232e 13007 int minOccurs =
pcercuei 0:03b5121a232e 13008 particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
pcercuei 0:03b5121a232e 13009
pcercuei 0:03b5121a232e 13010 /*
pcercuei 0:03b5121a232e 13011 * use a counter to keep track of the number of transtions
pcercuei 0:03b5121a232e 13012 * which went through the choice.
pcercuei 0:03b5121a232e 13013 */
pcercuei 0:03b5121a232e 13014 counter =
pcercuei 0:03b5121a232e 13015 xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
pcercuei 0:03b5121a232e 13016 hop = xmlAutomataNewState(pctxt->am);
pcercuei 0:03b5121a232e 13017 base = xmlAutomataNewState(pctxt->am);
pcercuei 0:03b5121a232e 13018
pcercuei 0:03b5121a232e 13019 sub = particle->children->children;
pcercuei 0:03b5121a232e 13020 while (sub != NULL) {
pcercuei 0:03b5121a232e 13021 pctxt->state = base;
pcercuei 0:03b5121a232e 13022 tmp2 = xmlSchemaBuildAContentModel(pctxt,
pcercuei 0:03b5121a232e 13023 (xmlSchemaParticlePtr) sub);
pcercuei 0:03b5121a232e 13024 if (tmp2 == 1) ret = 1;
pcercuei 0:03b5121a232e 13025 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
pcercuei 0:03b5121a232e 13026 sub = sub->next;
pcercuei 0:03b5121a232e 13027 }
pcercuei 0:03b5121a232e 13028 xmlAutomataNewEpsilon(pctxt->am, start, base);
pcercuei 0:03b5121a232e 13029 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
pcercuei 0:03b5121a232e 13030 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
pcercuei 0:03b5121a232e 13031 if (ret == 1)
pcercuei 0:03b5121a232e 13032 xmlAutomataNewEpsilon(pctxt->am, base, end);
pcercuei 0:03b5121a232e 13033 }
pcercuei 0:03b5121a232e 13034 if (particle->minOccurs == 0) {
pcercuei 0:03b5121a232e 13035 xmlAutomataNewEpsilon(pctxt->am, start, end);
pcercuei 0:03b5121a232e 13036 ret = 1;
pcercuei 0:03b5121a232e 13037 }
pcercuei 0:03b5121a232e 13038 pctxt->state = end;
pcercuei 0:03b5121a232e 13039 break;
pcercuei 0:03b5121a232e 13040 }
pcercuei 0:03b5121a232e 13041 case XML_SCHEMA_TYPE_ALL:{
pcercuei 0:03b5121a232e 13042 xmlAutomataStatePtr start, tmp;
pcercuei 0:03b5121a232e 13043 xmlSchemaParticlePtr sub;
pcercuei 0:03b5121a232e 13044 xmlSchemaElementPtr elemDecl;
pcercuei 0:03b5121a232e 13045
pcercuei 0:03b5121a232e 13046 ret = 1;
pcercuei 0:03b5121a232e 13047
pcercuei 0:03b5121a232e 13048 sub = (xmlSchemaParticlePtr) particle->children->children;
pcercuei 0:03b5121a232e 13049 if (sub == NULL)
pcercuei 0:03b5121a232e 13050 break;
pcercuei 0:03b5121a232e 13051
pcercuei 0:03b5121a232e 13052 ret = 0;
pcercuei 0:03b5121a232e 13053
pcercuei 0:03b5121a232e 13054 start = pctxt->state;
pcercuei 0:03b5121a232e 13055 tmp = xmlAutomataNewState(pctxt->am);
pcercuei 0:03b5121a232e 13056 xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
pcercuei 0:03b5121a232e 13057 pctxt->state = tmp;
pcercuei 0:03b5121a232e 13058 while (sub != NULL) {
pcercuei 0:03b5121a232e 13059 pctxt->state = tmp;
pcercuei 0:03b5121a232e 13060
pcercuei 0:03b5121a232e 13061 elemDecl = (xmlSchemaElementPtr) sub->children;
pcercuei 0:03b5121a232e 13062 if (elemDecl == NULL) {
pcercuei 0:03b5121a232e 13063 PERROR_INT("xmlSchemaBuildAContentModel",
pcercuei 0:03b5121a232e 13064 "<element> particle has no term");
pcercuei 0:03b5121a232e 13065 return(ret);
pcercuei 0:03b5121a232e 13066 };
pcercuei 0:03b5121a232e 13067 /*
pcercuei 0:03b5121a232e 13068 * NOTE: The {max occurs} of all the particles in the
pcercuei 0:03b5121a232e 13069 * {particles} of the group must be 0 or 1; this is
pcercuei 0:03b5121a232e 13070 * already ensured during the parse of the content of
pcercuei 0:03b5121a232e 13071 * <all>.
pcercuei 0:03b5121a232e 13072 */
pcercuei 0:03b5121a232e 13073 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
pcercuei 0:03b5121a232e 13074 int counter;
pcercuei 0:03b5121a232e 13075
pcercuei 0:03b5121a232e 13076 /*
pcercuei 0:03b5121a232e 13077 * This is an abstract group, we need to share
pcercuei 0:03b5121a232e 13078 * the same counter for all the element transitions
pcercuei 0:03b5121a232e 13079 * derived from the group
pcercuei 0:03b5121a232e 13080 */
pcercuei 0:03b5121a232e 13081 counter = xmlAutomataNewCounter(pctxt->am,
pcercuei 0:03b5121a232e 13082 sub->minOccurs, sub->maxOccurs);
pcercuei 0:03b5121a232e 13083 xmlSchemaBuildContentModelForSubstGroup(pctxt,
pcercuei 0:03b5121a232e 13084 sub, counter, pctxt->state);
pcercuei 0:03b5121a232e 13085 } else {
pcercuei 0:03b5121a232e 13086 if ((sub->minOccurs == 1) &&
pcercuei 0:03b5121a232e 13087 (sub->maxOccurs == 1)) {
pcercuei 0:03b5121a232e 13088 xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
pcercuei 0:03b5121a232e 13089 pctxt->state,
pcercuei 0:03b5121a232e 13090 elemDecl->name,
pcercuei 0:03b5121a232e 13091 elemDecl->targetNamespace,
pcercuei 0:03b5121a232e 13092 1, 1, elemDecl);
pcercuei 0:03b5121a232e 13093 } else if ((sub->minOccurs == 0) &&
pcercuei 0:03b5121a232e 13094 (sub->maxOccurs == 1)) {
pcercuei 0:03b5121a232e 13095
pcercuei 0:03b5121a232e 13096 xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
pcercuei 0:03b5121a232e 13097 pctxt->state,
pcercuei 0:03b5121a232e 13098 elemDecl->name,
pcercuei 0:03b5121a232e 13099 elemDecl->targetNamespace,
pcercuei 0:03b5121a232e 13100 0,
pcercuei 0:03b5121a232e 13101 1,
pcercuei 0:03b5121a232e 13102 elemDecl);
pcercuei 0:03b5121a232e 13103 }
pcercuei 0:03b5121a232e 13104 }
pcercuei 0:03b5121a232e 13105 sub = (xmlSchemaParticlePtr) sub->next;
pcercuei 0:03b5121a232e 13106 }
pcercuei 0:03b5121a232e 13107 pctxt->state =
pcercuei 0:03b5121a232e 13108 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
pcercuei 0:03b5121a232e 13109 if (particle->minOccurs == 0) {
pcercuei 0:03b5121a232e 13110 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
pcercuei 0:03b5121a232e 13111 ret = 1;
pcercuei 0:03b5121a232e 13112 }
pcercuei 0:03b5121a232e 13113 break;
pcercuei 0:03b5121a232e 13114 }
pcercuei 0:03b5121a232e 13115 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 13116 /*
pcercuei 0:03b5121a232e 13117 * If we hit a model group definition, then this means that
pcercuei 0:03b5121a232e 13118 * it was empty, thus was not substituted for the containing
pcercuei 0:03b5121a232e 13119 * model group. Just do nothing in this case.
pcercuei 0:03b5121a232e 13120 * TODO: But the group should be substituted and not occur at
pcercuei 0:03b5121a232e 13121 * all in the content model at this point. Fix this.
pcercuei 0:03b5121a232e 13122 */
pcercuei 0:03b5121a232e 13123 ret = 1;
pcercuei 0:03b5121a232e 13124 break;
pcercuei 0:03b5121a232e 13125 default:
pcercuei 0:03b5121a232e 13126 xmlSchemaInternalErr2(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 13127 "xmlSchemaBuildAContentModel",
pcercuei 0:03b5121a232e 13128 "found unexpected term of type '%s' in content model",
pcercuei 0:03b5121a232e 13129 WXS_ITEM_TYPE_NAME(particle->children), NULL);
pcercuei 0:03b5121a232e 13130 return(ret);
pcercuei 0:03b5121a232e 13131 }
pcercuei 0:03b5121a232e 13132 return(ret);
pcercuei 0:03b5121a232e 13133 }
pcercuei 0:03b5121a232e 13134
pcercuei 0:03b5121a232e 13135 /**
pcercuei 0:03b5121a232e 13136 * xmlSchemaBuildContentModel:
pcercuei 0:03b5121a232e 13137 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 13138 * @type: the complex type definition
pcercuei 0:03b5121a232e 13139 * @name: the element name
pcercuei 0:03b5121a232e 13140 *
pcercuei 0:03b5121a232e 13141 * Builds the content model of the complex type.
pcercuei 0:03b5121a232e 13142 */
pcercuei 0:03b5121a232e 13143 static void
pcercuei 0:03b5121a232e 13144 xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 13145 xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 13146 {
pcercuei 0:03b5121a232e 13147 if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
pcercuei 0:03b5121a232e 13148 (type->contModel != NULL) ||
pcercuei 0:03b5121a232e 13149 ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
pcercuei 0:03b5121a232e 13150 (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
pcercuei 0:03b5121a232e 13151 return;
pcercuei 0:03b5121a232e 13152
pcercuei 0:03b5121a232e 13153 #ifdef DEBUG_CONTENT
pcercuei 0:03b5121a232e 13154 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 13155 "Building content model for %s\n", name);
pcercuei 0:03b5121a232e 13156 #endif
pcercuei 0:03b5121a232e 13157 ctxt->am = NULL;
pcercuei 0:03b5121a232e 13158 ctxt->am = xmlNewAutomata();
pcercuei 0:03b5121a232e 13159 if (ctxt->am == NULL) {
pcercuei 0:03b5121a232e 13160 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 13161 "Cannot create automata for complex type %s\n", type->name);
pcercuei 0:03b5121a232e 13162 return;
pcercuei 0:03b5121a232e 13163 }
pcercuei 0:03b5121a232e 13164 ctxt->state = xmlAutomataGetInitState(ctxt->am);
pcercuei 0:03b5121a232e 13165 /*
pcercuei 0:03b5121a232e 13166 * Build the automaton.
pcercuei 0:03b5121a232e 13167 */
pcercuei 0:03b5121a232e 13168 xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
pcercuei 0:03b5121a232e 13169 xmlAutomataSetFinalState(ctxt->am, ctxt->state);
pcercuei 0:03b5121a232e 13170 type->contModel = xmlAutomataCompile(ctxt->am);
pcercuei 0:03b5121a232e 13171 if (type->contModel == NULL) {
pcercuei 0:03b5121a232e 13172 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 13173 XML_SCHEMAP_INTERNAL,
pcercuei 0:03b5121a232e 13174 WXS_BASIC_CAST type, type->node,
pcercuei 0:03b5121a232e 13175 "Failed to compile the content model", NULL);
pcercuei 0:03b5121a232e 13176 } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
pcercuei 0:03b5121a232e 13177 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 13178 XML_SCHEMAP_NOT_DETERMINISTIC,
pcercuei 0:03b5121a232e 13179 /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
pcercuei 0:03b5121a232e 13180 WXS_BASIC_CAST type, type->node,
pcercuei 0:03b5121a232e 13181 "The content model is not determinist", NULL);
pcercuei 0:03b5121a232e 13182 } else {
pcercuei 0:03b5121a232e 13183 #ifdef DEBUG_CONTENT_REGEXP
pcercuei 0:03b5121a232e 13184 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 13185 "Content model of %s:\n", type->name);
pcercuei 0:03b5121a232e 13186 xmlRegexpPrint(stderr, type->contModel);
pcercuei 0:03b5121a232e 13187 #endif
pcercuei 0:03b5121a232e 13188 }
pcercuei 0:03b5121a232e 13189 ctxt->state = NULL;
pcercuei 0:03b5121a232e 13190 xmlFreeAutomata(ctxt->am);
pcercuei 0:03b5121a232e 13191 ctxt->am = NULL;
pcercuei 0:03b5121a232e 13192 }
pcercuei 0:03b5121a232e 13193
pcercuei 0:03b5121a232e 13194 /**
pcercuei 0:03b5121a232e 13195 * xmlSchemaResolveElementReferences:
pcercuei 0:03b5121a232e 13196 * @elem: the schema element context
pcercuei 0:03b5121a232e 13197 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 13198 *
pcercuei 0:03b5121a232e 13199 * Resolves the references of an element declaration
pcercuei 0:03b5121a232e 13200 * or particle, which has an element declaration as it's
pcercuei 0:03b5121a232e 13201 * term.
pcercuei 0:03b5121a232e 13202 */
pcercuei 0:03b5121a232e 13203 static void
pcercuei 0:03b5121a232e 13204 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
pcercuei 0:03b5121a232e 13205 xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 13206 {
pcercuei 0:03b5121a232e 13207 if ((ctxt == NULL) || (elemDecl == NULL) ||
pcercuei 0:03b5121a232e 13208 ((elemDecl != NULL) &&
pcercuei 0:03b5121a232e 13209 (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
pcercuei 0:03b5121a232e 13210 return;
pcercuei 0:03b5121a232e 13211 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
pcercuei 0:03b5121a232e 13212
pcercuei 0:03b5121a232e 13213 if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
pcercuei 0:03b5121a232e 13214 xmlSchemaTypePtr type;
pcercuei 0:03b5121a232e 13215
pcercuei 0:03b5121a232e 13216 /* (type definition) ... otherwise the type definition `resolved`
pcercuei 0:03b5121a232e 13217 * to by the `actual value` of the type [attribute] ...
pcercuei 0:03b5121a232e 13218 */
pcercuei 0:03b5121a232e 13219 type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
pcercuei 0:03b5121a232e 13220 elemDecl->namedTypeNs);
pcercuei 0:03b5121a232e 13221 if (type == NULL) {
pcercuei 0:03b5121a232e 13222 xmlSchemaPResCompAttrErr(ctxt,
pcercuei 0:03b5121a232e 13223 XML_SCHEMAP_SRC_RESOLVE,
pcercuei 0:03b5121a232e 13224 WXS_BASIC_CAST elemDecl, elemDecl->node,
pcercuei 0:03b5121a232e 13225 "type", elemDecl->namedType, elemDecl->namedTypeNs,
pcercuei 0:03b5121a232e 13226 XML_SCHEMA_TYPE_BASIC, "type definition");
pcercuei 0:03b5121a232e 13227 } else
pcercuei 0:03b5121a232e 13228 elemDecl->subtypes = type;
pcercuei 0:03b5121a232e 13229 }
pcercuei 0:03b5121a232e 13230 if (elemDecl->substGroup != NULL) {
pcercuei 0:03b5121a232e 13231 xmlSchemaElementPtr substHead;
pcercuei 0:03b5121a232e 13232
pcercuei 0:03b5121a232e 13233 /*
pcercuei 0:03b5121a232e 13234 * FIXME TODO: Do we need a new field in _xmlSchemaElement for
pcercuei 0:03b5121a232e 13235 * substitutionGroup?
pcercuei 0:03b5121a232e 13236 */
pcercuei 0:03b5121a232e 13237 substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
pcercuei 0:03b5121a232e 13238 elemDecl->substGroupNs);
pcercuei 0:03b5121a232e 13239 if (substHead == NULL) {
pcercuei 0:03b5121a232e 13240 xmlSchemaPResCompAttrErr(ctxt,
pcercuei 0:03b5121a232e 13241 XML_SCHEMAP_SRC_RESOLVE,
pcercuei 0:03b5121a232e 13242 WXS_BASIC_CAST elemDecl, NULL,
pcercuei 0:03b5121a232e 13243 "substitutionGroup", elemDecl->substGroup,
pcercuei 0:03b5121a232e 13244 elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
pcercuei 0:03b5121a232e 13245 } else {
pcercuei 0:03b5121a232e 13246 xmlSchemaResolveElementReferences(substHead, ctxt);
pcercuei 0:03b5121a232e 13247 /*
pcercuei 0:03b5121a232e 13248 * Set the "substitution group affiliation".
pcercuei 0:03b5121a232e 13249 * NOTE that now we use the "refDecl" field for this.
pcercuei 0:03b5121a232e 13250 */
pcercuei 0:03b5121a232e 13251 WXS_SUBST_HEAD(elemDecl) = substHead;
pcercuei 0:03b5121a232e 13252 /*
pcercuei 0:03b5121a232e 13253 * The type definitions is set to:
pcercuei 0:03b5121a232e 13254 * SPEC "...the {type definition} of the element
pcercuei 0:03b5121a232e 13255 * declaration `resolved` to by the `actual value`
pcercuei 0:03b5121a232e 13256 * of the substitutionGroup [attribute], if present"
pcercuei 0:03b5121a232e 13257 */
pcercuei 0:03b5121a232e 13258 if (elemDecl->subtypes == NULL)
pcercuei 0:03b5121a232e 13259 elemDecl->subtypes = substHead->subtypes;
pcercuei 0:03b5121a232e 13260 }
pcercuei 0:03b5121a232e 13261 }
pcercuei 0:03b5121a232e 13262 /*
pcercuei 0:03b5121a232e 13263 * SPEC "The definition of anyType serves as the default type definition
pcercuei 0:03b5121a232e 13264 * for element declarations whose XML representation does not specify one."
pcercuei 0:03b5121a232e 13265 */
pcercuei 0:03b5121a232e 13266 if ((elemDecl->subtypes == NULL) &&
pcercuei 0:03b5121a232e 13267 (elemDecl->namedType == NULL) &&
pcercuei 0:03b5121a232e 13268 (elemDecl->substGroup == NULL))
pcercuei 0:03b5121a232e 13269 elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
pcercuei 0:03b5121a232e 13270 }
pcercuei 0:03b5121a232e 13271
pcercuei 0:03b5121a232e 13272 /**
pcercuei 0:03b5121a232e 13273 * xmlSchemaResolveUnionMemberTypes:
pcercuei 0:03b5121a232e 13274 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 13275 * @type: the schema simple type definition
pcercuei 0:03b5121a232e 13276 *
pcercuei 0:03b5121a232e 13277 * Checks and builds the "member type definitions" property of the union
pcercuei 0:03b5121a232e 13278 * simple type. This handles part (1), part (2) is done in
pcercuei 0:03b5121a232e 13279 * xmlSchemaFinishMemberTypeDefinitionsProperty()
pcercuei 0:03b5121a232e 13280 *
pcercuei 0:03b5121a232e 13281 * Returns -1 in case of an internal error, 0 otherwise.
pcercuei 0:03b5121a232e 13282 */
pcercuei 0:03b5121a232e 13283 static int
pcercuei 0:03b5121a232e 13284 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 13285 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 13286 {
pcercuei 0:03b5121a232e 13287
pcercuei 0:03b5121a232e 13288 xmlSchemaTypeLinkPtr link, lastLink, newLink;
pcercuei 0:03b5121a232e 13289 xmlSchemaTypePtr memberType;
pcercuei 0:03b5121a232e 13290
pcercuei 0:03b5121a232e 13291 /*
pcercuei 0:03b5121a232e 13292 * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
pcercuei 0:03b5121a232e 13293 * define the explicit members as the type definitions `resolved`
pcercuei 0:03b5121a232e 13294 * to by the items in the `actual value` of the memberTypes [attribute],
pcercuei 0:03b5121a232e 13295 * if any, followed by the type definitions corresponding to the
pcercuei 0:03b5121a232e 13296 * <simpleType>s among the [children] of <union>, if any."
pcercuei 0:03b5121a232e 13297 */
pcercuei 0:03b5121a232e 13298 /*
pcercuei 0:03b5121a232e 13299 * Resolve references.
pcercuei 0:03b5121a232e 13300 */
pcercuei 0:03b5121a232e 13301 link = type->memberTypes;
pcercuei 0:03b5121a232e 13302 lastLink = NULL;
pcercuei 0:03b5121a232e 13303 while (link != NULL) {
pcercuei 0:03b5121a232e 13304 const xmlChar *name, *nsName;
pcercuei 0:03b5121a232e 13305
pcercuei 0:03b5121a232e 13306 name = ((xmlSchemaQNameRefPtr) link->type)->name;
pcercuei 0:03b5121a232e 13307 nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
pcercuei 0:03b5121a232e 13308
pcercuei 0:03b5121a232e 13309 memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
pcercuei 0:03b5121a232e 13310 if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
pcercuei 0:03b5121a232e 13311 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
pcercuei 0:03b5121a232e 13312 WXS_BASIC_CAST type, type->node, "memberTypes",
pcercuei 0:03b5121a232e 13313 name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
pcercuei 0:03b5121a232e 13314 /*
pcercuei 0:03b5121a232e 13315 * Remove the member type link.
pcercuei 0:03b5121a232e 13316 */
pcercuei 0:03b5121a232e 13317 if (lastLink == NULL)
pcercuei 0:03b5121a232e 13318 type->memberTypes = link->next;
pcercuei 0:03b5121a232e 13319 else
pcercuei 0:03b5121a232e 13320 lastLink->next = link->next;
pcercuei 0:03b5121a232e 13321 newLink = link;
pcercuei 0:03b5121a232e 13322 link = link->next;
pcercuei 0:03b5121a232e 13323 xmlFree(newLink);
pcercuei 0:03b5121a232e 13324 } else {
pcercuei 0:03b5121a232e 13325 link->type = memberType;
pcercuei 0:03b5121a232e 13326 lastLink = link;
pcercuei 0:03b5121a232e 13327 link = link->next;
pcercuei 0:03b5121a232e 13328 }
pcercuei 0:03b5121a232e 13329 }
pcercuei 0:03b5121a232e 13330 /*
pcercuei 0:03b5121a232e 13331 * Add local simple types,
pcercuei 0:03b5121a232e 13332 */
pcercuei 0:03b5121a232e 13333 memberType = type->subtypes;
pcercuei 0:03b5121a232e 13334 while (memberType != NULL) {
pcercuei 0:03b5121a232e 13335 link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
pcercuei 0:03b5121a232e 13336 if (link == NULL) {
pcercuei 0:03b5121a232e 13337 xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
pcercuei 0:03b5121a232e 13338 return (-1);
pcercuei 0:03b5121a232e 13339 }
pcercuei 0:03b5121a232e 13340 link->type = memberType;
pcercuei 0:03b5121a232e 13341 link->next = NULL;
pcercuei 0:03b5121a232e 13342 if (lastLink == NULL)
pcercuei 0:03b5121a232e 13343 type->memberTypes = link;
pcercuei 0:03b5121a232e 13344 else
pcercuei 0:03b5121a232e 13345 lastLink->next = link;
pcercuei 0:03b5121a232e 13346 lastLink = link;
pcercuei 0:03b5121a232e 13347 memberType = memberType->next;
pcercuei 0:03b5121a232e 13348 }
pcercuei 0:03b5121a232e 13349 return (0);
pcercuei 0:03b5121a232e 13350 }
pcercuei 0:03b5121a232e 13351
pcercuei 0:03b5121a232e 13352 /**
pcercuei 0:03b5121a232e 13353 * xmlSchemaIsDerivedFromBuiltInType:
pcercuei 0:03b5121a232e 13354 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 13355 * @type: the type definition
pcercuei 0:03b5121a232e 13356 * @valType: the value type
pcercuei 0:03b5121a232e 13357 *
pcercuei 0:03b5121a232e 13358 *
pcercuei 0:03b5121a232e 13359 * Returns 1 if the type has the given value type, or
pcercuei 0:03b5121a232e 13360 * is derived from such a type.
pcercuei 0:03b5121a232e 13361 */
pcercuei 0:03b5121a232e 13362 static int
pcercuei 0:03b5121a232e 13363 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
pcercuei 0:03b5121a232e 13364 {
pcercuei 0:03b5121a232e 13365 if (type == NULL)
pcercuei 0:03b5121a232e 13366 return (0);
pcercuei 0:03b5121a232e 13367 if (WXS_IS_COMPLEX(type))
pcercuei 0:03b5121a232e 13368 return (0);
pcercuei 0:03b5121a232e 13369 if (type->type == XML_SCHEMA_TYPE_BASIC) {
pcercuei 0:03b5121a232e 13370 if (type->builtInType == valType)
pcercuei 0:03b5121a232e 13371 return(1);
pcercuei 0:03b5121a232e 13372 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
pcercuei 0:03b5121a232e 13373 (type->builtInType == XML_SCHEMAS_ANYTYPE))
pcercuei 0:03b5121a232e 13374 return (0);
pcercuei 0:03b5121a232e 13375 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
pcercuei 0:03b5121a232e 13376 }
pcercuei 0:03b5121a232e 13377 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
pcercuei 0:03b5121a232e 13378 }
pcercuei 0:03b5121a232e 13379
pcercuei 0:03b5121a232e 13380 #if 0
pcercuei 0:03b5121a232e 13381 /**
pcercuei 0:03b5121a232e 13382 * xmlSchemaIsDerivedFromBuiltInType:
pcercuei 0:03b5121a232e 13383 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 13384 * @type: the type definition
pcercuei 0:03b5121a232e 13385 * @valType: the value type
pcercuei 0:03b5121a232e 13386 *
pcercuei 0:03b5121a232e 13387 *
pcercuei 0:03b5121a232e 13388 * Returns 1 if the type has the given value type, or
pcercuei 0:03b5121a232e 13389 * is derived from such a type.
pcercuei 0:03b5121a232e 13390 */
pcercuei 0:03b5121a232e 13391 static int
pcercuei 0:03b5121a232e 13392 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
pcercuei 0:03b5121a232e 13393 {
pcercuei 0:03b5121a232e 13394 if (type == NULL)
pcercuei 0:03b5121a232e 13395 return (0);
pcercuei 0:03b5121a232e 13396 if (WXS_IS_COMPLEX(type))
pcercuei 0:03b5121a232e 13397 return (0);
pcercuei 0:03b5121a232e 13398 if (type->type == XML_SCHEMA_TYPE_BASIC) {
pcercuei 0:03b5121a232e 13399 if (type->builtInType == valType)
pcercuei 0:03b5121a232e 13400 return(1);
pcercuei 0:03b5121a232e 13401 return (0);
pcercuei 0:03b5121a232e 13402 } else
pcercuei 0:03b5121a232e 13403 return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
pcercuei 0:03b5121a232e 13404
pcercuei 0:03b5121a232e 13405 return (0);
pcercuei 0:03b5121a232e 13406 }
pcercuei 0:03b5121a232e 13407
pcercuei 0:03b5121a232e 13408 static xmlSchemaTypePtr
pcercuei 0:03b5121a232e 13409 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 13410 {
pcercuei 0:03b5121a232e 13411 if (type == NULL)
pcercuei 0:03b5121a232e 13412 return (NULL);
pcercuei 0:03b5121a232e 13413 if (WXS_IS_COMPLEX(type))
pcercuei 0:03b5121a232e 13414 return (NULL);
pcercuei 0:03b5121a232e 13415 if (type->type == XML_SCHEMA_TYPE_BASIC)
pcercuei 0:03b5121a232e 13416 return(type);
pcercuei 0:03b5121a232e 13417 return(xmlSchemaQueryBuiltInType(type->subtypes));
pcercuei 0:03b5121a232e 13418 }
pcercuei 0:03b5121a232e 13419 #endif
pcercuei 0:03b5121a232e 13420
pcercuei 0:03b5121a232e 13421 /**
pcercuei 0:03b5121a232e 13422 * xmlSchemaGetPrimitiveType:
pcercuei 0:03b5121a232e 13423 * @type: the simpleType definition
pcercuei 0:03b5121a232e 13424 *
pcercuei 0:03b5121a232e 13425 * Returns the primitive type of the given type or
pcercuei 0:03b5121a232e 13426 * NULL in case of error.
pcercuei 0:03b5121a232e 13427 */
pcercuei 0:03b5121a232e 13428 static xmlSchemaTypePtr
pcercuei 0:03b5121a232e 13429 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 13430 {
pcercuei 0:03b5121a232e 13431
pcercuei 0:03b5121a232e 13432 while (type != NULL) {
pcercuei 0:03b5121a232e 13433 /*
pcercuei 0:03b5121a232e 13434 * Note that anySimpleType is actually not a primitive type
pcercuei 0:03b5121a232e 13435 * but we need that here.
pcercuei 0:03b5121a232e 13436 */
pcercuei 0:03b5121a232e 13437 if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
pcercuei 0:03b5121a232e 13438 (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
pcercuei 0:03b5121a232e 13439 return (type);
pcercuei 0:03b5121a232e 13440 type = type->baseType;
pcercuei 0:03b5121a232e 13441 }
pcercuei 0:03b5121a232e 13442
pcercuei 0:03b5121a232e 13443 return (NULL);
pcercuei 0:03b5121a232e 13444 }
pcercuei 0:03b5121a232e 13445
pcercuei 0:03b5121a232e 13446 #if 0
pcercuei 0:03b5121a232e 13447 /**
pcercuei 0:03b5121a232e 13448 * xmlSchemaGetBuiltInTypeAncestor:
pcercuei 0:03b5121a232e 13449 * @type: the simpleType definition
pcercuei 0:03b5121a232e 13450 *
pcercuei 0:03b5121a232e 13451 * Returns the primitive type of the given type or
pcercuei 0:03b5121a232e 13452 * NULL in case of error.
pcercuei 0:03b5121a232e 13453 */
pcercuei 0:03b5121a232e 13454 static xmlSchemaTypePtr
pcercuei 0:03b5121a232e 13455 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 13456 {
pcercuei 0:03b5121a232e 13457 if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
pcercuei 0:03b5121a232e 13458 return (0);
pcercuei 0:03b5121a232e 13459 while (type != NULL) {
pcercuei 0:03b5121a232e 13460 if (type->type == XML_SCHEMA_TYPE_BASIC)
pcercuei 0:03b5121a232e 13461 return (type);
pcercuei 0:03b5121a232e 13462 type = type->baseType;
pcercuei 0:03b5121a232e 13463 }
pcercuei 0:03b5121a232e 13464
pcercuei 0:03b5121a232e 13465 return (NULL);
pcercuei 0:03b5121a232e 13466 }
pcercuei 0:03b5121a232e 13467 #endif
pcercuei 0:03b5121a232e 13468
pcercuei 0:03b5121a232e 13469 /**
pcercuei 0:03b5121a232e 13470 * xmlSchemaCloneWildcardNsConstraints:
pcercuei 0:03b5121a232e 13471 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 13472 * @dest: the destination wildcard
pcercuei 0:03b5121a232e 13473 * @source: the source wildcard
pcercuei 0:03b5121a232e 13474 *
pcercuei 0:03b5121a232e 13475 * Clones the namespace constraints of source
pcercuei 0:03b5121a232e 13476 * and assignes them to dest.
pcercuei 0:03b5121a232e 13477 * Returns -1 on internal error, 0 otherwise.
pcercuei 0:03b5121a232e 13478 */
pcercuei 0:03b5121a232e 13479 static int
pcercuei 0:03b5121a232e 13480 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 13481 xmlSchemaWildcardPtr dest,
pcercuei 0:03b5121a232e 13482 xmlSchemaWildcardPtr source)
pcercuei 0:03b5121a232e 13483 {
pcercuei 0:03b5121a232e 13484 xmlSchemaWildcardNsPtr cur, tmp, last;
pcercuei 0:03b5121a232e 13485
pcercuei 0:03b5121a232e 13486 if ((source == NULL) || (dest == NULL))
pcercuei 0:03b5121a232e 13487 return(-1);
pcercuei 0:03b5121a232e 13488 dest->any = source->any;
pcercuei 0:03b5121a232e 13489 cur = source->nsSet;
pcercuei 0:03b5121a232e 13490 last = NULL;
pcercuei 0:03b5121a232e 13491 while (cur != NULL) {
pcercuei 0:03b5121a232e 13492 tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
pcercuei 0:03b5121a232e 13493 if (tmp == NULL)
pcercuei 0:03b5121a232e 13494 return(-1);
pcercuei 0:03b5121a232e 13495 tmp->value = cur->value;
pcercuei 0:03b5121a232e 13496 if (last == NULL)
pcercuei 0:03b5121a232e 13497 dest->nsSet = tmp;
pcercuei 0:03b5121a232e 13498 else
pcercuei 0:03b5121a232e 13499 last->next = tmp;
pcercuei 0:03b5121a232e 13500 last = tmp;
pcercuei 0:03b5121a232e 13501 cur = cur->next;
pcercuei 0:03b5121a232e 13502 }
pcercuei 0:03b5121a232e 13503 if (dest->negNsSet != NULL)
pcercuei 0:03b5121a232e 13504 xmlSchemaFreeWildcardNsSet(dest->negNsSet);
pcercuei 0:03b5121a232e 13505 if (source->negNsSet != NULL) {
pcercuei 0:03b5121a232e 13506 dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
pcercuei 0:03b5121a232e 13507 if (dest->negNsSet == NULL)
pcercuei 0:03b5121a232e 13508 return(-1);
pcercuei 0:03b5121a232e 13509 dest->negNsSet->value = source->negNsSet->value;
pcercuei 0:03b5121a232e 13510 } else
pcercuei 0:03b5121a232e 13511 dest->negNsSet = NULL;
pcercuei 0:03b5121a232e 13512 return(0);
pcercuei 0:03b5121a232e 13513 }
pcercuei 0:03b5121a232e 13514
pcercuei 0:03b5121a232e 13515 /**
pcercuei 0:03b5121a232e 13516 * xmlSchemaUnionWildcards:
pcercuei 0:03b5121a232e 13517 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 13518 * @completeWild: the first wildcard
pcercuei 0:03b5121a232e 13519 * @curWild: the second wildcard
pcercuei 0:03b5121a232e 13520 *
pcercuei 0:03b5121a232e 13521 * Unions the namespace constraints of the given wildcards.
pcercuei 0:03b5121a232e 13522 * @completeWild will hold the resulting union.
pcercuei 0:03b5121a232e 13523 * Returns a positive error code on failure, -1 in case of an
pcercuei 0:03b5121a232e 13524 * internal error, 0 otherwise.
pcercuei 0:03b5121a232e 13525 */
pcercuei 0:03b5121a232e 13526 static int
pcercuei 0:03b5121a232e 13527 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 13528 xmlSchemaWildcardPtr completeWild,
pcercuei 0:03b5121a232e 13529 xmlSchemaWildcardPtr curWild)
pcercuei 0:03b5121a232e 13530 {
pcercuei 0:03b5121a232e 13531 xmlSchemaWildcardNsPtr cur, curB, tmp;
pcercuei 0:03b5121a232e 13532
pcercuei 0:03b5121a232e 13533 /*
pcercuei 0:03b5121a232e 13534 * 1 If O1 and O2 are the same value, then that value must be the
pcercuei 0:03b5121a232e 13535 * value.
pcercuei 0:03b5121a232e 13536 */
pcercuei 0:03b5121a232e 13537 if ((completeWild->any == curWild->any) &&
pcercuei 0:03b5121a232e 13538 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
pcercuei 0:03b5121a232e 13539 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
pcercuei 0:03b5121a232e 13540
pcercuei 0:03b5121a232e 13541 if ((completeWild->negNsSet == NULL) ||
pcercuei 0:03b5121a232e 13542 (completeWild->negNsSet->value == curWild->negNsSet->value)) {
pcercuei 0:03b5121a232e 13543
pcercuei 0:03b5121a232e 13544 if (completeWild->nsSet != NULL) {
pcercuei 0:03b5121a232e 13545 int found = 0;
pcercuei 0:03b5121a232e 13546
pcercuei 0:03b5121a232e 13547 /*
pcercuei 0:03b5121a232e 13548 * Check equality of sets.
pcercuei 0:03b5121a232e 13549 */
pcercuei 0:03b5121a232e 13550 cur = completeWild->nsSet;
pcercuei 0:03b5121a232e 13551 while (cur != NULL) {
pcercuei 0:03b5121a232e 13552 found = 0;
pcercuei 0:03b5121a232e 13553 curB = curWild->nsSet;
pcercuei 0:03b5121a232e 13554 while (curB != NULL) {
pcercuei 0:03b5121a232e 13555 if (cur->value == curB->value) {
pcercuei 0:03b5121a232e 13556 found = 1;
pcercuei 0:03b5121a232e 13557 break;
pcercuei 0:03b5121a232e 13558 }
pcercuei 0:03b5121a232e 13559 curB = curB->next;
pcercuei 0:03b5121a232e 13560 }
pcercuei 0:03b5121a232e 13561 if (!found)
pcercuei 0:03b5121a232e 13562 break;
pcercuei 0:03b5121a232e 13563 cur = cur->next;
pcercuei 0:03b5121a232e 13564 }
pcercuei 0:03b5121a232e 13565 if (found)
pcercuei 0:03b5121a232e 13566 return(0);
pcercuei 0:03b5121a232e 13567 } else
pcercuei 0:03b5121a232e 13568 return(0);
pcercuei 0:03b5121a232e 13569 }
pcercuei 0:03b5121a232e 13570 }
pcercuei 0:03b5121a232e 13571 /*
pcercuei 0:03b5121a232e 13572 * 2 If either O1 or O2 is any, then any must be the value
pcercuei 0:03b5121a232e 13573 */
pcercuei 0:03b5121a232e 13574 if (completeWild->any != curWild->any) {
pcercuei 0:03b5121a232e 13575 if (completeWild->any == 0) {
pcercuei 0:03b5121a232e 13576 completeWild->any = 1;
pcercuei 0:03b5121a232e 13577 if (completeWild->nsSet != NULL) {
pcercuei 0:03b5121a232e 13578 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
pcercuei 0:03b5121a232e 13579 completeWild->nsSet = NULL;
pcercuei 0:03b5121a232e 13580 }
pcercuei 0:03b5121a232e 13581 if (completeWild->negNsSet != NULL) {
pcercuei 0:03b5121a232e 13582 xmlFree(completeWild->negNsSet);
pcercuei 0:03b5121a232e 13583 completeWild->negNsSet = NULL;
pcercuei 0:03b5121a232e 13584 }
pcercuei 0:03b5121a232e 13585 }
pcercuei 0:03b5121a232e 13586 return (0);
pcercuei 0:03b5121a232e 13587 }
pcercuei 0:03b5121a232e 13588 /*
pcercuei 0:03b5121a232e 13589 * 3 If both O1 and O2 are sets of (namespace names or `absent`),
pcercuei 0:03b5121a232e 13590 * then the union of those sets must be the value.
pcercuei 0:03b5121a232e 13591 */
pcercuei 0:03b5121a232e 13592 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
pcercuei 0:03b5121a232e 13593 int found;
pcercuei 0:03b5121a232e 13594 xmlSchemaWildcardNsPtr start;
pcercuei 0:03b5121a232e 13595
pcercuei 0:03b5121a232e 13596 cur = curWild->nsSet;
pcercuei 0:03b5121a232e 13597 start = completeWild->nsSet;
pcercuei 0:03b5121a232e 13598 while (cur != NULL) {
pcercuei 0:03b5121a232e 13599 found = 0;
pcercuei 0:03b5121a232e 13600 curB = start;
pcercuei 0:03b5121a232e 13601 while (curB != NULL) {
pcercuei 0:03b5121a232e 13602 if (cur->value == curB->value) {
pcercuei 0:03b5121a232e 13603 found = 1;
pcercuei 0:03b5121a232e 13604 break;
pcercuei 0:03b5121a232e 13605 }
pcercuei 0:03b5121a232e 13606 curB = curB->next;
pcercuei 0:03b5121a232e 13607 }
pcercuei 0:03b5121a232e 13608 if (!found) {
pcercuei 0:03b5121a232e 13609 tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
pcercuei 0:03b5121a232e 13610 if (tmp == NULL)
pcercuei 0:03b5121a232e 13611 return (-1);
pcercuei 0:03b5121a232e 13612 tmp->value = cur->value;
pcercuei 0:03b5121a232e 13613 tmp->next = completeWild->nsSet;
pcercuei 0:03b5121a232e 13614 completeWild->nsSet = tmp;
pcercuei 0:03b5121a232e 13615 }
pcercuei 0:03b5121a232e 13616 cur = cur->next;
pcercuei 0:03b5121a232e 13617 }
pcercuei 0:03b5121a232e 13618
pcercuei 0:03b5121a232e 13619 return(0);
pcercuei 0:03b5121a232e 13620 }
pcercuei 0:03b5121a232e 13621 /*
pcercuei 0:03b5121a232e 13622 * 4 If the two are negations of different values (namespace names
pcercuei 0:03b5121a232e 13623 * or `absent`), then a pair of not and `absent` must be the value.
pcercuei 0:03b5121a232e 13624 */
pcercuei 0:03b5121a232e 13625 if ((completeWild->negNsSet != NULL) &&
pcercuei 0:03b5121a232e 13626 (curWild->negNsSet != NULL) &&
pcercuei 0:03b5121a232e 13627 (completeWild->negNsSet->value != curWild->negNsSet->value)) {
pcercuei 0:03b5121a232e 13628 completeWild->negNsSet->value = NULL;
pcercuei 0:03b5121a232e 13629
pcercuei 0:03b5121a232e 13630 return(0);
pcercuei 0:03b5121a232e 13631 }
pcercuei 0:03b5121a232e 13632 /*
pcercuei 0:03b5121a232e 13633 * 5.
pcercuei 0:03b5121a232e 13634 */
pcercuei 0:03b5121a232e 13635 if (((completeWild->negNsSet != NULL) &&
pcercuei 0:03b5121a232e 13636 (completeWild->negNsSet->value != NULL) &&
pcercuei 0:03b5121a232e 13637 (curWild->nsSet != NULL)) ||
pcercuei 0:03b5121a232e 13638 ((curWild->negNsSet != NULL) &&
pcercuei 0:03b5121a232e 13639 (curWild->negNsSet->value != NULL) &&
pcercuei 0:03b5121a232e 13640 (completeWild->nsSet != NULL))) {
pcercuei 0:03b5121a232e 13641
pcercuei 0:03b5121a232e 13642 int nsFound, absentFound = 0;
pcercuei 0:03b5121a232e 13643
pcercuei 0:03b5121a232e 13644 if (completeWild->nsSet != NULL) {
pcercuei 0:03b5121a232e 13645 cur = completeWild->nsSet;
pcercuei 0:03b5121a232e 13646 curB = curWild->negNsSet;
pcercuei 0:03b5121a232e 13647 } else {
pcercuei 0:03b5121a232e 13648 cur = curWild->nsSet;
pcercuei 0:03b5121a232e 13649 curB = completeWild->negNsSet;
pcercuei 0:03b5121a232e 13650 }
pcercuei 0:03b5121a232e 13651 nsFound = 0;
pcercuei 0:03b5121a232e 13652 while (cur != NULL) {
pcercuei 0:03b5121a232e 13653 if (cur->value == NULL)
pcercuei 0:03b5121a232e 13654 absentFound = 1;
pcercuei 0:03b5121a232e 13655 else if (cur->value == curB->value)
pcercuei 0:03b5121a232e 13656 nsFound = 1;
pcercuei 0:03b5121a232e 13657 if (nsFound && absentFound)
pcercuei 0:03b5121a232e 13658 break;
pcercuei 0:03b5121a232e 13659 cur = cur->next;
pcercuei 0:03b5121a232e 13660 }
pcercuei 0:03b5121a232e 13661
pcercuei 0:03b5121a232e 13662 if (nsFound && absentFound) {
pcercuei 0:03b5121a232e 13663 /*
pcercuei 0:03b5121a232e 13664 * 5.1 If the set S includes both the negated namespace
pcercuei 0:03b5121a232e 13665 * name and `absent`, then any must be the value.
pcercuei 0:03b5121a232e 13666 */
pcercuei 0:03b5121a232e 13667 completeWild->any = 1;
pcercuei 0:03b5121a232e 13668 if (completeWild->nsSet != NULL) {
pcercuei 0:03b5121a232e 13669 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
pcercuei 0:03b5121a232e 13670 completeWild->nsSet = NULL;
pcercuei 0:03b5121a232e 13671 }
pcercuei 0:03b5121a232e 13672 if (completeWild->negNsSet != NULL) {
pcercuei 0:03b5121a232e 13673 xmlFree(completeWild->negNsSet);
pcercuei 0:03b5121a232e 13674 completeWild->negNsSet = NULL;
pcercuei 0:03b5121a232e 13675 }
pcercuei 0:03b5121a232e 13676 } else if (nsFound && (!absentFound)) {
pcercuei 0:03b5121a232e 13677 /*
pcercuei 0:03b5121a232e 13678 * 5.2 If the set S includes the negated namespace name
pcercuei 0:03b5121a232e 13679 * but not `absent`, then a pair of not and `absent` must
pcercuei 0:03b5121a232e 13680 * be the value.
pcercuei 0:03b5121a232e 13681 */
pcercuei 0:03b5121a232e 13682 if (completeWild->nsSet != NULL) {
pcercuei 0:03b5121a232e 13683 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
pcercuei 0:03b5121a232e 13684 completeWild->nsSet = NULL;
pcercuei 0:03b5121a232e 13685 }
pcercuei 0:03b5121a232e 13686 if (completeWild->negNsSet == NULL) {
pcercuei 0:03b5121a232e 13687 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
pcercuei 0:03b5121a232e 13688 if (completeWild->negNsSet == NULL)
pcercuei 0:03b5121a232e 13689 return (-1);
pcercuei 0:03b5121a232e 13690 }
pcercuei 0:03b5121a232e 13691 completeWild->negNsSet->value = NULL;
pcercuei 0:03b5121a232e 13692 } else if ((!nsFound) && absentFound) {
pcercuei 0:03b5121a232e 13693 /*
pcercuei 0:03b5121a232e 13694 * 5.3 If the set S includes `absent` but not the negated
pcercuei 0:03b5121a232e 13695 * namespace name, then the union is not expressible.
pcercuei 0:03b5121a232e 13696 */
pcercuei 0:03b5121a232e 13697 xmlSchemaPErr(ctxt, completeWild->node,
pcercuei 0:03b5121a232e 13698 XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
pcercuei 0:03b5121a232e 13699 "The union of the wilcard is not expressible.\n",
pcercuei 0:03b5121a232e 13700 NULL, NULL);
pcercuei 0:03b5121a232e 13701 return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
pcercuei 0:03b5121a232e 13702 } else if ((!nsFound) && (!absentFound)) {
pcercuei 0:03b5121a232e 13703 /*
pcercuei 0:03b5121a232e 13704 * 5.4 If the set S does not include either the negated namespace
pcercuei 0:03b5121a232e 13705 * name or `absent`, then whichever of O1 or O2 is a pair of not
pcercuei 0:03b5121a232e 13706 * and a namespace name must be the value.
pcercuei 0:03b5121a232e 13707 */
pcercuei 0:03b5121a232e 13708 if (completeWild->negNsSet == NULL) {
pcercuei 0:03b5121a232e 13709 if (completeWild->nsSet != NULL) {
pcercuei 0:03b5121a232e 13710 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
pcercuei 0:03b5121a232e 13711 completeWild->nsSet = NULL;
pcercuei 0:03b5121a232e 13712 }
pcercuei 0:03b5121a232e 13713 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
pcercuei 0:03b5121a232e 13714 if (completeWild->negNsSet == NULL)
pcercuei 0:03b5121a232e 13715 return (-1);
pcercuei 0:03b5121a232e 13716 completeWild->negNsSet->value = curWild->negNsSet->value;
pcercuei 0:03b5121a232e 13717 }
pcercuei 0:03b5121a232e 13718 }
pcercuei 0:03b5121a232e 13719 return (0);
pcercuei 0:03b5121a232e 13720 }
pcercuei 0:03b5121a232e 13721 /*
pcercuei 0:03b5121a232e 13722 * 6.
pcercuei 0:03b5121a232e 13723 */
pcercuei 0:03b5121a232e 13724 if (((completeWild->negNsSet != NULL) &&
pcercuei 0:03b5121a232e 13725 (completeWild->negNsSet->value == NULL) &&
pcercuei 0:03b5121a232e 13726 (curWild->nsSet != NULL)) ||
pcercuei 0:03b5121a232e 13727 ((curWild->negNsSet != NULL) &&
pcercuei 0:03b5121a232e 13728 (curWild->negNsSet->value == NULL) &&
pcercuei 0:03b5121a232e 13729 (completeWild->nsSet != NULL))) {
pcercuei 0:03b5121a232e 13730
pcercuei 0:03b5121a232e 13731 if (completeWild->nsSet != NULL) {
pcercuei 0:03b5121a232e 13732 cur = completeWild->nsSet;
pcercuei 0:03b5121a232e 13733 } else {
pcercuei 0:03b5121a232e 13734 cur = curWild->nsSet;
pcercuei 0:03b5121a232e 13735 }
pcercuei 0:03b5121a232e 13736 while (cur != NULL) {
pcercuei 0:03b5121a232e 13737 if (cur->value == NULL) {
pcercuei 0:03b5121a232e 13738 /*
pcercuei 0:03b5121a232e 13739 * 6.1 If the set S includes `absent`, then any must be the
pcercuei 0:03b5121a232e 13740 * value.
pcercuei 0:03b5121a232e 13741 */
pcercuei 0:03b5121a232e 13742 completeWild->any = 1;
pcercuei 0:03b5121a232e 13743 if (completeWild->nsSet != NULL) {
pcercuei 0:03b5121a232e 13744 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
pcercuei 0:03b5121a232e 13745 completeWild->nsSet = NULL;
pcercuei 0:03b5121a232e 13746 }
pcercuei 0:03b5121a232e 13747 if (completeWild->negNsSet != NULL) {
pcercuei 0:03b5121a232e 13748 xmlFree(completeWild->negNsSet);
pcercuei 0:03b5121a232e 13749 completeWild->negNsSet = NULL;
pcercuei 0:03b5121a232e 13750 }
pcercuei 0:03b5121a232e 13751 return (0);
pcercuei 0:03b5121a232e 13752 }
pcercuei 0:03b5121a232e 13753 cur = cur->next;
pcercuei 0:03b5121a232e 13754 }
pcercuei 0:03b5121a232e 13755 if (completeWild->negNsSet == NULL) {
pcercuei 0:03b5121a232e 13756 /*
pcercuei 0:03b5121a232e 13757 * 6.2 If the set S does not include `absent`, then a pair of not
pcercuei 0:03b5121a232e 13758 * and `absent` must be the value.
pcercuei 0:03b5121a232e 13759 */
pcercuei 0:03b5121a232e 13760 if (completeWild->nsSet != NULL) {
pcercuei 0:03b5121a232e 13761 xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
pcercuei 0:03b5121a232e 13762 completeWild->nsSet = NULL;
pcercuei 0:03b5121a232e 13763 }
pcercuei 0:03b5121a232e 13764 completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
pcercuei 0:03b5121a232e 13765 if (completeWild->negNsSet == NULL)
pcercuei 0:03b5121a232e 13766 return (-1);
pcercuei 0:03b5121a232e 13767 completeWild->negNsSet->value = NULL;
pcercuei 0:03b5121a232e 13768 }
pcercuei 0:03b5121a232e 13769 return (0);
pcercuei 0:03b5121a232e 13770 }
pcercuei 0:03b5121a232e 13771 return (0);
pcercuei 0:03b5121a232e 13772
pcercuei 0:03b5121a232e 13773 }
pcercuei 0:03b5121a232e 13774
pcercuei 0:03b5121a232e 13775 /**
pcercuei 0:03b5121a232e 13776 * xmlSchemaIntersectWildcards:
pcercuei 0:03b5121a232e 13777 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 13778 * @completeWild: the first wildcard
pcercuei 0:03b5121a232e 13779 * @curWild: the second wildcard
pcercuei 0:03b5121a232e 13780 *
pcercuei 0:03b5121a232e 13781 * Intersects the namespace constraints of the given wildcards.
pcercuei 0:03b5121a232e 13782 * @completeWild will hold the resulting intersection.
pcercuei 0:03b5121a232e 13783 * Returns a positive error code on failure, -1 in case of an
pcercuei 0:03b5121a232e 13784 * internal error, 0 otherwise.
pcercuei 0:03b5121a232e 13785 */
pcercuei 0:03b5121a232e 13786 static int
pcercuei 0:03b5121a232e 13787 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 13788 xmlSchemaWildcardPtr completeWild,
pcercuei 0:03b5121a232e 13789 xmlSchemaWildcardPtr curWild)
pcercuei 0:03b5121a232e 13790 {
pcercuei 0:03b5121a232e 13791 xmlSchemaWildcardNsPtr cur, curB, prev, tmp;
pcercuei 0:03b5121a232e 13792
pcercuei 0:03b5121a232e 13793 /*
pcercuei 0:03b5121a232e 13794 * 1 If O1 and O2 are the same value, then that value must be the
pcercuei 0:03b5121a232e 13795 * value.
pcercuei 0:03b5121a232e 13796 */
pcercuei 0:03b5121a232e 13797 if ((completeWild->any == curWild->any) &&
pcercuei 0:03b5121a232e 13798 ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
pcercuei 0:03b5121a232e 13799 ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
pcercuei 0:03b5121a232e 13800
pcercuei 0:03b5121a232e 13801 if ((completeWild->negNsSet == NULL) ||
pcercuei 0:03b5121a232e 13802 (completeWild->negNsSet->value == curWild->negNsSet->value)) {
pcercuei 0:03b5121a232e 13803
pcercuei 0:03b5121a232e 13804 if (completeWild->nsSet != NULL) {
pcercuei 0:03b5121a232e 13805 int found = 0;
pcercuei 0:03b5121a232e 13806
pcercuei 0:03b5121a232e 13807 /*
pcercuei 0:03b5121a232e 13808 * Check equality of sets.
pcercuei 0:03b5121a232e 13809 */
pcercuei 0:03b5121a232e 13810 cur = completeWild->nsSet;
pcercuei 0:03b5121a232e 13811 while (cur != NULL) {
pcercuei 0:03b5121a232e 13812 found = 0;
pcercuei 0:03b5121a232e 13813 curB = curWild->nsSet;
pcercuei 0:03b5121a232e 13814 while (curB != NULL) {
pcercuei 0:03b5121a232e 13815 if (cur->value == curB->value) {
pcercuei 0:03b5121a232e 13816 found = 1;
pcercuei 0:03b5121a232e 13817 break;
pcercuei 0:03b5121a232e 13818 }
pcercuei 0:03b5121a232e 13819 curB = curB->next;
pcercuei 0:03b5121a232e 13820 }
pcercuei 0:03b5121a232e 13821 if (!found)
pcercuei 0:03b5121a232e 13822 break;
pcercuei 0:03b5121a232e 13823 cur = cur->next;
pcercuei 0:03b5121a232e 13824 }
pcercuei 0:03b5121a232e 13825 if (found)
pcercuei 0:03b5121a232e 13826 return(0);
pcercuei 0:03b5121a232e 13827 } else
pcercuei 0:03b5121a232e 13828 return(0);
pcercuei 0:03b5121a232e 13829 }
pcercuei 0:03b5121a232e 13830 }
pcercuei 0:03b5121a232e 13831 /*
pcercuei 0:03b5121a232e 13832 * 2 If either O1 or O2 is any, then the other must be the value.
pcercuei 0:03b5121a232e 13833 */
pcercuei 0:03b5121a232e 13834 if ((completeWild->any != curWild->any) && (completeWild->any)) {
pcercuei 0:03b5121a232e 13835 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
pcercuei 0:03b5121a232e 13836 return(-1);
pcercuei 0:03b5121a232e 13837 return(0);
pcercuei 0:03b5121a232e 13838 }
pcercuei 0:03b5121a232e 13839 /*
pcercuei 0:03b5121a232e 13840 * 3 If either O1 or O2 is a pair of not and a value (a namespace
pcercuei 0:03b5121a232e 13841 * name or `absent`) and the other is a set of (namespace names or
pcercuei 0:03b5121a232e 13842 * `absent`), then that set, minus the negated value if it was in
pcercuei 0:03b5121a232e 13843 * the set, minus `absent` if it was in the set, must be the value.
pcercuei 0:03b5121a232e 13844 */
pcercuei 0:03b5121a232e 13845 if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
pcercuei 0:03b5121a232e 13846 ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
pcercuei 0:03b5121a232e 13847 const xmlChar *neg;
pcercuei 0:03b5121a232e 13848
pcercuei 0:03b5121a232e 13849 if (completeWild->nsSet == NULL) {
pcercuei 0:03b5121a232e 13850 neg = completeWild->negNsSet->value;
pcercuei 0:03b5121a232e 13851 if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
pcercuei 0:03b5121a232e 13852 return(-1);
pcercuei 0:03b5121a232e 13853 } else
pcercuei 0:03b5121a232e 13854 neg = curWild->negNsSet->value;
pcercuei 0:03b5121a232e 13855 /*
pcercuei 0:03b5121a232e 13856 * Remove absent and negated.
pcercuei 0:03b5121a232e 13857 */
pcercuei 0:03b5121a232e 13858 prev = NULL;
pcercuei 0:03b5121a232e 13859 cur = completeWild->nsSet;
pcercuei 0:03b5121a232e 13860 while (cur != NULL) {
pcercuei 0:03b5121a232e 13861 if (cur->value == NULL) {
pcercuei 0:03b5121a232e 13862 if (prev == NULL)
pcercuei 0:03b5121a232e 13863 completeWild->nsSet = cur->next;
pcercuei 0:03b5121a232e 13864 else
pcercuei 0:03b5121a232e 13865 prev->next = cur->next;
pcercuei 0:03b5121a232e 13866 xmlFree(cur);
pcercuei 0:03b5121a232e 13867 break;
pcercuei 0:03b5121a232e 13868 }
pcercuei 0:03b5121a232e 13869 prev = cur;
pcercuei 0:03b5121a232e 13870 cur = cur->next;
pcercuei 0:03b5121a232e 13871 }
pcercuei 0:03b5121a232e 13872 if (neg != NULL) {
pcercuei 0:03b5121a232e 13873 prev = NULL;
pcercuei 0:03b5121a232e 13874 cur = completeWild->nsSet;
pcercuei 0:03b5121a232e 13875 while (cur != NULL) {
pcercuei 0:03b5121a232e 13876 if (cur->value == neg) {
pcercuei 0:03b5121a232e 13877 if (prev == NULL)
pcercuei 0:03b5121a232e 13878 completeWild->nsSet = cur->next;
pcercuei 0:03b5121a232e 13879 else
pcercuei 0:03b5121a232e 13880 prev->next = cur->next;
pcercuei 0:03b5121a232e 13881 xmlFree(cur);
pcercuei 0:03b5121a232e 13882 break;
pcercuei 0:03b5121a232e 13883 }
pcercuei 0:03b5121a232e 13884 prev = cur;
pcercuei 0:03b5121a232e 13885 cur = cur->next;
pcercuei 0:03b5121a232e 13886 }
pcercuei 0:03b5121a232e 13887 }
pcercuei 0:03b5121a232e 13888
pcercuei 0:03b5121a232e 13889 return(0);
pcercuei 0:03b5121a232e 13890 }
pcercuei 0:03b5121a232e 13891 /*
pcercuei 0:03b5121a232e 13892 * 4 If both O1 and O2 are sets of (namespace names or `absent`),
pcercuei 0:03b5121a232e 13893 * then the intersection of those sets must be the value.
pcercuei 0:03b5121a232e 13894 */
pcercuei 0:03b5121a232e 13895 if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
pcercuei 0:03b5121a232e 13896 int found;
pcercuei 0:03b5121a232e 13897
pcercuei 0:03b5121a232e 13898 cur = completeWild->nsSet;
pcercuei 0:03b5121a232e 13899 prev = NULL;
pcercuei 0:03b5121a232e 13900 while (cur != NULL) {
pcercuei 0:03b5121a232e 13901 found = 0;
pcercuei 0:03b5121a232e 13902 curB = curWild->nsSet;
pcercuei 0:03b5121a232e 13903 while (curB != NULL) {
pcercuei 0:03b5121a232e 13904 if (cur->value == curB->value) {
pcercuei 0:03b5121a232e 13905 found = 1;
pcercuei 0:03b5121a232e 13906 break;
pcercuei 0:03b5121a232e 13907 }
pcercuei 0:03b5121a232e 13908 curB = curB->next;
pcercuei 0:03b5121a232e 13909 }
pcercuei 0:03b5121a232e 13910 if (!found) {
pcercuei 0:03b5121a232e 13911 if (prev == NULL)
pcercuei 0:03b5121a232e 13912 completeWild->nsSet = cur->next;
pcercuei 0:03b5121a232e 13913 else
pcercuei 0:03b5121a232e 13914 prev->next = cur->next;
pcercuei 0:03b5121a232e 13915 tmp = cur->next;
pcercuei 0:03b5121a232e 13916 xmlFree(cur);
pcercuei 0:03b5121a232e 13917 cur = tmp;
pcercuei 0:03b5121a232e 13918 continue;
pcercuei 0:03b5121a232e 13919 }
pcercuei 0:03b5121a232e 13920 prev = cur;
pcercuei 0:03b5121a232e 13921 cur = cur->next;
pcercuei 0:03b5121a232e 13922 }
pcercuei 0:03b5121a232e 13923
pcercuei 0:03b5121a232e 13924 return(0);
pcercuei 0:03b5121a232e 13925 }
pcercuei 0:03b5121a232e 13926 /* 5 If the two are negations of different namespace names,
pcercuei 0:03b5121a232e 13927 * then the intersection is not expressible
pcercuei 0:03b5121a232e 13928 */
pcercuei 0:03b5121a232e 13929 if ((completeWild->negNsSet != NULL) &&
pcercuei 0:03b5121a232e 13930 (curWild->negNsSet != NULL) &&
pcercuei 0:03b5121a232e 13931 (completeWild->negNsSet->value != curWild->negNsSet->value) &&
pcercuei 0:03b5121a232e 13932 (completeWild->negNsSet->value != NULL) &&
pcercuei 0:03b5121a232e 13933 (curWild->negNsSet->value != NULL)) {
pcercuei 0:03b5121a232e 13934
pcercuei 0:03b5121a232e 13935 xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
pcercuei 0:03b5121a232e 13936 "The intersection of the wilcard is not expressible.\n",
pcercuei 0:03b5121a232e 13937 NULL, NULL);
pcercuei 0:03b5121a232e 13938 return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
pcercuei 0:03b5121a232e 13939 }
pcercuei 0:03b5121a232e 13940 /*
pcercuei 0:03b5121a232e 13941 * 6 If the one is a negation of a namespace name and the other
pcercuei 0:03b5121a232e 13942 * is a negation of `absent`, then the one which is the negation
pcercuei 0:03b5121a232e 13943 * of a namespace name must be the value.
pcercuei 0:03b5121a232e 13944 */
pcercuei 0:03b5121a232e 13945 if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
pcercuei 0:03b5121a232e 13946 (completeWild->negNsSet->value != curWild->negNsSet->value) &&
pcercuei 0:03b5121a232e 13947 (completeWild->negNsSet->value == NULL)) {
pcercuei 0:03b5121a232e 13948 completeWild->negNsSet->value = curWild->negNsSet->value;
pcercuei 0:03b5121a232e 13949 }
pcercuei 0:03b5121a232e 13950 return(0);
pcercuei 0:03b5121a232e 13951 }
pcercuei 0:03b5121a232e 13952
pcercuei 0:03b5121a232e 13953 /**
pcercuei 0:03b5121a232e 13954 * xmlSchemaIsWildcardNsConstraintSubset:
pcercuei 0:03b5121a232e 13955 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 13956 * @sub: the first wildcard
pcercuei 0:03b5121a232e 13957 * @super: the second wildcard
pcercuei 0:03b5121a232e 13958 *
pcercuei 0:03b5121a232e 13959 * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
pcercuei 0:03b5121a232e 13960 *
pcercuei 0:03b5121a232e 13961 * Returns 0 if the namespace constraint of @sub is an intensional
pcercuei 0:03b5121a232e 13962 * subset of @super, 1 otherwise.
pcercuei 0:03b5121a232e 13963 */
pcercuei 0:03b5121a232e 13964 static int
pcercuei 0:03b5121a232e 13965 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
pcercuei 0:03b5121a232e 13966 xmlSchemaWildcardPtr super)
pcercuei 0:03b5121a232e 13967 {
pcercuei 0:03b5121a232e 13968 /*
pcercuei 0:03b5121a232e 13969 * 1 super must be any.
pcercuei 0:03b5121a232e 13970 */
pcercuei 0:03b5121a232e 13971 if (super->any)
pcercuei 0:03b5121a232e 13972 return (0);
pcercuei 0:03b5121a232e 13973 /*
pcercuei 0:03b5121a232e 13974 * 2.1 sub must be a pair of not and a namespace name or `absent`.
pcercuei 0:03b5121a232e 13975 * 2.2 super must be a pair of not and the same value.
pcercuei 0:03b5121a232e 13976 */
pcercuei 0:03b5121a232e 13977 if ((sub->negNsSet != NULL) &&
pcercuei 0:03b5121a232e 13978 (super->negNsSet != NULL) &&
pcercuei 0:03b5121a232e 13979 (sub->negNsSet->value == super->negNsSet->value))
pcercuei 0:03b5121a232e 13980 return (0);
pcercuei 0:03b5121a232e 13981 /*
pcercuei 0:03b5121a232e 13982 * 3.1 sub must be a set whose members are either namespace names or `absent`.
pcercuei 0:03b5121a232e 13983 */
pcercuei 0:03b5121a232e 13984 if (sub->nsSet != NULL) {
pcercuei 0:03b5121a232e 13985 /*
pcercuei 0:03b5121a232e 13986 * 3.2.1 super must be the same set or a superset thereof.
pcercuei 0:03b5121a232e 13987 */
pcercuei 0:03b5121a232e 13988 if (super->nsSet != NULL) {
pcercuei 0:03b5121a232e 13989 xmlSchemaWildcardNsPtr cur, curB;
pcercuei 0:03b5121a232e 13990 int found = 0;
pcercuei 0:03b5121a232e 13991
pcercuei 0:03b5121a232e 13992 cur = sub->nsSet;
pcercuei 0:03b5121a232e 13993 while (cur != NULL) {
pcercuei 0:03b5121a232e 13994 found = 0;
pcercuei 0:03b5121a232e 13995 curB = super->nsSet;
pcercuei 0:03b5121a232e 13996 while (curB != NULL) {
pcercuei 0:03b5121a232e 13997 if (cur->value == curB->value) {
pcercuei 0:03b5121a232e 13998 found = 1;
pcercuei 0:03b5121a232e 13999 break;
pcercuei 0:03b5121a232e 14000 }
pcercuei 0:03b5121a232e 14001 curB = curB->next;
pcercuei 0:03b5121a232e 14002 }
pcercuei 0:03b5121a232e 14003 if (!found)
pcercuei 0:03b5121a232e 14004 return (1);
pcercuei 0:03b5121a232e 14005 cur = cur->next;
pcercuei 0:03b5121a232e 14006 }
pcercuei 0:03b5121a232e 14007 if (found)
pcercuei 0:03b5121a232e 14008 return (0);
pcercuei 0:03b5121a232e 14009 } else if (super->negNsSet != NULL) {
pcercuei 0:03b5121a232e 14010 xmlSchemaWildcardNsPtr cur;
pcercuei 0:03b5121a232e 14011 /*
pcercuei 0:03b5121a232e 14012 * 3.2.2 super must be a pair of not and a namespace name or
pcercuei 0:03b5121a232e 14013 * `absent` and that value must not be in sub's set.
pcercuei 0:03b5121a232e 14014 */
pcercuei 0:03b5121a232e 14015 cur = sub->nsSet;
pcercuei 0:03b5121a232e 14016 while (cur != NULL) {
pcercuei 0:03b5121a232e 14017 if (cur->value == super->negNsSet->value)
pcercuei 0:03b5121a232e 14018 return (1);
pcercuei 0:03b5121a232e 14019 cur = cur->next;
pcercuei 0:03b5121a232e 14020 }
pcercuei 0:03b5121a232e 14021 return (0);
pcercuei 0:03b5121a232e 14022 }
pcercuei 0:03b5121a232e 14023 }
pcercuei 0:03b5121a232e 14024 return (1);
pcercuei 0:03b5121a232e 14025 }
pcercuei 0:03b5121a232e 14026
pcercuei 0:03b5121a232e 14027 static int
pcercuei 0:03b5121a232e 14028 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
pcercuei 0:03b5121a232e 14029 int *fixed,
pcercuei 0:03b5121a232e 14030 const xmlChar **value,
pcercuei 0:03b5121a232e 14031 xmlSchemaValPtr *val)
pcercuei 0:03b5121a232e 14032 {
pcercuei 0:03b5121a232e 14033 *fixed = 0;
pcercuei 0:03b5121a232e 14034 *value = NULL;
pcercuei 0:03b5121a232e 14035 if (val != 0)
pcercuei 0:03b5121a232e 14036 *val = NULL;
pcercuei 0:03b5121a232e 14037
pcercuei 0:03b5121a232e 14038 if (attruse->defValue != NULL) {
pcercuei 0:03b5121a232e 14039 *value = attruse->defValue;
pcercuei 0:03b5121a232e 14040 if (val != NULL)
pcercuei 0:03b5121a232e 14041 *val = attruse->defVal;
pcercuei 0:03b5121a232e 14042 if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
pcercuei 0:03b5121a232e 14043 *fixed = 1;
pcercuei 0:03b5121a232e 14044 return(1);
pcercuei 0:03b5121a232e 14045 } else if ((attruse->attrDecl != NULL) &&
pcercuei 0:03b5121a232e 14046 (attruse->attrDecl->defValue != NULL)) {
pcercuei 0:03b5121a232e 14047 *value = attruse->attrDecl->defValue;
pcercuei 0:03b5121a232e 14048 if (val != NULL)
pcercuei 0:03b5121a232e 14049 *val = attruse->attrDecl->defVal;
pcercuei 0:03b5121a232e 14050 if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
pcercuei 0:03b5121a232e 14051 *fixed = 1;
pcercuei 0:03b5121a232e 14052 return(1);
pcercuei 0:03b5121a232e 14053 }
pcercuei 0:03b5121a232e 14054 return(0);
pcercuei 0:03b5121a232e 14055 }
pcercuei 0:03b5121a232e 14056 /**
pcercuei 0:03b5121a232e 14057 * xmlSchemaCheckCVCWildcardNamespace:
pcercuei 0:03b5121a232e 14058 * @wild: the wildcard
pcercuei 0:03b5121a232e 14059 * @ns: the namespace
pcercuei 0:03b5121a232e 14060 *
pcercuei 0:03b5121a232e 14061 * Validation Rule: Wildcard allows Namespace Name
pcercuei 0:03b5121a232e 14062 * (cvc-wildcard-namespace)
pcercuei 0:03b5121a232e 14063 *
pcercuei 0:03b5121a232e 14064 * Returns 0 if the given namespace matches the wildcard,
pcercuei 0:03b5121a232e 14065 * 1 otherwise and -1 on API errors.
pcercuei 0:03b5121a232e 14066 */
pcercuei 0:03b5121a232e 14067 static int
pcercuei 0:03b5121a232e 14068 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
pcercuei 0:03b5121a232e 14069 const xmlChar* ns)
pcercuei 0:03b5121a232e 14070 {
pcercuei 0:03b5121a232e 14071 if (wild == NULL)
pcercuei 0:03b5121a232e 14072 return(-1);
pcercuei 0:03b5121a232e 14073
pcercuei 0:03b5121a232e 14074 if (wild->any)
pcercuei 0:03b5121a232e 14075 return(0);
pcercuei 0:03b5121a232e 14076 else if (wild->nsSet != NULL) {
pcercuei 0:03b5121a232e 14077 xmlSchemaWildcardNsPtr cur;
pcercuei 0:03b5121a232e 14078
pcercuei 0:03b5121a232e 14079 cur = wild->nsSet;
pcercuei 0:03b5121a232e 14080 while (cur != NULL) {
pcercuei 0:03b5121a232e 14081 if (xmlStrEqual(cur->value, ns))
pcercuei 0:03b5121a232e 14082 return(0);
pcercuei 0:03b5121a232e 14083 cur = cur->next;
pcercuei 0:03b5121a232e 14084 }
pcercuei 0:03b5121a232e 14085 } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
pcercuei 0:03b5121a232e 14086 (!xmlStrEqual(wild->negNsSet->value, ns)))
pcercuei 0:03b5121a232e 14087 return(0);
pcercuei 0:03b5121a232e 14088
pcercuei 0:03b5121a232e 14089 return(1);
pcercuei 0:03b5121a232e 14090 }
pcercuei 0:03b5121a232e 14091
pcercuei 0:03b5121a232e 14092 #define XML_SCHEMA_ACTION_DERIVE 0
pcercuei 0:03b5121a232e 14093 #define XML_SCHEMA_ACTION_REDEFINE 1
pcercuei 0:03b5121a232e 14094
pcercuei 0:03b5121a232e 14095 #define WXS_ACTION_STR(a) \
pcercuei 0:03b5121a232e 14096 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
pcercuei 0:03b5121a232e 14097
pcercuei 0:03b5121a232e 14098 /*
pcercuei 0:03b5121a232e 14099 * Schema Component Constraint:
pcercuei 0:03b5121a232e 14100 * Derivation Valid (Restriction, Complex)
pcercuei 0:03b5121a232e 14101 * derivation-ok-restriction (2) - (4)
pcercuei 0:03b5121a232e 14102 *
pcercuei 0:03b5121a232e 14103 * ATTENTION:
pcercuei 0:03b5121a232e 14104 * In XML Schema 1.1 this will be:
pcercuei 0:03b5121a232e 14105 * Validation Rule:
pcercuei 0:03b5121a232e 14106 * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
pcercuei 0:03b5121a232e 14107 *
pcercuei 0:03b5121a232e 14108 */
pcercuei 0:03b5121a232e 14109 static int
pcercuei 0:03b5121a232e 14110 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 14111 int action,
pcercuei 0:03b5121a232e 14112 xmlSchemaBasicItemPtr item,
pcercuei 0:03b5121a232e 14113 xmlSchemaBasicItemPtr baseItem,
pcercuei 0:03b5121a232e 14114 xmlSchemaItemListPtr uses,
pcercuei 0:03b5121a232e 14115 xmlSchemaItemListPtr baseUses,
pcercuei 0:03b5121a232e 14116 xmlSchemaWildcardPtr wild,
pcercuei 0:03b5121a232e 14117 xmlSchemaWildcardPtr baseWild)
pcercuei 0:03b5121a232e 14118 {
pcercuei 0:03b5121a232e 14119 xmlSchemaAttributeUsePtr cur = NULL, bcur;
pcercuei 0:03b5121a232e 14120 int i, j, found; /* err = 0; */
pcercuei 0:03b5121a232e 14121 const xmlChar *bEffValue;
pcercuei 0:03b5121a232e 14122 int effFixed;
pcercuei 0:03b5121a232e 14123
pcercuei 0:03b5121a232e 14124 if (uses != NULL) {
pcercuei 0:03b5121a232e 14125 for (i = 0; i < uses->nbItems; i++) {
pcercuei 0:03b5121a232e 14126 cur = uses->items[i];
pcercuei 0:03b5121a232e 14127 found = 0;
pcercuei 0:03b5121a232e 14128 if (baseUses == NULL)
pcercuei 0:03b5121a232e 14129 goto not_found;
pcercuei 0:03b5121a232e 14130 for (j = 0; j < baseUses->nbItems; j++) {
pcercuei 0:03b5121a232e 14131 bcur = baseUses->items[j];
pcercuei 0:03b5121a232e 14132 if ((WXS_ATTRUSE_DECL_NAME(cur) ==
pcercuei 0:03b5121a232e 14133 WXS_ATTRUSE_DECL_NAME(bcur)) &&
pcercuei 0:03b5121a232e 14134 (WXS_ATTRUSE_DECL_TNS(cur) ==
pcercuei 0:03b5121a232e 14135 WXS_ATTRUSE_DECL_TNS(bcur)))
pcercuei 0:03b5121a232e 14136 {
pcercuei 0:03b5121a232e 14137 /*
pcercuei 0:03b5121a232e 14138 * (2.1) "If there is an attribute use in the {attribute
pcercuei 0:03b5121a232e 14139 * uses} of the {base type definition} (call this B) whose
pcercuei 0:03b5121a232e 14140 * {attribute declaration} has the same {name} and {target
pcercuei 0:03b5121a232e 14141 * namespace}, then all of the following must be true:"
pcercuei 0:03b5121a232e 14142 */
pcercuei 0:03b5121a232e 14143 found = 1;
pcercuei 0:03b5121a232e 14144
pcercuei 0:03b5121a232e 14145 if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
pcercuei 0:03b5121a232e 14146 (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
pcercuei 0:03b5121a232e 14147 {
pcercuei 0:03b5121a232e 14148 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 14149 /*
pcercuei 0:03b5121a232e 14150 * (2.1.1) "one of the following must be true:"
pcercuei 0:03b5121a232e 14151 * (2.1.1.1) "B's {required} is false."
pcercuei 0:03b5121a232e 14152 * (2.1.1.2) "R's {required} is true."
pcercuei 0:03b5121a232e 14153 */
pcercuei 0:03b5121a232e 14154 xmlSchemaPAttrUseErr4(pctxt,
pcercuei 0:03b5121a232e 14155 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
pcercuei 0:03b5121a232e 14156 WXS_ITEM_NODE(item), item, cur,
pcercuei 0:03b5121a232e 14157 "The 'optional' attribute use is inconsistent "
pcercuei 0:03b5121a232e 14158 "with the corresponding 'required' attribute use of "
pcercuei 0:03b5121a232e 14159 "the %s %s",
pcercuei 0:03b5121a232e 14160 WXS_ACTION_STR(action),
pcercuei 0:03b5121a232e 14161 xmlSchemaGetComponentDesignation(&str, baseItem),
pcercuei 0:03b5121a232e 14162 NULL, NULL);
pcercuei 0:03b5121a232e 14163 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 14164 /* err = pctxt->err; */
pcercuei 0:03b5121a232e 14165 } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 14166 WXS_ATTRUSE_TYPEDEF(cur),
pcercuei 0:03b5121a232e 14167 WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
pcercuei 0:03b5121a232e 14168 {
pcercuei 0:03b5121a232e 14169 xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
pcercuei 0:03b5121a232e 14170
pcercuei 0:03b5121a232e 14171 /*
pcercuei 0:03b5121a232e 14172 * SPEC (2.1.2) "R's {attribute declaration}'s
pcercuei 0:03b5121a232e 14173 * {type definition} must be validly derived from
pcercuei 0:03b5121a232e 14174 * B's {type definition} given the empty set as
pcercuei 0:03b5121a232e 14175 * defined in Type Derivation OK (Simple) ($3.14.6)."
pcercuei 0:03b5121a232e 14176 */
pcercuei 0:03b5121a232e 14177 xmlSchemaPAttrUseErr4(pctxt,
pcercuei 0:03b5121a232e 14178 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
pcercuei 0:03b5121a232e 14179 WXS_ITEM_NODE(item), item, cur,
pcercuei 0:03b5121a232e 14180 "The attribute declaration's %s "
pcercuei 0:03b5121a232e 14181 "is not validly derived from "
pcercuei 0:03b5121a232e 14182 "the corresponding %s of the "
pcercuei 0:03b5121a232e 14183 "attribute declaration in the %s %s",
pcercuei 0:03b5121a232e 14184 xmlSchemaGetComponentDesignation(&strA,
pcercuei 0:03b5121a232e 14185 WXS_ATTRUSE_TYPEDEF(cur)),
pcercuei 0:03b5121a232e 14186 xmlSchemaGetComponentDesignation(&strB,
pcercuei 0:03b5121a232e 14187 WXS_ATTRUSE_TYPEDEF(bcur)),
pcercuei 0:03b5121a232e 14188 WXS_ACTION_STR(action),
pcercuei 0:03b5121a232e 14189 xmlSchemaGetComponentDesignation(&strC, baseItem));
pcercuei 0:03b5121a232e 14190 /* xmlSchemaGetComponentDesignation(&str, baseItem), */
pcercuei 0:03b5121a232e 14191 FREE_AND_NULL(strA);
pcercuei 0:03b5121a232e 14192 FREE_AND_NULL(strB);
pcercuei 0:03b5121a232e 14193 FREE_AND_NULL(strC);
pcercuei 0:03b5121a232e 14194 /* err = pctxt->err; */
pcercuei 0:03b5121a232e 14195 } else {
pcercuei 0:03b5121a232e 14196 /*
pcercuei 0:03b5121a232e 14197 * 2.1.3 [Definition:] Let the effective value
pcercuei 0:03b5121a232e 14198 * constraint of an attribute use be its {value
pcercuei 0:03b5121a232e 14199 * constraint}, if present, otherwise its {attribute
pcercuei 0:03b5121a232e 14200 * declaration}'s {value constraint} .
pcercuei 0:03b5121a232e 14201 */
pcercuei 0:03b5121a232e 14202 xmlSchemaGetEffectiveValueConstraint(bcur,
pcercuei 0:03b5121a232e 14203 &effFixed, &bEffValue, NULL);
pcercuei 0:03b5121a232e 14204 /*
pcercuei 0:03b5121a232e 14205 * 2.1.3 ... one of the following must be true
pcercuei 0:03b5121a232e 14206 *
pcercuei 0:03b5121a232e 14207 * 2.1.3.1 B's `effective value constraint` is
pcercuei 0:03b5121a232e 14208 * `absent` or default.
pcercuei 0:03b5121a232e 14209 */
pcercuei 0:03b5121a232e 14210 if ((bEffValue != NULL) &&
pcercuei 0:03b5121a232e 14211 (effFixed == 1)) {
pcercuei 0:03b5121a232e 14212 const xmlChar *rEffValue = NULL;
pcercuei 0:03b5121a232e 14213
pcercuei 0:03b5121a232e 14214 xmlSchemaGetEffectiveValueConstraint(bcur,
pcercuei 0:03b5121a232e 14215 &effFixed, &rEffValue, NULL);
pcercuei 0:03b5121a232e 14216 /*
pcercuei 0:03b5121a232e 14217 * 2.1.3.2 R's `effective value constraint` is
pcercuei 0:03b5121a232e 14218 * fixed with the same string as B's.
pcercuei 0:03b5121a232e 14219 * MAYBE TODO: Compare the computed values.
pcercuei 0:03b5121a232e 14220 * Hmm, it says "same string" so
pcercuei 0:03b5121a232e 14221 * string-equality might really be sufficient.
pcercuei 0:03b5121a232e 14222 */
pcercuei 0:03b5121a232e 14223 if ((effFixed == 0) ||
pcercuei 0:03b5121a232e 14224 (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
pcercuei 0:03b5121a232e 14225 {
pcercuei 0:03b5121a232e 14226 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 14227
pcercuei 0:03b5121a232e 14228 xmlSchemaPAttrUseErr4(pctxt,
pcercuei 0:03b5121a232e 14229 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
pcercuei 0:03b5121a232e 14230 WXS_ITEM_NODE(item), item, cur,
pcercuei 0:03b5121a232e 14231 "The effective value constraint of the "
pcercuei 0:03b5121a232e 14232 "attribute use is inconsistent with "
pcercuei 0:03b5121a232e 14233 "its correspondent in the %s %s",
pcercuei 0:03b5121a232e 14234 WXS_ACTION_STR(action),
pcercuei 0:03b5121a232e 14235 xmlSchemaGetComponentDesignation(&str,
pcercuei 0:03b5121a232e 14236 baseItem),
pcercuei 0:03b5121a232e 14237 NULL, NULL);
pcercuei 0:03b5121a232e 14238 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 14239 /* err = pctxt->err; */
pcercuei 0:03b5121a232e 14240 }
pcercuei 0:03b5121a232e 14241 }
pcercuei 0:03b5121a232e 14242 }
pcercuei 0:03b5121a232e 14243 break;
pcercuei 0:03b5121a232e 14244 }
pcercuei 0:03b5121a232e 14245 }
pcercuei 0:03b5121a232e 14246 not_found:
pcercuei 0:03b5121a232e 14247 if (!found) {
pcercuei 0:03b5121a232e 14248 /*
pcercuei 0:03b5121a232e 14249 * (2.2) "otherwise the {base type definition} must have an
pcercuei 0:03b5121a232e 14250 * {attribute wildcard} and the {target namespace} of the
pcercuei 0:03b5121a232e 14251 * R's {attribute declaration} must be `valid` with respect
pcercuei 0:03b5121a232e 14252 * to that wildcard, as defined in Wildcard allows Namespace
pcercuei 0:03b5121a232e 14253 * Name ($3.10.4)."
pcercuei 0:03b5121a232e 14254 */
pcercuei 0:03b5121a232e 14255 if ((baseWild == NULL) ||
pcercuei 0:03b5121a232e 14256 (xmlSchemaCheckCVCWildcardNamespace(baseWild,
pcercuei 0:03b5121a232e 14257 (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
pcercuei 0:03b5121a232e 14258 {
pcercuei 0:03b5121a232e 14259 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 14260
pcercuei 0:03b5121a232e 14261 xmlSchemaPAttrUseErr4(pctxt,
pcercuei 0:03b5121a232e 14262 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
pcercuei 0:03b5121a232e 14263 WXS_ITEM_NODE(item), item, cur,
pcercuei 0:03b5121a232e 14264 "Neither a matching attribute use, "
pcercuei 0:03b5121a232e 14265 "nor a matching wildcard exists in the %s %s",
pcercuei 0:03b5121a232e 14266 WXS_ACTION_STR(action),
pcercuei 0:03b5121a232e 14267 xmlSchemaGetComponentDesignation(&str, baseItem),
pcercuei 0:03b5121a232e 14268 NULL, NULL);
pcercuei 0:03b5121a232e 14269 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 14270 /* err = pctxt->err; */
pcercuei 0:03b5121a232e 14271 }
pcercuei 0:03b5121a232e 14272 }
pcercuei 0:03b5121a232e 14273 }
pcercuei 0:03b5121a232e 14274 }
pcercuei 0:03b5121a232e 14275 /*
pcercuei 0:03b5121a232e 14276 * SPEC derivation-ok-restriction (3):
pcercuei 0:03b5121a232e 14277 * (3) "For each attribute use in the {attribute uses} of the {base type
pcercuei 0:03b5121a232e 14278 * definition} whose {required} is true, there must be an attribute
pcercuei 0:03b5121a232e 14279 * use with an {attribute declaration} with the same {name} and
pcercuei 0:03b5121a232e 14280 * {target namespace} as its {attribute declaration} in the {attribute
pcercuei 0:03b5121a232e 14281 * uses} of the complex type definition itself whose {required} is true.
pcercuei 0:03b5121a232e 14282 */
pcercuei 0:03b5121a232e 14283 if (baseUses != NULL) {
pcercuei 0:03b5121a232e 14284 for (j = 0; j < baseUses->nbItems; j++) {
pcercuei 0:03b5121a232e 14285 bcur = baseUses->items[j];
pcercuei 0:03b5121a232e 14286 if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
pcercuei 0:03b5121a232e 14287 continue;
pcercuei 0:03b5121a232e 14288 found = 0;
pcercuei 0:03b5121a232e 14289 if (uses != NULL) {
pcercuei 0:03b5121a232e 14290 for (i = 0; i < uses->nbItems; i++) {
pcercuei 0:03b5121a232e 14291 cur = uses->items[i];
pcercuei 0:03b5121a232e 14292 if ((WXS_ATTRUSE_DECL_NAME(cur) ==
pcercuei 0:03b5121a232e 14293 WXS_ATTRUSE_DECL_NAME(bcur)) &&
pcercuei 0:03b5121a232e 14294 (WXS_ATTRUSE_DECL_TNS(cur) ==
pcercuei 0:03b5121a232e 14295 WXS_ATTRUSE_DECL_TNS(bcur))) {
pcercuei 0:03b5121a232e 14296 found = 1;
pcercuei 0:03b5121a232e 14297 break;
pcercuei 0:03b5121a232e 14298 }
pcercuei 0:03b5121a232e 14299 }
pcercuei 0:03b5121a232e 14300 }
pcercuei 0:03b5121a232e 14301 if (!found) {
pcercuei 0:03b5121a232e 14302 xmlChar *strA = NULL, *strB = NULL;
pcercuei 0:03b5121a232e 14303
pcercuei 0:03b5121a232e 14304 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 14305 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
pcercuei 0:03b5121a232e 14306 NULL, item,
pcercuei 0:03b5121a232e 14307 "A matching attribute use for the "
pcercuei 0:03b5121a232e 14308 "'required' %s of the %s %s is missing",
pcercuei 0:03b5121a232e 14309 xmlSchemaGetComponentDesignation(&strA, bcur),
pcercuei 0:03b5121a232e 14310 WXS_ACTION_STR(action),
pcercuei 0:03b5121a232e 14311 xmlSchemaGetComponentDesignation(&strB, baseItem),
pcercuei 0:03b5121a232e 14312 NULL);
pcercuei 0:03b5121a232e 14313 FREE_AND_NULL(strA);
pcercuei 0:03b5121a232e 14314 FREE_AND_NULL(strB);
pcercuei 0:03b5121a232e 14315 }
pcercuei 0:03b5121a232e 14316 }
pcercuei 0:03b5121a232e 14317 }
pcercuei 0:03b5121a232e 14318 /*
pcercuei 0:03b5121a232e 14319 * derivation-ok-restriction (4)
pcercuei 0:03b5121a232e 14320 */
pcercuei 0:03b5121a232e 14321 if (wild != NULL) {
pcercuei 0:03b5121a232e 14322 /*
pcercuei 0:03b5121a232e 14323 * (4) "If there is an {attribute wildcard}, all of the
pcercuei 0:03b5121a232e 14324 * following must be true:"
pcercuei 0:03b5121a232e 14325 */
pcercuei 0:03b5121a232e 14326 if (baseWild == NULL) {
pcercuei 0:03b5121a232e 14327 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 14328
pcercuei 0:03b5121a232e 14329 /*
pcercuei 0:03b5121a232e 14330 * (4.1) "The {base type definition} must also have one."
pcercuei 0:03b5121a232e 14331 */
pcercuei 0:03b5121a232e 14332 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 14333 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
pcercuei 0:03b5121a232e 14334 NULL, item,
pcercuei 0:03b5121a232e 14335 "The %s has an attribute wildcard, "
pcercuei 0:03b5121a232e 14336 "but the %s %s '%s' does not have one",
pcercuei 0:03b5121a232e 14337 WXS_ITEM_TYPE_NAME(item),
pcercuei 0:03b5121a232e 14338 WXS_ACTION_STR(action),
pcercuei 0:03b5121a232e 14339 WXS_ITEM_TYPE_NAME(baseItem),
pcercuei 0:03b5121a232e 14340 xmlSchemaGetComponentQName(&str, baseItem));
pcercuei 0:03b5121a232e 14341 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 14342 return(pctxt->err);
pcercuei 0:03b5121a232e 14343 } else if ((baseWild->any == 0) &&
pcercuei 0:03b5121a232e 14344 xmlSchemaCheckCOSNSSubset(wild, baseWild))
pcercuei 0:03b5121a232e 14345 {
pcercuei 0:03b5121a232e 14346 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 14347 /*
pcercuei 0:03b5121a232e 14348 * (4.2) "The complex type definition's {attribute wildcard}'s
pcercuei 0:03b5121a232e 14349 * {namespace constraint} must be a subset of the {base type
pcercuei 0:03b5121a232e 14350 * definition}'s {attribute wildcard}'s {namespace constraint},
pcercuei 0:03b5121a232e 14351 * as defined by Wildcard Subset ($3.10.6)."
pcercuei 0:03b5121a232e 14352 */
pcercuei 0:03b5121a232e 14353 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 14354 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
pcercuei 0:03b5121a232e 14355 NULL, item,
pcercuei 0:03b5121a232e 14356 "The attribute wildcard is not a valid "
pcercuei 0:03b5121a232e 14357 "subset of the wildcard in the %s %s '%s'",
pcercuei 0:03b5121a232e 14358 WXS_ACTION_STR(action),
pcercuei 0:03b5121a232e 14359 WXS_ITEM_TYPE_NAME(baseItem),
pcercuei 0:03b5121a232e 14360 xmlSchemaGetComponentQName(&str, baseItem),
pcercuei 0:03b5121a232e 14361 NULL);
pcercuei 0:03b5121a232e 14362 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 14363 return(pctxt->err);
pcercuei 0:03b5121a232e 14364 }
pcercuei 0:03b5121a232e 14365 /* 4.3 Unless the {base type definition} is the `ur-type
pcercuei 0:03b5121a232e 14366 * definition`, the complex type definition's {attribute
pcercuei 0:03b5121a232e 14367 * wildcard}'s {process contents} must be identical to or
pcercuei 0:03b5121a232e 14368 * stronger than the {base type definition}'s {attribute
pcercuei 0:03b5121a232e 14369 * wildcard}'s {process contents}, where strict is stronger
pcercuei 0:03b5121a232e 14370 * than lax is stronger than skip.
pcercuei 0:03b5121a232e 14371 */
pcercuei 0:03b5121a232e 14372 if ((! WXS_IS_ANYTYPE(baseItem)) &&
pcercuei 0:03b5121a232e 14373 (wild->processContents < baseWild->processContents)) {
pcercuei 0:03b5121a232e 14374 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 14375 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 14376 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
pcercuei 0:03b5121a232e 14377 NULL, baseItem,
pcercuei 0:03b5121a232e 14378 "The {process contents} of the attribute wildcard is "
pcercuei 0:03b5121a232e 14379 "weaker than the one in the %s %s '%s'",
pcercuei 0:03b5121a232e 14380 WXS_ACTION_STR(action),
pcercuei 0:03b5121a232e 14381 WXS_ITEM_TYPE_NAME(baseItem),
pcercuei 0:03b5121a232e 14382 xmlSchemaGetComponentQName(&str, baseItem),
pcercuei 0:03b5121a232e 14383 NULL);
pcercuei 0:03b5121a232e 14384 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 14385 return(pctxt->err);
pcercuei 0:03b5121a232e 14386 }
pcercuei 0:03b5121a232e 14387 }
pcercuei 0:03b5121a232e 14388 return(0);
pcercuei 0:03b5121a232e 14389 }
pcercuei 0:03b5121a232e 14390
pcercuei 0:03b5121a232e 14391
pcercuei 0:03b5121a232e 14392 static int
pcercuei 0:03b5121a232e 14393 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 14394 xmlSchemaBasicItemPtr item,
pcercuei 0:03b5121a232e 14395 xmlSchemaWildcardPtr *completeWild,
pcercuei 0:03b5121a232e 14396 xmlSchemaItemListPtr list,
pcercuei 0:03b5121a232e 14397 xmlSchemaItemListPtr prohibs);
pcercuei 0:03b5121a232e 14398 /**
pcercuei 0:03b5121a232e 14399 * xmlSchemaFixupTypeAttributeUses:
pcercuei 0:03b5121a232e 14400 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 14401 * @type: the complex type definition
pcercuei 0:03b5121a232e 14402 *
pcercuei 0:03b5121a232e 14403 *
pcercuei 0:03b5121a232e 14404 * Builds the wildcard and the attribute uses on the given complex type.
pcercuei 0:03b5121a232e 14405 * Returns -1 if an internal error occurs, 0 otherwise.
pcercuei 0:03b5121a232e 14406 *
pcercuei 0:03b5121a232e 14407 * ATTENTION TODO: Experimantally this uses pointer comparisons for
pcercuei 0:03b5121a232e 14408 * strings, so recheck this if we start to hardcode some schemata, since
pcercuei 0:03b5121a232e 14409 * they might not be in the same dict.
pcercuei 0:03b5121a232e 14410 * NOTE: It is allowed to "extend" the xs:anyType type.
pcercuei 0:03b5121a232e 14411 */
pcercuei 0:03b5121a232e 14412 static int
pcercuei 0:03b5121a232e 14413 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 14414 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 14415 {
pcercuei 0:03b5121a232e 14416 xmlSchemaTypePtr baseType = NULL;
pcercuei 0:03b5121a232e 14417 xmlSchemaAttributeUsePtr use;
pcercuei 0:03b5121a232e 14418 xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
pcercuei 0:03b5121a232e 14419
pcercuei 0:03b5121a232e 14420 if (type->baseType == NULL) {
pcercuei 0:03b5121a232e 14421 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
pcercuei 0:03b5121a232e 14422 "no base type");
pcercuei 0:03b5121a232e 14423 return (-1);
pcercuei 0:03b5121a232e 14424 }
pcercuei 0:03b5121a232e 14425 baseType = type->baseType;
pcercuei 0:03b5121a232e 14426 if (WXS_IS_TYPE_NOT_FIXED(baseType))
pcercuei 0:03b5121a232e 14427 if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
pcercuei 0:03b5121a232e 14428 return(-1);
pcercuei 0:03b5121a232e 14429
pcercuei 0:03b5121a232e 14430 uses = type->attrUses;
pcercuei 0:03b5121a232e 14431 baseUses = baseType->attrUses;
pcercuei 0:03b5121a232e 14432 /*
pcercuei 0:03b5121a232e 14433 * Expand attribute group references. And build the 'complete'
pcercuei 0:03b5121a232e 14434 * wildcard, i.e. intersect multiple wildcards.
pcercuei 0:03b5121a232e 14435 * Move attribute prohibitions into a separate list.
pcercuei 0:03b5121a232e 14436 */
pcercuei 0:03b5121a232e 14437 if (uses != NULL) {
pcercuei 0:03b5121a232e 14438 if (WXS_IS_RESTRICTION(type)) {
pcercuei 0:03b5121a232e 14439 /*
pcercuei 0:03b5121a232e 14440 * This one will transfer all attr. prohibitions
pcercuei 0:03b5121a232e 14441 * into pctxt->attrProhibs.
pcercuei 0:03b5121a232e 14442 */
pcercuei 0:03b5121a232e 14443 if (xmlSchemaExpandAttributeGroupRefs(pctxt,
pcercuei 0:03b5121a232e 14444 WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
pcercuei 0:03b5121a232e 14445 pctxt->attrProhibs) == -1)
pcercuei 0:03b5121a232e 14446 {
pcercuei 0:03b5121a232e 14447 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
pcercuei 0:03b5121a232e 14448 "failed to expand attributes");
pcercuei 0:03b5121a232e 14449 }
pcercuei 0:03b5121a232e 14450 if (pctxt->attrProhibs->nbItems != 0)
pcercuei 0:03b5121a232e 14451 prohibs = pctxt->attrProhibs;
pcercuei 0:03b5121a232e 14452 } else {
pcercuei 0:03b5121a232e 14453 if (xmlSchemaExpandAttributeGroupRefs(pctxt,
pcercuei 0:03b5121a232e 14454 WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
pcercuei 0:03b5121a232e 14455 NULL) == -1)
pcercuei 0:03b5121a232e 14456 {
pcercuei 0:03b5121a232e 14457 PERROR_INT("xmlSchemaFixupTypeAttributeUses",
pcercuei 0:03b5121a232e 14458 "failed to expand attributes");
pcercuei 0:03b5121a232e 14459 }
pcercuei 0:03b5121a232e 14460 }
pcercuei 0:03b5121a232e 14461 }
pcercuei 0:03b5121a232e 14462 /*
pcercuei 0:03b5121a232e 14463 * Inherit the attribute uses of the base type.
pcercuei 0:03b5121a232e 14464 */
pcercuei 0:03b5121a232e 14465 if (baseUses != NULL) {
pcercuei 0:03b5121a232e 14466 int i, j;
pcercuei 0:03b5121a232e 14467 xmlSchemaAttributeUseProhibPtr pro;
pcercuei 0:03b5121a232e 14468
pcercuei 0:03b5121a232e 14469 if (WXS_IS_RESTRICTION(type)) {
pcercuei 0:03b5121a232e 14470 int usesCount;
pcercuei 0:03b5121a232e 14471 xmlSchemaAttributeUsePtr tmp;
pcercuei 0:03b5121a232e 14472
pcercuei 0:03b5121a232e 14473 if (uses != NULL)
pcercuei 0:03b5121a232e 14474 usesCount = uses->nbItems;
pcercuei 0:03b5121a232e 14475 else
pcercuei 0:03b5121a232e 14476 usesCount = 0;
pcercuei 0:03b5121a232e 14477
pcercuei 0:03b5121a232e 14478 /* Restriction. */
pcercuei 0:03b5121a232e 14479 for (i = 0; i < baseUses->nbItems; i++) {
pcercuei 0:03b5121a232e 14480 use = baseUses->items[i];
pcercuei 0:03b5121a232e 14481 if (prohibs) {
pcercuei 0:03b5121a232e 14482 /*
pcercuei 0:03b5121a232e 14483 * Filter out prohibited uses.
pcercuei 0:03b5121a232e 14484 */
pcercuei 0:03b5121a232e 14485 for (j = 0; j < prohibs->nbItems; j++) {
pcercuei 0:03b5121a232e 14486 pro = prohibs->items[j];
pcercuei 0:03b5121a232e 14487 if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
pcercuei 0:03b5121a232e 14488 (WXS_ATTRUSE_DECL_TNS(use) ==
pcercuei 0:03b5121a232e 14489 pro->targetNamespace))
pcercuei 0:03b5121a232e 14490 {
pcercuei 0:03b5121a232e 14491 goto inherit_next;
pcercuei 0:03b5121a232e 14492 }
pcercuei 0:03b5121a232e 14493 }
pcercuei 0:03b5121a232e 14494 }
pcercuei 0:03b5121a232e 14495 if (usesCount) {
pcercuei 0:03b5121a232e 14496 /*
pcercuei 0:03b5121a232e 14497 * Filter out existing uses.
pcercuei 0:03b5121a232e 14498 */
pcercuei 0:03b5121a232e 14499 for (j = 0; j < usesCount; j++) {
pcercuei 0:03b5121a232e 14500 tmp = uses->items[j];
pcercuei 0:03b5121a232e 14501 if ((WXS_ATTRUSE_DECL_NAME(use) ==
pcercuei 0:03b5121a232e 14502 WXS_ATTRUSE_DECL_NAME(tmp)) &&
pcercuei 0:03b5121a232e 14503 (WXS_ATTRUSE_DECL_TNS(use) ==
pcercuei 0:03b5121a232e 14504 WXS_ATTRUSE_DECL_TNS(tmp)))
pcercuei 0:03b5121a232e 14505 {
pcercuei 0:03b5121a232e 14506 goto inherit_next;
pcercuei 0:03b5121a232e 14507 }
pcercuei 0:03b5121a232e 14508 }
pcercuei 0:03b5121a232e 14509 }
pcercuei 0:03b5121a232e 14510 if (uses == NULL) {
pcercuei 0:03b5121a232e 14511 type->attrUses = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 14512 if (type->attrUses == NULL)
pcercuei 0:03b5121a232e 14513 goto exit_failure;
pcercuei 0:03b5121a232e 14514 uses = type->attrUses;
pcercuei 0:03b5121a232e 14515 }
pcercuei 0:03b5121a232e 14516 xmlSchemaItemListAddSize(uses, 2, use);
pcercuei 0:03b5121a232e 14517 inherit_next: {}
pcercuei 0:03b5121a232e 14518 }
pcercuei 0:03b5121a232e 14519 } else {
pcercuei 0:03b5121a232e 14520 /* Extension. */
pcercuei 0:03b5121a232e 14521 for (i = 0; i < baseUses->nbItems; i++) {
pcercuei 0:03b5121a232e 14522 use = baseUses->items[i];
pcercuei 0:03b5121a232e 14523 if (uses == NULL) {
pcercuei 0:03b5121a232e 14524 type->attrUses = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 14525 if (type->attrUses == NULL)
pcercuei 0:03b5121a232e 14526 goto exit_failure;
pcercuei 0:03b5121a232e 14527 uses = type->attrUses;
pcercuei 0:03b5121a232e 14528 }
pcercuei 0:03b5121a232e 14529 xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
pcercuei 0:03b5121a232e 14530 }
pcercuei 0:03b5121a232e 14531 }
pcercuei 0:03b5121a232e 14532 }
pcercuei 0:03b5121a232e 14533 /*
pcercuei 0:03b5121a232e 14534 * Shrink attr. uses.
pcercuei 0:03b5121a232e 14535 */
pcercuei 0:03b5121a232e 14536 if (uses) {
pcercuei 0:03b5121a232e 14537 if (uses->nbItems == 0) {
pcercuei 0:03b5121a232e 14538 xmlSchemaItemListFree(uses);
pcercuei 0:03b5121a232e 14539 type->attrUses = NULL;
pcercuei 0:03b5121a232e 14540 }
pcercuei 0:03b5121a232e 14541 /*
pcercuei 0:03b5121a232e 14542 * TODO: We could shrink the size of the array
pcercuei 0:03b5121a232e 14543 * to fit the actual number of items.
pcercuei 0:03b5121a232e 14544 */
pcercuei 0:03b5121a232e 14545 }
pcercuei 0:03b5121a232e 14546 /*
pcercuei 0:03b5121a232e 14547 * Compute the complete wildcard.
pcercuei 0:03b5121a232e 14548 */
pcercuei 0:03b5121a232e 14549 if (WXS_IS_EXTENSION(type)) {
pcercuei 0:03b5121a232e 14550 if (baseType->attributeWildcard != NULL) {
pcercuei 0:03b5121a232e 14551 /*
pcercuei 0:03b5121a232e 14552 * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
pcercuei 0:03b5121a232e 14553 * the appropriate case among the following:"
pcercuei 0:03b5121a232e 14554 */
pcercuei 0:03b5121a232e 14555 if (type->attributeWildcard != NULL) {
pcercuei 0:03b5121a232e 14556 /*
pcercuei 0:03b5121a232e 14557 * Union the complete wildcard with the base wildcard.
pcercuei 0:03b5121a232e 14558 * SPEC {attribute wildcard}
pcercuei 0:03b5121a232e 14559 * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
pcercuei 0:03b5121a232e 14560 * and {annotation} are those of the `complete wildcard`,
pcercuei 0:03b5121a232e 14561 * and whose {namespace constraint} is the intensional union
pcercuei 0:03b5121a232e 14562 * of the {namespace constraint} of the `complete wildcard`
pcercuei 0:03b5121a232e 14563 * and of the `base wildcard`, as defined in Attribute
pcercuei 0:03b5121a232e 14564 * Wildcard Union ($3.10.6)."
pcercuei 0:03b5121a232e 14565 */
pcercuei 0:03b5121a232e 14566 if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
pcercuei 0:03b5121a232e 14567 baseType->attributeWildcard) == -1)
pcercuei 0:03b5121a232e 14568 goto exit_failure;
pcercuei 0:03b5121a232e 14569 } else {
pcercuei 0:03b5121a232e 14570 /*
pcercuei 0:03b5121a232e 14571 * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
pcercuei 0:03b5121a232e 14572 * then the `base wildcard`."
pcercuei 0:03b5121a232e 14573 */
pcercuei 0:03b5121a232e 14574 type->attributeWildcard = baseType->attributeWildcard;
pcercuei 0:03b5121a232e 14575 }
pcercuei 0:03b5121a232e 14576 } else {
pcercuei 0:03b5121a232e 14577 /*
pcercuei 0:03b5121a232e 14578 * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
pcercuei 0:03b5121a232e 14579 * `complete wildcard`"
pcercuei 0:03b5121a232e 14580 * NOOP
pcercuei 0:03b5121a232e 14581 */
pcercuei 0:03b5121a232e 14582 }
pcercuei 0:03b5121a232e 14583 } else {
pcercuei 0:03b5121a232e 14584 /*
pcercuei 0:03b5121a232e 14585 * SPEC {attribute wildcard}
pcercuei 0:03b5121a232e 14586 * (3.1) "If the <restriction> alternative is chosen, then the
pcercuei 0:03b5121a232e 14587 * `complete wildcard`;"
pcercuei 0:03b5121a232e 14588 * NOOP
pcercuei 0:03b5121a232e 14589 */
pcercuei 0:03b5121a232e 14590 }
pcercuei 0:03b5121a232e 14591
pcercuei 0:03b5121a232e 14592 return (0);
pcercuei 0:03b5121a232e 14593
pcercuei 0:03b5121a232e 14594 exit_failure:
pcercuei 0:03b5121a232e 14595 return(-1);
pcercuei 0:03b5121a232e 14596 }
pcercuei 0:03b5121a232e 14597
pcercuei 0:03b5121a232e 14598 /**
pcercuei 0:03b5121a232e 14599 * xmlSchemaTypeFinalContains:
pcercuei 0:03b5121a232e 14600 * @schema: the schema
pcercuei 0:03b5121a232e 14601 * @type: the type definition
pcercuei 0:03b5121a232e 14602 * @final: the final
pcercuei 0:03b5121a232e 14603 *
pcercuei 0:03b5121a232e 14604 * Evaluates if a type definition contains the given "final".
pcercuei 0:03b5121a232e 14605 * This does take "finalDefault" into account as well.
pcercuei 0:03b5121a232e 14606 *
pcercuei 0:03b5121a232e 14607 * Returns 1 if the type does containt the given "final",
pcercuei 0:03b5121a232e 14608 * 0 otherwise.
pcercuei 0:03b5121a232e 14609 */
pcercuei 0:03b5121a232e 14610 static int
pcercuei 0:03b5121a232e 14611 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
pcercuei 0:03b5121a232e 14612 {
pcercuei 0:03b5121a232e 14613 if (type == NULL)
pcercuei 0:03b5121a232e 14614 return (0);
pcercuei 0:03b5121a232e 14615 if (type->flags & final)
pcercuei 0:03b5121a232e 14616 return (1);
pcercuei 0:03b5121a232e 14617 else
pcercuei 0:03b5121a232e 14618 return (0);
pcercuei 0:03b5121a232e 14619 }
pcercuei 0:03b5121a232e 14620
pcercuei 0:03b5121a232e 14621 /**
pcercuei 0:03b5121a232e 14622 * xmlSchemaGetUnionSimpleTypeMemberTypes:
pcercuei 0:03b5121a232e 14623 * @type: the Union Simple Type
pcercuei 0:03b5121a232e 14624 *
pcercuei 0:03b5121a232e 14625 * Returns a list of member types of @type if existing,
pcercuei 0:03b5121a232e 14626 * returns NULL otherwise.
pcercuei 0:03b5121a232e 14627 */
pcercuei 0:03b5121a232e 14628 static xmlSchemaTypeLinkPtr
pcercuei 0:03b5121a232e 14629 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 14630 {
pcercuei 0:03b5121a232e 14631 while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
pcercuei 0:03b5121a232e 14632 if (type->memberTypes != NULL)
pcercuei 0:03b5121a232e 14633 return (type->memberTypes);
pcercuei 0:03b5121a232e 14634 else
pcercuei 0:03b5121a232e 14635 type = type->baseType;
pcercuei 0:03b5121a232e 14636 }
pcercuei 0:03b5121a232e 14637 return (NULL);
pcercuei 0:03b5121a232e 14638 }
pcercuei 0:03b5121a232e 14639
pcercuei 0:03b5121a232e 14640 /**
pcercuei 0:03b5121a232e 14641 * xmlSchemaGetParticleTotalRangeMin:
pcercuei 0:03b5121a232e 14642 * @particle: the particle
pcercuei 0:03b5121a232e 14643 *
pcercuei 0:03b5121a232e 14644 * Schema Component Constraint: Effective Total Range
pcercuei 0:03b5121a232e 14645 * (all and sequence) + (choice)
pcercuei 0:03b5121a232e 14646 *
pcercuei 0:03b5121a232e 14647 * Returns the minimun Effective Total Range.
pcercuei 0:03b5121a232e 14648 */
pcercuei 0:03b5121a232e 14649 static int
pcercuei 0:03b5121a232e 14650 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
pcercuei 0:03b5121a232e 14651 {
pcercuei 0:03b5121a232e 14652 if ((particle->children == NULL) ||
pcercuei 0:03b5121a232e 14653 (particle->minOccurs == 0))
pcercuei 0:03b5121a232e 14654 return (0);
pcercuei 0:03b5121a232e 14655 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
pcercuei 0:03b5121a232e 14656 int min = -1, cur;
pcercuei 0:03b5121a232e 14657 xmlSchemaParticlePtr part =
pcercuei 0:03b5121a232e 14658 (xmlSchemaParticlePtr) particle->children->children;
pcercuei 0:03b5121a232e 14659
pcercuei 0:03b5121a232e 14660 if (part == NULL)
pcercuei 0:03b5121a232e 14661 return (0);
pcercuei 0:03b5121a232e 14662 while (part != NULL) {
pcercuei 0:03b5121a232e 14663 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
pcercuei 0:03b5121a232e 14664 (part->children->type == XML_SCHEMA_TYPE_ANY))
pcercuei 0:03b5121a232e 14665 cur = part->minOccurs;
pcercuei 0:03b5121a232e 14666 else
pcercuei 0:03b5121a232e 14667 cur = xmlSchemaGetParticleTotalRangeMin(part);
pcercuei 0:03b5121a232e 14668 if (cur == 0)
pcercuei 0:03b5121a232e 14669 return (0);
pcercuei 0:03b5121a232e 14670 if ((min > cur) || (min == -1))
pcercuei 0:03b5121a232e 14671 min = cur;
pcercuei 0:03b5121a232e 14672 part = (xmlSchemaParticlePtr) part->next;
pcercuei 0:03b5121a232e 14673 }
pcercuei 0:03b5121a232e 14674 return (particle->minOccurs * min);
pcercuei 0:03b5121a232e 14675 } else {
pcercuei 0:03b5121a232e 14676 /* <all> and <sequence> */
pcercuei 0:03b5121a232e 14677 int sum = 0;
pcercuei 0:03b5121a232e 14678 xmlSchemaParticlePtr part =
pcercuei 0:03b5121a232e 14679 (xmlSchemaParticlePtr) particle->children->children;
pcercuei 0:03b5121a232e 14680
pcercuei 0:03b5121a232e 14681 if (part == NULL)
pcercuei 0:03b5121a232e 14682 return (0);
pcercuei 0:03b5121a232e 14683 do {
pcercuei 0:03b5121a232e 14684 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
pcercuei 0:03b5121a232e 14685 (part->children->type == XML_SCHEMA_TYPE_ANY))
pcercuei 0:03b5121a232e 14686 sum += part->minOccurs;
pcercuei 0:03b5121a232e 14687 else
pcercuei 0:03b5121a232e 14688 sum += xmlSchemaGetParticleTotalRangeMin(part);
pcercuei 0:03b5121a232e 14689 part = (xmlSchemaParticlePtr) part->next;
pcercuei 0:03b5121a232e 14690 } while (part != NULL);
pcercuei 0:03b5121a232e 14691 return (particle->minOccurs * sum);
pcercuei 0:03b5121a232e 14692 }
pcercuei 0:03b5121a232e 14693 }
pcercuei 0:03b5121a232e 14694
pcercuei 0:03b5121a232e 14695 #if 0
pcercuei 0:03b5121a232e 14696 /**
pcercuei 0:03b5121a232e 14697 * xmlSchemaGetParticleTotalRangeMax:
pcercuei 0:03b5121a232e 14698 * @particle: the particle
pcercuei 0:03b5121a232e 14699 *
pcercuei 0:03b5121a232e 14700 * Schema Component Constraint: Effective Total Range
pcercuei 0:03b5121a232e 14701 * (all and sequence) + (choice)
pcercuei 0:03b5121a232e 14702 *
pcercuei 0:03b5121a232e 14703 * Returns the maximum Effective Total Range.
pcercuei 0:03b5121a232e 14704 */
pcercuei 0:03b5121a232e 14705 static int
pcercuei 0:03b5121a232e 14706 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
pcercuei 0:03b5121a232e 14707 {
pcercuei 0:03b5121a232e 14708 if ((particle->children == NULL) ||
pcercuei 0:03b5121a232e 14709 (particle->children->children == NULL))
pcercuei 0:03b5121a232e 14710 return (0);
pcercuei 0:03b5121a232e 14711 if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
pcercuei 0:03b5121a232e 14712 int max = -1, cur;
pcercuei 0:03b5121a232e 14713 xmlSchemaParticlePtr part =
pcercuei 0:03b5121a232e 14714 (xmlSchemaParticlePtr) particle->children->children;
pcercuei 0:03b5121a232e 14715
pcercuei 0:03b5121a232e 14716 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
pcercuei 0:03b5121a232e 14717 if (part->children == NULL)
pcercuei 0:03b5121a232e 14718 continue;
pcercuei 0:03b5121a232e 14719 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
pcercuei 0:03b5121a232e 14720 (part->children->type == XML_SCHEMA_TYPE_ANY))
pcercuei 0:03b5121a232e 14721 cur = part->maxOccurs;
pcercuei 0:03b5121a232e 14722 else
pcercuei 0:03b5121a232e 14723 cur = xmlSchemaGetParticleTotalRangeMax(part);
pcercuei 0:03b5121a232e 14724 if (cur == UNBOUNDED)
pcercuei 0:03b5121a232e 14725 return (UNBOUNDED);
pcercuei 0:03b5121a232e 14726 if ((max < cur) || (max == -1))
pcercuei 0:03b5121a232e 14727 max = cur;
pcercuei 0:03b5121a232e 14728 }
pcercuei 0:03b5121a232e 14729 /* TODO: Handle overflows? */
pcercuei 0:03b5121a232e 14730 return (particle->maxOccurs * max);
pcercuei 0:03b5121a232e 14731 } else {
pcercuei 0:03b5121a232e 14732 /* <all> and <sequence> */
pcercuei 0:03b5121a232e 14733 int sum = 0, cur;
pcercuei 0:03b5121a232e 14734 xmlSchemaParticlePtr part =
pcercuei 0:03b5121a232e 14735 (xmlSchemaParticlePtr) particle->children->children;
pcercuei 0:03b5121a232e 14736
pcercuei 0:03b5121a232e 14737 for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
pcercuei 0:03b5121a232e 14738 if (part->children == NULL)
pcercuei 0:03b5121a232e 14739 continue;
pcercuei 0:03b5121a232e 14740 if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
pcercuei 0:03b5121a232e 14741 (part->children->type == XML_SCHEMA_TYPE_ANY))
pcercuei 0:03b5121a232e 14742 cur = part->maxOccurs;
pcercuei 0:03b5121a232e 14743 else
pcercuei 0:03b5121a232e 14744 cur = xmlSchemaGetParticleTotalRangeMax(part);
pcercuei 0:03b5121a232e 14745 if (cur == UNBOUNDED)
pcercuei 0:03b5121a232e 14746 return (UNBOUNDED);
pcercuei 0:03b5121a232e 14747 if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
pcercuei 0:03b5121a232e 14748 return (UNBOUNDED);
pcercuei 0:03b5121a232e 14749 sum += cur;
pcercuei 0:03b5121a232e 14750 }
pcercuei 0:03b5121a232e 14751 /* TODO: Handle overflows? */
pcercuei 0:03b5121a232e 14752 return (particle->maxOccurs * sum);
pcercuei 0:03b5121a232e 14753 }
pcercuei 0:03b5121a232e 14754 }
pcercuei 0:03b5121a232e 14755 #endif
pcercuei 0:03b5121a232e 14756
pcercuei 0:03b5121a232e 14757 /**
pcercuei 0:03b5121a232e 14758 * xmlSchemaIsParticleEmptiable:
pcercuei 0:03b5121a232e 14759 * @particle: the particle
pcercuei 0:03b5121a232e 14760 *
pcercuei 0:03b5121a232e 14761 * Schema Component Constraint: Particle Emptiable
pcercuei 0:03b5121a232e 14762 * Checks whether the given particle is emptiable.
pcercuei 0:03b5121a232e 14763 *
pcercuei 0:03b5121a232e 14764 * Returns 1 if emptiable, 0 otherwise.
pcercuei 0:03b5121a232e 14765 */
pcercuei 0:03b5121a232e 14766 static int
pcercuei 0:03b5121a232e 14767 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
pcercuei 0:03b5121a232e 14768 {
pcercuei 0:03b5121a232e 14769 /*
pcercuei 0:03b5121a232e 14770 * SPEC (1) "Its {min occurs} is 0."
pcercuei 0:03b5121a232e 14771 */
pcercuei 0:03b5121a232e 14772 if ((particle == NULL) || (particle->minOccurs == 0) ||
pcercuei 0:03b5121a232e 14773 (particle->children == NULL))
pcercuei 0:03b5121a232e 14774 return (1);
pcercuei 0:03b5121a232e 14775 /*
pcercuei 0:03b5121a232e 14776 * SPEC (2) "Its {term} is a group and the minimum part of the
pcercuei 0:03b5121a232e 14777 * effective total range of that group, [...] is 0."
pcercuei 0:03b5121a232e 14778 */
pcercuei 0:03b5121a232e 14779 if (WXS_IS_MODEL_GROUP(particle->children)) {
pcercuei 0:03b5121a232e 14780 if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
pcercuei 0:03b5121a232e 14781 return (1);
pcercuei 0:03b5121a232e 14782 }
pcercuei 0:03b5121a232e 14783 return (0);
pcercuei 0:03b5121a232e 14784 }
pcercuei 0:03b5121a232e 14785
pcercuei 0:03b5121a232e 14786 /**
pcercuei 0:03b5121a232e 14787 * xmlSchemaCheckCOSSTDerivedOK:
pcercuei 0:03b5121a232e 14788 * @actxt: a context
pcercuei 0:03b5121a232e 14789 * @type: the derived simple type definition
pcercuei 0:03b5121a232e 14790 * @baseType: the base type definition
pcercuei 0:03b5121a232e 14791 * @subset: the subset of ('restriction', ect.)
pcercuei 0:03b5121a232e 14792 *
pcercuei 0:03b5121a232e 14793 * Schema Component Constraint:
pcercuei 0:03b5121a232e 14794 * Type Derivation OK (Simple) (cos-st-derived-OK)
pcercuei 0:03b5121a232e 14795 *
pcercuei 0:03b5121a232e 14796 * Checks wheter @type can be validly
pcercuei 0:03b5121a232e 14797 * derived from @baseType.
pcercuei 0:03b5121a232e 14798 *
pcercuei 0:03b5121a232e 14799 * Returns 0 on success, an positive error code otherwise.
pcercuei 0:03b5121a232e 14800 */
pcercuei 0:03b5121a232e 14801 static int
pcercuei 0:03b5121a232e 14802 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 14803 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 14804 xmlSchemaTypePtr baseType,
pcercuei 0:03b5121a232e 14805 int subset)
pcercuei 0:03b5121a232e 14806 {
pcercuei 0:03b5121a232e 14807 /*
pcercuei 0:03b5121a232e 14808 * 1 They are the same type definition.
pcercuei 0:03b5121a232e 14809 * TODO: The identy check might have to be more complex than this.
pcercuei 0:03b5121a232e 14810 */
pcercuei 0:03b5121a232e 14811 if (type == baseType)
pcercuei 0:03b5121a232e 14812 return (0);
pcercuei 0:03b5121a232e 14813 /*
pcercuei 0:03b5121a232e 14814 * 2.1 restriction is not in the subset, or in the {final}
pcercuei 0:03b5121a232e 14815 * of its own {base type definition};
pcercuei 0:03b5121a232e 14816 *
pcercuei 0:03b5121a232e 14817 * NOTE that this will be used also via "xsi:type".
pcercuei 0:03b5121a232e 14818 *
pcercuei 0:03b5121a232e 14819 * TODO: Revise this, it looks strange. How can the "type"
pcercuei 0:03b5121a232e 14820 * not be fixed or *in* fixing?
pcercuei 0:03b5121a232e 14821 */
pcercuei 0:03b5121a232e 14822 if (WXS_IS_TYPE_NOT_FIXED(type))
pcercuei 0:03b5121a232e 14823 if (xmlSchemaTypeFixup(type, actxt) == -1)
pcercuei 0:03b5121a232e 14824 return(-1);
pcercuei 0:03b5121a232e 14825 if (WXS_IS_TYPE_NOT_FIXED(baseType))
pcercuei 0:03b5121a232e 14826 if (xmlSchemaTypeFixup(baseType, actxt) == -1)
pcercuei 0:03b5121a232e 14827 return(-1);
pcercuei 0:03b5121a232e 14828 if ((subset & SUBSET_RESTRICTION) ||
pcercuei 0:03b5121a232e 14829 (xmlSchemaTypeFinalContains(type->baseType,
pcercuei 0:03b5121a232e 14830 XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
pcercuei 0:03b5121a232e 14831 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
pcercuei 0:03b5121a232e 14832 }
pcercuei 0:03b5121a232e 14833 /* 2.2 */
pcercuei 0:03b5121a232e 14834 if (type->baseType == baseType) {
pcercuei 0:03b5121a232e 14835 /*
pcercuei 0:03b5121a232e 14836 * 2.2.1 D's `base type definition` is B.
pcercuei 0:03b5121a232e 14837 */
pcercuei 0:03b5121a232e 14838 return (0);
pcercuei 0:03b5121a232e 14839 }
pcercuei 0:03b5121a232e 14840 /*
pcercuei 0:03b5121a232e 14841 * 2.2.2 D's `base type definition` is not the `ur-type definition`
pcercuei 0:03b5121a232e 14842 * and is validly derived from B given the subset, as defined by this
pcercuei 0:03b5121a232e 14843 * constraint.
pcercuei 0:03b5121a232e 14844 */
pcercuei 0:03b5121a232e 14845 if ((! WXS_IS_ANYTYPE(type->baseType)) &&
pcercuei 0:03b5121a232e 14846 (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
pcercuei 0:03b5121a232e 14847 baseType, subset) == 0)) {
pcercuei 0:03b5121a232e 14848 return (0);
pcercuei 0:03b5121a232e 14849 }
pcercuei 0:03b5121a232e 14850 /*
pcercuei 0:03b5121a232e 14851 * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
pcercuei 0:03b5121a232e 14852 * definition`.
pcercuei 0:03b5121a232e 14853 */
pcercuei 0:03b5121a232e 14854 if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
pcercuei 0:03b5121a232e 14855 (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
pcercuei 0:03b5121a232e 14856 return (0);
pcercuei 0:03b5121a232e 14857 }
pcercuei 0:03b5121a232e 14858 /*
pcercuei 0:03b5121a232e 14859 * 2.2.4 B's {variety} is union and D is validly derived from a type
pcercuei 0:03b5121a232e 14860 * definition in B's {member type definitions} given the subset, as
pcercuei 0:03b5121a232e 14861 * defined by this constraint.
pcercuei 0:03b5121a232e 14862 *
pcercuei 0:03b5121a232e 14863 * NOTE: This seems not to involve built-in types, since there is no
pcercuei 0:03b5121a232e 14864 * built-in Union Simple Type.
pcercuei 0:03b5121a232e 14865 */
pcercuei 0:03b5121a232e 14866 if (WXS_IS_UNION(baseType)) {
pcercuei 0:03b5121a232e 14867 xmlSchemaTypeLinkPtr cur;
pcercuei 0:03b5121a232e 14868
pcercuei 0:03b5121a232e 14869 cur = baseType->memberTypes;
pcercuei 0:03b5121a232e 14870 while (cur != NULL) {
pcercuei 0:03b5121a232e 14871 if (WXS_IS_TYPE_NOT_FIXED(cur->type))
pcercuei 0:03b5121a232e 14872 if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
pcercuei 0:03b5121a232e 14873 return(-1);
pcercuei 0:03b5121a232e 14874 if (xmlSchemaCheckCOSSTDerivedOK(actxt,
pcercuei 0:03b5121a232e 14875 type, cur->type, subset) == 0)
pcercuei 0:03b5121a232e 14876 {
pcercuei 0:03b5121a232e 14877 /*
pcercuei 0:03b5121a232e 14878 * It just has to be validly derived from at least one
pcercuei 0:03b5121a232e 14879 * member-type.
pcercuei 0:03b5121a232e 14880 */
pcercuei 0:03b5121a232e 14881 return (0);
pcercuei 0:03b5121a232e 14882 }
pcercuei 0:03b5121a232e 14883 cur = cur->next;
pcercuei 0:03b5121a232e 14884 }
pcercuei 0:03b5121a232e 14885 }
pcercuei 0:03b5121a232e 14886 return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
pcercuei 0:03b5121a232e 14887 }
pcercuei 0:03b5121a232e 14888
pcercuei 0:03b5121a232e 14889 /**
pcercuei 0:03b5121a232e 14890 * xmlSchemaCheckTypeDefCircularInternal:
pcercuei 0:03b5121a232e 14891 * @pctxt: the schema parser context
pcercuei 0:03b5121a232e 14892 * @ctxtType: the type definition
pcercuei 0:03b5121a232e 14893 * @ancestor: an ancestor of @ctxtType
pcercuei 0:03b5121a232e 14894 *
pcercuei 0:03b5121a232e 14895 * Checks st-props-correct (2) + ct-props-correct (3).
pcercuei 0:03b5121a232e 14896 * Circular type definitions are not allowed.
pcercuei 0:03b5121a232e 14897 *
pcercuei 0:03b5121a232e 14898 * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
pcercuei 0:03b5121a232e 14899 * circular, 0 otherwise.
pcercuei 0:03b5121a232e 14900 */
pcercuei 0:03b5121a232e 14901 static int
pcercuei 0:03b5121a232e 14902 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 14903 xmlSchemaTypePtr ctxtType,
pcercuei 0:03b5121a232e 14904 xmlSchemaTypePtr ancestor)
pcercuei 0:03b5121a232e 14905 {
pcercuei 0:03b5121a232e 14906 int ret;
pcercuei 0:03b5121a232e 14907
pcercuei 0:03b5121a232e 14908 if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
pcercuei 0:03b5121a232e 14909 return (0);
pcercuei 0:03b5121a232e 14910
pcercuei 0:03b5121a232e 14911 if (ctxtType == ancestor) {
pcercuei 0:03b5121a232e 14912 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 14913 XML_SCHEMAP_ST_PROPS_CORRECT_2,
pcercuei 0:03b5121a232e 14914 WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
pcercuei 0:03b5121a232e 14915 "The definition is circular", NULL);
pcercuei 0:03b5121a232e 14916 return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
pcercuei 0:03b5121a232e 14917 }
pcercuei 0:03b5121a232e 14918 if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
pcercuei 0:03b5121a232e 14919 /*
pcercuei 0:03b5121a232e 14920 * Avoid inifinite recursion on circular types not yet checked.
pcercuei 0:03b5121a232e 14921 */
pcercuei 0:03b5121a232e 14922 return (0);
pcercuei 0:03b5121a232e 14923 }
pcercuei 0:03b5121a232e 14924 ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
pcercuei 0:03b5121a232e 14925 ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
pcercuei 0:03b5121a232e 14926 ancestor->baseType);
pcercuei 0:03b5121a232e 14927 ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
pcercuei 0:03b5121a232e 14928 return (ret);
pcercuei 0:03b5121a232e 14929 }
pcercuei 0:03b5121a232e 14930
pcercuei 0:03b5121a232e 14931 /**
pcercuei 0:03b5121a232e 14932 * xmlSchemaCheckTypeDefCircular:
pcercuei 0:03b5121a232e 14933 * @item: the complex/simple type definition
pcercuei 0:03b5121a232e 14934 * @ctxt: the parser context
pcercuei 0:03b5121a232e 14935 * @name: the name
pcercuei 0:03b5121a232e 14936 *
pcercuei 0:03b5121a232e 14937 * Checks for circular type definitions.
pcercuei 0:03b5121a232e 14938 */
pcercuei 0:03b5121a232e 14939 static void
pcercuei 0:03b5121a232e 14940 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
pcercuei 0:03b5121a232e 14941 xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 14942 {
pcercuei 0:03b5121a232e 14943 if ((item == NULL) ||
pcercuei 0:03b5121a232e 14944 (item->type == XML_SCHEMA_TYPE_BASIC) ||
pcercuei 0:03b5121a232e 14945 (item->baseType == NULL))
pcercuei 0:03b5121a232e 14946 return;
pcercuei 0:03b5121a232e 14947 xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
pcercuei 0:03b5121a232e 14948 item->baseType);
pcercuei 0:03b5121a232e 14949 }
pcercuei 0:03b5121a232e 14950
pcercuei 0:03b5121a232e 14951 /*
pcercuei 0:03b5121a232e 14952 * Simple Type Definition Representation OK (src-simple-type) 4
pcercuei 0:03b5121a232e 14953 *
pcercuei 0:03b5121a232e 14954 * "4 Circular union type definition is disallowed. That is, if the
pcercuei 0:03b5121a232e 14955 * <union> alternative is chosen, there must not be any entries in the
pcercuei 0:03b5121a232e 14956 * memberTypes [attribute] at any depth which resolve to the component
pcercuei 0:03b5121a232e 14957 * corresponding to the <simpleType>."
pcercuei 0:03b5121a232e 14958 *
pcercuei 0:03b5121a232e 14959 * Note that this should work on the *representation* of a component,
pcercuei 0:03b5121a232e 14960 * thus assumes any union types in the member types not being yet
pcercuei 0:03b5121a232e 14961 * substituted. At this stage we need the variety of the types
pcercuei 0:03b5121a232e 14962 * to be already computed.
pcercuei 0:03b5121a232e 14963 */
pcercuei 0:03b5121a232e 14964 static int
pcercuei 0:03b5121a232e 14965 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 14966 xmlSchemaTypePtr ctxType,
pcercuei 0:03b5121a232e 14967 xmlSchemaTypeLinkPtr members)
pcercuei 0:03b5121a232e 14968 {
pcercuei 0:03b5121a232e 14969 xmlSchemaTypeLinkPtr member;
pcercuei 0:03b5121a232e 14970 xmlSchemaTypePtr memberType;
pcercuei 0:03b5121a232e 14971
pcercuei 0:03b5121a232e 14972 member = members;
pcercuei 0:03b5121a232e 14973 while (member != NULL) {
pcercuei 0:03b5121a232e 14974 memberType = member->type;
pcercuei 0:03b5121a232e 14975 while ((memberType != NULL) &&
pcercuei 0:03b5121a232e 14976 (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
pcercuei 0:03b5121a232e 14977 if (memberType == ctxType) {
pcercuei 0:03b5121a232e 14978 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 14979 XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
pcercuei 0:03b5121a232e 14980 WXS_BASIC_CAST ctxType, NULL,
pcercuei 0:03b5121a232e 14981 "The union type definition is circular", NULL);
pcercuei 0:03b5121a232e 14982 return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
pcercuei 0:03b5121a232e 14983 }
pcercuei 0:03b5121a232e 14984 if ((WXS_IS_UNION(memberType)) &&
pcercuei 0:03b5121a232e 14985 ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
pcercuei 0:03b5121a232e 14986 {
pcercuei 0:03b5121a232e 14987 int res;
pcercuei 0:03b5121a232e 14988 memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
pcercuei 0:03b5121a232e 14989 res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
pcercuei 0:03b5121a232e 14990 ctxType,
pcercuei 0:03b5121a232e 14991 xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
pcercuei 0:03b5121a232e 14992 memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
pcercuei 0:03b5121a232e 14993 if (res != 0)
pcercuei 0:03b5121a232e 14994 return(res);
pcercuei 0:03b5121a232e 14995 }
pcercuei 0:03b5121a232e 14996 memberType = memberType->baseType;
pcercuei 0:03b5121a232e 14997 }
pcercuei 0:03b5121a232e 14998 member = member->next;
pcercuei 0:03b5121a232e 14999 }
pcercuei 0:03b5121a232e 15000 return(0);
pcercuei 0:03b5121a232e 15001 }
pcercuei 0:03b5121a232e 15002
pcercuei 0:03b5121a232e 15003 static int
pcercuei 0:03b5121a232e 15004 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 15005 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 15006 {
pcercuei 0:03b5121a232e 15007 if (! WXS_IS_UNION(type))
pcercuei 0:03b5121a232e 15008 return(0);
pcercuei 0:03b5121a232e 15009 return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
pcercuei 0:03b5121a232e 15010 type->memberTypes));
pcercuei 0:03b5121a232e 15011 }
pcercuei 0:03b5121a232e 15012
pcercuei 0:03b5121a232e 15013 /**
pcercuei 0:03b5121a232e 15014 * xmlSchemaResolveTypeReferences:
pcercuei 0:03b5121a232e 15015 * @item: the complex/simple type definition
pcercuei 0:03b5121a232e 15016 * @ctxt: the parser context
pcercuei 0:03b5121a232e 15017 * @name: the name
pcercuei 0:03b5121a232e 15018 *
pcercuei 0:03b5121a232e 15019 * Resolvese type definition references
pcercuei 0:03b5121a232e 15020 */
pcercuei 0:03b5121a232e 15021 static void
pcercuei 0:03b5121a232e 15022 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
pcercuei 0:03b5121a232e 15023 xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 15024 {
pcercuei 0:03b5121a232e 15025 if (typeDef == NULL)
pcercuei 0:03b5121a232e 15026 return;
pcercuei 0:03b5121a232e 15027
pcercuei 0:03b5121a232e 15028 /*
pcercuei 0:03b5121a232e 15029 * Resolve the base type.
pcercuei 0:03b5121a232e 15030 */
pcercuei 0:03b5121a232e 15031 if (typeDef->baseType == NULL) {
pcercuei 0:03b5121a232e 15032 typeDef->baseType = xmlSchemaGetType(ctxt->schema,
pcercuei 0:03b5121a232e 15033 typeDef->base, typeDef->baseNs);
pcercuei 0:03b5121a232e 15034 if (typeDef->baseType == NULL) {
pcercuei 0:03b5121a232e 15035 xmlSchemaPResCompAttrErr(ctxt,
pcercuei 0:03b5121a232e 15036 XML_SCHEMAP_SRC_RESOLVE,
pcercuei 0:03b5121a232e 15037 WXS_BASIC_CAST typeDef, typeDef->node,
pcercuei 0:03b5121a232e 15038 "base", typeDef->base, typeDef->baseNs,
pcercuei 0:03b5121a232e 15039 XML_SCHEMA_TYPE_SIMPLE, NULL);
pcercuei 0:03b5121a232e 15040 return;
pcercuei 0:03b5121a232e 15041 }
pcercuei 0:03b5121a232e 15042 }
pcercuei 0:03b5121a232e 15043 if (WXS_IS_SIMPLE(typeDef)) {
pcercuei 0:03b5121a232e 15044 if (WXS_IS_UNION(typeDef)) {
pcercuei 0:03b5121a232e 15045 /*
pcercuei 0:03b5121a232e 15046 * Resolve the memberTypes.
pcercuei 0:03b5121a232e 15047 */
pcercuei 0:03b5121a232e 15048 xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
pcercuei 0:03b5121a232e 15049 return;
pcercuei 0:03b5121a232e 15050 } else if (WXS_IS_LIST(typeDef)) {
pcercuei 0:03b5121a232e 15051 /*
pcercuei 0:03b5121a232e 15052 * Resolve the itemType.
pcercuei 0:03b5121a232e 15053 */
pcercuei 0:03b5121a232e 15054 if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
pcercuei 0:03b5121a232e 15055
pcercuei 0:03b5121a232e 15056 typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
pcercuei 0:03b5121a232e 15057 typeDef->base, typeDef->baseNs);
pcercuei 0:03b5121a232e 15058
pcercuei 0:03b5121a232e 15059 if ((typeDef->subtypes == NULL) ||
pcercuei 0:03b5121a232e 15060 (! WXS_IS_SIMPLE(typeDef->subtypes)))
pcercuei 0:03b5121a232e 15061 {
pcercuei 0:03b5121a232e 15062 typeDef->subtypes = NULL;
pcercuei 0:03b5121a232e 15063 xmlSchemaPResCompAttrErr(ctxt,
pcercuei 0:03b5121a232e 15064 XML_SCHEMAP_SRC_RESOLVE,
pcercuei 0:03b5121a232e 15065 WXS_BASIC_CAST typeDef, typeDef->node,
pcercuei 0:03b5121a232e 15066 "itemType", typeDef->base, typeDef->baseNs,
pcercuei 0:03b5121a232e 15067 XML_SCHEMA_TYPE_SIMPLE, NULL);
pcercuei 0:03b5121a232e 15068 }
pcercuei 0:03b5121a232e 15069 }
pcercuei 0:03b5121a232e 15070 return;
pcercuei 0:03b5121a232e 15071 }
pcercuei 0:03b5121a232e 15072 }
pcercuei 0:03b5121a232e 15073 /*
pcercuei 0:03b5121a232e 15074 * The ball of letters below means, that if we have a particle
pcercuei 0:03b5121a232e 15075 * which has a QName-helper component as its {term}, we want
pcercuei 0:03b5121a232e 15076 * to resolve it...
pcercuei 0:03b5121a232e 15077 */
pcercuei 0:03b5121a232e 15078 else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
pcercuei 0:03b5121a232e 15079 ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
pcercuei 0:03b5121a232e 15080 XML_SCHEMA_TYPE_PARTICLE) &&
pcercuei 0:03b5121a232e 15081 (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
pcercuei 0:03b5121a232e 15082 ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
pcercuei 0:03b5121a232e 15083 XML_SCHEMA_EXTRA_QNAMEREF))
pcercuei 0:03b5121a232e 15084 {
pcercuei 0:03b5121a232e 15085 xmlSchemaQNameRefPtr ref =
pcercuei 0:03b5121a232e 15086 WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
pcercuei 0:03b5121a232e 15087 xmlSchemaModelGroupDefPtr groupDef;
pcercuei 0:03b5121a232e 15088
pcercuei 0:03b5121a232e 15089 /*
pcercuei 0:03b5121a232e 15090 * URGENT TODO: Test this.
pcercuei 0:03b5121a232e 15091 */
pcercuei 0:03b5121a232e 15092 WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
pcercuei 0:03b5121a232e 15093 /*
pcercuei 0:03b5121a232e 15094 * Resolve the MG definition reference.
pcercuei 0:03b5121a232e 15095 */
pcercuei 0:03b5121a232e 15096 groupDef =
pcercuei 0:03b5121a232e 15097 WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
pcercuei 0:03b5121a232e 15098 ref->itemType, ref->name, ref->targetNamespace);
pcercuei 0:03b5121a232e 15099 if (groupDef == NULL) {
pcercuei 0:03b5121a232e 15100 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
pcercuei 0:03b5121a232e 15101 NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
pcercuei 0:03b5121a232e 15102 "ref", ref->name, ref->targetNamespace, ref->itemType,
pcercuei 0:03b5121a232e 15103 NULL);
pcercuei 0:03b5121a232e 15104 /* Remove the particle. */
pcercuei 0:03b5121a232e 15105 WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
pcercuei 0:03b5121a232e 15106 } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
pcercuei 0:03b5121a232e 15107 /* Remove the particle. */
pcercuei 0:03b5121a232e 15108 WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
pcercuei 0:03b5121a232e 15109 else {
pcercuei 0:03b5121a232e 15110 /*
pcercuei 0:03b5121a232e 15111 * Assign the MG definition's {model group} to the
pcercuei 0:03b5121a232e 15112 * particle's {term}.
pcercuei 0:03b5121a232e 15113 */
pcercuei 0:03b5121a232e 15114 WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
pcercuei 0:03b5121a232e 15115
pcercuei 0:03b5121a232e 15116 if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
pcercuei 0:03b5121a232e 15117 /*
pcercuei 0:03b5121a232e 15118 * SPEC cos-all-limited (1.2)
pcercuei 0:03b5121a232e 15119 * "1.2 the {term} property of a particle with
pcercuei 0:03b5121a232e 15120 * {max occurs}=1 which is part of a pair which constitutes
pcercuei 0:03b5121a232e 15121 * the {content type} of a complex type definition."
pcercuei 0:03b5121a232e 15122 */
pcercuei 0:03b5121a232e 15123 if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
pcercuei 0:03b5121a232e 15124 xmlSchemaCustomErr(ACTXT_CAST ctxt,
pcercuei 0:03b5121a232e 15125 /* TODO: error code */
pcercuei 0:03b5121a232e 15126 XML_SCHEMAP_COS_ALL_LIMITED,
pcercuei 0:03b5121a232e 15127 WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
pcercuei 0:03b5121a232e 15128 "The particle's {max occurs} must be 1, since the "
pcercuei 0:03b5121a232e 15129 "reference resolves to an 'all' model group",
pcercuei 0:03b5121a232e 15130 NULL, NULL);
pcercuei 0:03b5121a232e 15131 }
pcercuei 0:03b5121a232e 15132 }
pcercuei 0:03b5121a232e 15133 }
pcercuei 0:03b5121a232e 15134 }
pcercuei 0:03b5121a232e 15135 }
pcercuei 0:03b5121a232e 15136
pcercuei 0:03b5121a232e 15137
pcercuei 0:03b5121a232e 15138
pcercuei 0:03b5121a232e 15139 /**
pcercuei 0:03b5121a232e 15140 * xmlSchemaCheckSTPropsCorrect:
pcercuei 0:03b5121a232e 15141 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 15142 * @type: the simple type definition
pcercuei 0:03b5121a232e 15143 *
pcercuei 0:03b5121a232e 15144 * Checks st-props-correct.
pcercuei 0:03b5121a232e 15145 *
pcercuei 0:03b5121a232e 15146 * Returns 0 if the properties are correct,
pcercuei 0:03b5121a232e 15147 * if not, a positive error code and -1 on internal
pcercuei 0:03b5121a232e 15148 * errors.
pcercuei 0:03b5121a232e 15149 */
pcercuei 0:03b5121a232e 15150 static int
pcercuei 0:03b5121a232e 15151 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 15152 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 15153 {
pcercuei 0:03b5121a232e 15154 xmlSchemaTypePtr baseType = type->baseType;
pcercuei 0:03b5121a232e 15155 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 15156
pcercuei 0:03b5121a232e 15157 /* STATE: error funcs converted. */
pcercuei 0:03b5121a232e 15158 /*
pcercuei 0:03b5121a232e 15159 * Schema Component Constraint: Simple Type Definition Properties Correct
pcercuei 0:03b5121a232e 15160 *
pcercuei 0:03b5121a232e 15161 * NOTE: This is somehow redundant, since we actually built a simple type
pcercuei 0:03b5121a232e 15162 * to have all the needed information; this acts as an self test.
pcercuei 0:03b5121a232e 15163 */
pcercuei 0:03b5121a232e 15164 /* Base type: If the datatype has been `derived` by `restriction`
pcercuei 0:03b5121a232e 15165 * then the Simple Type Definition component from which it is `derived`,
pcercuei 0:03b5121a232e 15166 * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
pcercuei 0:03b5121a232e 15167 */
pcercuei 0:03b5121a232e 15168 if (baseType == NULL) {
pcercuei 0:03b5121a232e 15169 /*
pcercuei 0:03b5121a232e 15170 * TODO: Think about: "modulo the impact of Missing
pcercuei 0:03b5121a232e 15171 * Sub-components ($5.3)."
pcercuei 0:03b5121a232e 15172 */
pcercuei 0:03b5121a232e 15173 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 15174 XML_SCHEMAP_ST_PROPS_CORRECT_1,
pcercuei 0:03b5121a232e 15175 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15176 "No base type existent", NULL);
pcercuei 0:03b5121a232e 15177 return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
pcercuei 0:03b5121a232e 15178
pcercuei 0:03b5121a232e 15179 }
pcercuei 0:03b5121a232e 15180 if (! WXS_IS_SIMPLE(baseType)) {
pcercuei 0:03b5121a232e 15181 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 15182 XML_SCHEMAP_ST_PROPS_CORRECT_1,
pcercuei 0:03b5121a232e 15183 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15184 "The base type '%s' is not a simple type",
pcercuei 0:03b5121a232e 15185 xmlSchemaGetComponentQName(&str, baseType));
pcercuei 0:03b5121a232e 15186 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15187 return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
pcercuei 0:03b5121a232e 15188 }
pcercuei 0:03b5121a232e 15189 if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
pcercuei 0:03b5121a232e 15190 (WXS_IS_RESTRICTION(type) == 0) &&
pcercuei 0:03b5121a232e 15191 ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
pcercuei 0:03b5121a232e 15192 (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
pcercuei 0:03b5121a232e 15193 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 15194 XML_SCHEMAP_ST_PROPS_CORRECT_1,
pcercuei 0:03b5121a232e 15195 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15196 "A type, derived by list or union, must have "
pcercuei 0:03b5121a232e 15197 "the simple ur-type definition as base type, not '%s'",
pcercuei 0:03b5121a232e 15198 xmlSchemaGetComponentQName(&str, baseType));
pcercuei 0:03b5121a232e 15199 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15200 return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
pcercuei 0:03b5121a232e 15201 }
pcercuei 0:03b5121a232e 15202 /*
pcercuei 0:03b5121a232e 15203 * Variety: One of {atomic, list, union}.
pcercuei 0:03b5121a232e 15204 */
pcercuei 0:03b5121a232e 15205 if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
pcercuei 0:03b5121a232e 15206 (! WXS_IS_LIST(type))) {
pcercuei 0:03b5121a232e 15207 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 15208 XML_SCHEMAP_ST_PROPS_CORRECT_1,
pcercuei 0:03b5121a232e 15209 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15210 "The variety is absent", NULL);
pcercuei 0:03b5121a232e 15211 return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
pcercuei 0:03b5121a232e 15212 }
pcercuei 0:03b5121a232e 15213 /* TODO: Finish this. Hmm, is this finished? */
pcercuei 0:03b5121a232e 15214
pcercuei 0:03b5121a232e 15215 /*
pcercuei 0:03b5121a232e 15216 * 3 The {final} of the {base type definition} must not contain restriction.
pcercuei 0:03b5121a232e 15217 */
pcercuei 0:03b5121a232e 15218 if (xmlSchemaTypeFinalContains(baseType,
pcercuei 0:03b5121a232e 15219 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
pcercuei 0:03b5121a232e 15220 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 15221 XML_SCHEMAP_ST_PROPS_CORRECT_3,
pcercuei 0:03b5121a232e 15222 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15223 "The 'final' of its base type '%s' must not contain "
pcercuei 0:03b5121a232e 15224 "'restriction'",
pcercuei 0:03b5121a232e 15225 xmlSchemaGetComponentQName(&str, baseType));
pcercuei 0:03b5121a232e 15226 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15227 return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
pcercuei 0:03b5121a232e 15228 }
pcercuei 0:03b5121a232e 15229
pcercuei 0:03b5121a232e 15230 /*
pcercuei 0:03b5121a232e 15231 * 2 All simple type definitions must be derived ultimately from the `simple
pcercuei 0:03b5121a232e 15232 * ur-type definition` (so circular definitions are disallowed). That is, it
pcercuei 0:03b5121a232e 15233 * must be possible to reach a built-in primitive datatype or the `simple
pcercuei 0:03b5121a232e 15234 * ur-type definition` by repeatedly following the {base type definition}.
pcercuei 0:03b5121a232e 15235 *
pcercuei 0:03b5121a232e 15236 * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
pcercuei 0:03b5121a232e 15237 */
pcercuei 0:03b5121a232e 15238 return (0);
pcercuei 0:03b5121a232e 15239 }
pcercuei 0:03b5121a232e 15240
pcercuei 0:03b5121a232e 15241 /**
pcercuei 0:03b5121a232e 15242 * xmlSchemaCheckCOSSTRestricts:
pcercuei 0:03b5121a232e 15243 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 15244 * @type: the simple type definition
pcercuei 0:03b5121a232e 15245 *
pcercuei 0:03b5121a232e 15246 * Schema Component Constraint:
pcercuei 0:03b5121a232e 15247 * Derivation Valid (Restriction, Simple) (cos-st-restricts)
pcercuei 0:03b5121a232e 15248
pcercuei 0:03b5121a232e 15249 * Checks if the given @type (simpleType) is derived validly by restriction.
pcercuei 0:03b5121a232e 15250 * STATUS:
pcercuei 0:03b5121a232e 15251 *
pcercuei 0:03b5121a232e 15252 * Returns -1 on internal errors, 0 if the type is validly derived,
pcercuei 0:03b5121a232e 15253 * a positive error code otherwise.
pcercuei 0:03b5121a232e 15254 */
pcercuei 0:03b5121a232e 15255 static int
pcercuei 0:03b5121a232e 15256 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 15257 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 15258 {
pcercuei 0:03b5121a232e 15259 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 15260
pcercuei 0:03b5121a232e 15261 if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
pcercuei 0:03b5121a232e 15262 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
pcercuei 0:03b5121a232e 15263 "given type is not a user-derived simpleType");
pcercuei 0:03b5121a232e 15264 return (-1);
pcercuei 0:03b5121a232e 15265 }
pcercuei 0:03b5121a232e 15266
pcercuei 0:03b5121a232e 15267 if (WXS_IS_ATOMIC(type)) {
pcercuei 0:03b5121a232e 15268 xmlSchemaTypePtr primitive;
pcercuei 0:03b5121a232e 15269 /*
pcercuei 0:03b5121a232e 15270 * 1.1 The {base type definition} must be an atomic simple
pcercuei 0:03b5121a232e 15271 * type definition or a built-in primitive datatype.
pcercuei 0:03b5121a232e 15272 */
pcercuei 0:03b5121a232e 15273 if (! WXS_IS_ATOMIC(type->baseType)) {
pcercuei 0:03b5121a232e 15274 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 15275 XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
pcercuei 0:03b5121a232e 15276 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15277 "The base type '%s' is not an atomic simple type",
pcercuei 0:03b5121a232e 15278 xmlSchemaGetComponentQName(&str, type->baseType));
pcercuei 0:03b5121a232e 15279 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15280 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
pcercuei 0:03b5121a232e 15281 }
pcercuei 0:03b5121a232e 15282 /* 1.2 The {final} of the {base type definition} must not contain
pcercuei 0:03b5121a232e 15283 * restriction.
pcercuei 0:03b5121a232e 15284 */
pcercuei 0:03b5121a232e 15285 /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
pcercuei 0:03b5121a232e 15286 if (xmlSchemaTypeFinalContains(type->baseType,
pcercuei 0:03b5121a232e 15287 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
pcercuei 0:03b5121a232e 15288 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 15289 XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
pcercuei 0:03b5121a232e 15290 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15291 "The final of its base type '%s' must not contain 'restriction'",
pcercuei 0:03b5121a232e 15292 xmlSchemaGetComponentQName(&str, type->baseType));
pcercuei 0:03b5121a232e 15293 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15294 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
pcercuei 0:03b5121a232e 15295 }
pcercuei 0:03b5121a232e 15296
pcercuei 0:03b5121a232e 15297 /*
pcercuei 0:03b5121a232e 15298 * 1.3.1 DF must be an allowed constraining facet for the {primitive
pcercuei 0:03b5121a232e 15299 * type definition}, as specified in the appropriate subsection of 3.2
pcercuei 0:03b5121a232e 15300 * Primitive datatypes.
pcercuei 0:03b5121a232e 15301 */
pcercuei 0:03b5121a232e 15302 if (type->facets != NULL) {
pcercuei 0:03b5121a232e 15303 xmlSchemaFacetPtr facet;
pcercuei 0:03b5121a232e 15304 int ok = 1;
pcercuei 0:03b5121a232e 15305
pcercuei 0:03b5121a232e 15306 primitive = xmlSchemaGetPrimitiveType(type);
pcercuei 0:03b5121a232e 15307 if (primitive == NULL) {
pcercuei 0:03b5121a232e 15308 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
pcercuei 0:03b5121a232e 15309 "failed to get primitive type");
pcercuei 0:03b5121a232e 15310 return (-1);
pcercuei 0:03b5121a232e 15311 }
pcercuei 0:03b5121a232e 15312 facet = type->facets;
pcercuei 0:03b5121a232e 15313 do {
pcercuei 0:03b5121a232e 15314 if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
pcercuei 0:03b5121a232e 15315 ok = 0;
pcercuei 0:03b5121a232e 15316 xmlSchemaPIllegalFacetAtomicErr(pctxt,
pcercuei 0:03b5121a232e 15317 XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
pcercuei 0:03b5121a232e 15318 type, primitive, facet);
pcercuei 0:03b5121a232e 15319 }
pcercuei 0:03b5121a232e 15320 facet = facet->next;
pcercuei 0:03b5121a232e 15321 } while (facet != NULL);
pcercuei 0:03b5121a232e 15322 if (ok == 0)
pcercuei 0:03b5121a232e 15323 return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
pcercuei 0:03b5121a232e 15324 }
pcercuei 0:03b5121a232e 15325 /*
pcercuei 0:03b5121a232e 15326 * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
pcercuei 0:03b5121a232e 15327 * of the {base type definition} (call this BF),then the DF's {value}
pcercuei 0:03b5121a232e 15328 * must be a valid restriction of BF's {value} as defined in
pcercuei 0:03b5121a232e 15329 * [XML Schemas: Datatypes]."
pcercuei 0:03b5121a232e 15330 *
pcercuei 0:03b5121a232e 15331 * NOTE (1.3.2) Facet derivation constraints are currently handled in
pcercuei 0:03b5121a232e 15332 * xmlSchemaDeriveAndValidateFacets()
pcercuei 0:03b5121a232e 15333 */
pcercuei 0:03b5121a232e 15334 } else if (WXS_IS_LIST(type)) {
pcercuei 0:03b5121a232e 15335 xmlSchemaTypePtr itemType = NULL;
pcercuei 0:03b5121a232e 15336
pcercuei 0:03b5121a232e 15337 itemType = type->subtypes;
pcercuei 0:03b5121a232e 15338 if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
pcercuei 0:03b5121a232e 15339 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
pcercuei 0:03b5121a232e 15340 "failed to evaluate the item type");
pcercuei 0:03b5121a232e 15341 return (-1);
pcercuei 0:03b5121a232e 15342 }
pcercuei 0:03b5121a232e 15343 if (WXS_IS_TYPE_NOT_FIXED(itemType))
pcercuei 0:03b5121a232e 15344 xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
pcercuei 0:03b5121a232e 15345 /*
pcercuei 0:03b5121a232e 15346 * 2.1 The {item type definition} must have a {variety} of atomic or
pcercuei 0:03b5121a232e 15347 * union (in which case all the {member type definitions}
pcercuei 0:03b5121a232e 15348 * must be atomic).
pcercuei 0:03b5121a232e 15349 */
pcercuei 0:03b5121a232e 15350 if ((! WXS_IS_ATOMIC(itemType)) &&
pcercuei 0:03b5121a232e 15351 (! WXS_IS_UNION(itemType))) {
pcercuei 0:03b5121a232e 15352 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 15353 XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
pcercuei 0:03b5121a232e 15354 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15355 "The item type '%s' does not have a variety of atomic or union",
pcercuei 0:03b5121a232e 15356 xmlSchemaGetComponentQName(&str, itemType));
pcercuei 0:03b5121a232e 15357 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15358 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
pcercuei 0:03b5121a232e 15359 } else if (WXS_IS_UNION(itemType)) {
pcercuei 0:03b5121a232e 15360 xmlSchemaTypeLinkPtr member;
pcercuei 0:03b5121a232e 15361
pcercuei 0:03b5121a232e 15362 member = itemType->memberTypes;
pcercuei 0:03b5121a232e 15363 while (member != NULL) {
pcercuei 0:03b5121a232e 15364 if (! WXS_IS_ATOMIC(member->type)) {
pcercuei 0:03b5121a232e 15365 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 15366 XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
pcercuei 0:03b5121a232e 15367 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15368 "The item type is a union type, but the "
pcercuei 0:03b5121a232e 15369 "member type '%s' of this item type is not atomic",
pcercuei 0:03b5121a232e 15370 xmlSchemaGetComponentQName(&str, member->type));
pcercuei 0:03b5121a232e 15371 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15372 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
pcercuei 0:03b5121a232e 15373 }
pcercuei 0:03b5121a232e 15374 member = member->next;
pcercuei 0:03b5121a232e 15375 }
pcercuei 0:03b5121a232e 15376 }
pcercuei 0:03b5121a232e 15377
pcercuei 0:03b5121a232e 15378 if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
pcercuei 0:03b5121a232e 15379 xmlSchemaFacetPtr facet;
pcercuei 0:03b5121a232e 15380 /*
pcercuei 0:03b5121a232e 15381 * This is the case if we have: <simpleType><list ..
pcercuei 0:03b5121a232e 15382 */
pcercuei 0:03b5121a232e 15383 /*
pcercuei 0:03b5121a232e 15384 * 2.3.1
pcercuei 0:03b5121a232e 15385 * 2.3.1.1 The {final} of the {item type definition} must not
pcercuei 0:03b5121a232e 15386 * contain list.
pcercuei 0:03b5121a232e 15387 */
pcercuei 0:03b5121a232e 15388 if (xmlSchemaTypeFinalContains(itemType,
pcercuei 0:03b5121a232e 15389 XML_SCHEMAS_TYPE_FINAL_LIST)) {
pcercuei 0:03b5121a232e 15390 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 15391 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
pcercuei 0:03b5121a232e 15392 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15393 "The final of its item type '%s' must not contain 'list'",
pcercuei 0:03b5121a232e 15394 xmlSchemaGetComponentQName(&str, itemType));
pcercuei 0:03b5121a232e 15395 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15396 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
pcercuei 0:03b5121a232e 15397 }
pcercuei 0:03b5121a232e 15398 /*
pcercuei 0:03b5121a232e 15399 * 2.3.1.2 The {facets} must only contain the whiteSpace
pcercuei 0:03b5121a232e 15400 * facet component.
pcercuei 0:03b5121a232e 15401 * OPTIMIZE TODO: the S4S already disallows any facet
pcercuei 0:03b5121a232e 15402 * to be specified.
pcercuei 0:03b5121a232e 15403 */
pcercuei 0:03b5121a232e 15404 if (type->facets != NULL) {
pcercuei 0:03b5121a232e 15405 facet = type->facets;
pcercuei 0:03b5121a232e 15406 do {
pcercuei 0:03b5121a232e 15407 if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
pcercuei 0:03b5121a232e 15408 xmlSchemaPIllegalFacetListUnionErr(pctxt,
pcercuei 0:03b5121a232e 15409 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
pcercuei 0:03b5121a232e 15410 type, facet);
pcercuei 0:03b5121a232e 15411 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
pcercuei 0:03b5121a232e 15412 }
pcercuei 0:03b5121a232e 15413 facet = facet->next;
pcercuei 0:03b5121a232e 15414 } while (facet != NULL);
pcercuei 0:03b5121a232e 15415 }
pcercuei 0:03b5121a232e 15416 /*
pcercuei 0:03b5121a232e 15417 * MAYBE TODO: (Hmm, not really) Datatypes states:
pcercuei 0:03b5121a232e 15418 * A `list` datatype can be `derived` from an `atomic` datatype
pcercuei 0:03b5121a232e 15419 * whose `lexical space` allows space (such as string or anyURI)or
pcercuei 0:03b5121a232e 15420 * a `union` datatype any of whose {member type definitions}'s
pcercuei 0:03b5121a232e 15421 * `lexical space` allows space.
pcercuei 0:03b5121a232e 15422 */
pcercuei 0:03b5121a232e 15423 } else {
pcercuei 0:03b5121a232e 15424 /*
pcercuei 0:03b5121a232e 15425 * This is the case if we have: <simpleType><restriction ...
pcercuei 0:03b5121a232e 15426 * I.e. the variety of "list" is inherited.
pcercuei 0:03b5121a232e 15427 */
pcercuei 0:03b5121a232e 15428 /*
pcercuei 0:03b5121a232e 15429 * 2.3.2
pcercuei 0:03b5121a232e 15430 * 2.3.2.1 The {base type definition} must have a {variety} of list.
pcercuei 0:03b5121a232e 15431 */
pcercuei 0:03b5121a232e 15432 if (! WXS_IS_LIST(type->baseType)) {
pcercuei 0:03b5121a232e 15433 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 15434 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
pcercuei 0:03b5121a232e 15435 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15436 "The base type '%s' must be a list type",
pcercuei 0:03b5121a232e 15437 xmlSchemaGetComponentQName(&str, type->baseType));
pcercuei 0:03b5121a232e 15438 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15439 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
pcercuei 0:03b5121a232e 15440 }
pcercuei 0:03b5121a232e 15441 /*
pcercuei 0:03b5121a232e 15442 * 2.3.2.2 The {final} of the {base type definition} must not
pcercuei 0:03b5121a232e 15443 * contain restriction.
pcercuei 0:03b5121a232e 15444 */
pcercuei 0:03b5121a232e 15445 if (xmlSchemaTypeFinalContains(type->baseType,
pcercuei 0:03b5121a232e 15446 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
pcercuei 0:03b5121a232e 15447 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 15448 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
pcercuei 0:03b5121a232e 15449 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15450 "The 'final' of the base type '%s' must not contain 'restriction'",
pcercuei 0:03b5121a232e 15451 xmlSchemaGetComponentQName(&str, type->baseType));
pcercuei 0:03b5121a232e 15452 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15453 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
pcercuei 0:03b5121a232e 15454 }
pcercuei 0:03b5121a232e 15455 /*
pcercuei 0:03b5121a232e 15456 * 2.3.2.3 The {item type definition} must be validly derived
pcercuei 0:03b5121a232e 15457 * from the {base type definition}'s {item type definition} given
pcercuei 0:03b5121a232e 15458 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
pcercuei 0:03b5121a232e 15459 */
pcercuei 0:03b5121a232e 15460 {
pcercuei 0:03b5121a232e 15461 xmlSchemaTypePtr baseItemType;
pcercuei 0:03b5121a232e 15462
pcercuei 0:03b5121a232e 15463 baseItemType = type->baseType->subtypes;
pcercuei 0:03b5121a232e 15464 if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
pcercuei 0:03b5121a232e 15465 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
pcercuei 0:03b5121a232e 15466 "failed to eval the item type of a base type");
pcercuei 0:03b5121a232e 15467 return (-1);
pcercuei 0:03b5121a232e 15468 }
pcercuei 0:03b5121a232e 15469 if ((itemType != baseItemType) &&
pcercuei 0:03b5121a232e 15470 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
pcercuei 0:03b5121a232e 15471 baseItemType, 0) != 0)) {
pcercuei 0:03b5121a232e 15472 xmlChar *strBIT = NULL, *strBT = NULL;
pcercuei 0:03b5121a232e 15473 xmlSchemaPCustomErrExt(pctxt,
pcercuei 0:03b5121a232e 15474 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
pcercuei 0:03b5121a232e 15475 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15476 "The item type '%s' is not validly derived from "
pcercuei 0:03b5121a232e 15477 "the item type '%s' of the base type '%s'",
pcercuei 0:03b5121a232e 15478 xmlSchemaGetComponentQName(&str, itemType),
pcercuei 0:03b5121a232e 15479 xmlSchemaGetComponentQName(&strBIT, baseItemType),
pcercuei 0:03b5121a232e 15480 xmlSchemaGetComponentQName(&strBT, type->baseType));
pcercuei 0:03b5121a232e 15481
pcercuei 0:03b5121a232e 15482 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15483 FREE_AND_NULL(strBIT)
pcercuei 0:03b5121a232e 15484 FREE_AND_NULL(strBT)
pcercuei 0:03b5121a232e 15485 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
pcercuei 0:03b5121a232e 15486 }
pcercuei 0:03b5121a232e 15487 }
pcercuei 0:03b5121a232e 15488
pcercuei 0:03b5121a232e 15489 if (type->facets != NULL) {
pcercuei 0:03b5121a232e 15490 xmlSchemaFacetPtr facet;
pcercuei 0:03b5121a232e 15491 int ok = 1;
pcercuei 0:03b5121a232e 15492 /*
pcercuei 0:03b5121a232e 15493 * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
pcercuei 0:03b5121a232e 15494 * and enumeration facet components are allowed among the {facets}.
pcercuei 0:03b5121a232e 15495 */
pcercuei 0:03b5121a232e 15496 facet = type->facets;
pcercuei 0:03b5121a232e 15497 do {
pcercuei 0:03b5121a232e 15498 switch (facet->type) {
pcercuei 0:03b5121a232e 15499 case XML_SCHEMA_FACET_LENGTH:
pcercuei 0:03b5121a232e 15500 case XML_SCHEMA_FACET_MINLENGTH:
pcercuei 0:03b5121a232e 15501 case XML_SCHEMA_FACET_MAXLENGTH:
pcercuei 0:03b5121a232e 15502 case XML_SCHEMA_FACET_WHITESPACE:
pcercuei 0:03b5121a232e 15503 /*
pcercuei 0:03b5121a232e 15504 * TODO: 2.5.1.2 List datatypes
pcercuei 0:03b5121a232e 15505 * The value of `whiteSpace` is fixed to the value collapse.
pcercuei 0:03b5121a232e 15506 */
pcercuei 0:03b5121a232e 15507 case XML_SCHEMA_FACET_PATTERN:
pcercuei 0:03b5121a232e 15508 case XML_SCHEMA_FACET_ENUMERATION:
pcercuei 0:03b5121a232e 15509 break;
pcercuei 0:03b5121a232e 15510 default: {
pcercuei 0:03b5121a232e 15511 xmlSchemaPIllegalFacetListUnionErr(pctxt,
pcercuei 0:03b5121a232e 15512 XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
pcercuei 0:03b5121a232e 15513 type, facet);
pcercuei 0:03b5121a232e 15514 /*
pcercuei 0:03b5121a232e 15515 * We could return, but it's nicer to report all
pcercuei 0:03b5121a232e 15516 * invalid facets.
pcercuei 0:03b5121a232e 15517 */
pcercuei 0:03b5121a232e 15518 ok = 0;
pcercuei 0:03b5121a232e 15519 }
pcercuei 0:03b5121a232e 15520 }
pcercuei 0:03b5121a232e 15521 facet = facet->next;
pcercuei 0:03b5121a232e 15522 } while (facet != NULL);
pcercuei 0:03b5121a232e 15523 if (ok == 0)
pcercuei 0:03b5121a232e 15524 return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
pcercuei 0:03b5121a232e 15525 /*
pcercuei 0:03b5121a232e 15526 * SPEC (2.3.2.5) (same as 1.3.2)
pcercuei 0:03b5121a232e 15527 *
pcercuei 0:03b5121a232e 15528 * NOTE (2.3.2.5) This is currently done in
pcercuei 0:03b5121a232e 15529 * xmlSchemaDeriveAndValidateFacets()
pcercuei 0:03b5121a232e 15530 */
pcercuei 0:03b5121a232e 15531 }
pcercuei 0:03b5121a232e 15532 }
pcercuei 0:03b5121a232e 15533 } else if (WXS_IS_UNION(type)) {
pcercuei 0:03b5121a232e 15534 /*
pcercuei 0:03b5121a232e 15535 * 3.1 The {member type definitions} must all have {variety} of
pcercuei 0:03b5121a232e 15536 * atomic or list.
pcercuei 0:03b5121a232e 15537 */
pcercuei 0:03b5121a232e 15538 xmlSchemaTypeLinkPtr member;
pcercuei 0:03b5121a232e 15539
pcercuei 0:03b5121a232e 15540 member = type->memberTypes;
pcercuei 0:03b5121a232e 15541 while (member != NULL) {
pcercuei 0:03b5121a232e 15542 if (WXS_IS_TYPE_NOT_FIXED(member->type))
pcercuei 0:03b5121a232e 15543 xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
pcercuei 0:03b5121a232e 15544
pcercuei 0:03b5121a232e 15545 if ((! WXS_IS_ATOMIC(member->type)) &&
pcercuei 0:03b5121a232e 15546 (! WXS_IS_LIST(member->type))) {
pcercuei 0:03b5121a232e 15547 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 15548 XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
pcercuei 0:03b5121a232e 15549 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15550 "The member type '%s' is neither an atomic, nor a list type",
pcercuei 0:03b5121a232e 15551 xmlSchemaGetComponentQName(&str, member->type));
pcercuei 0:03b5121a232e 15552 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15553 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
pcercuei 0:03b5121a232e 15554 }
pcercuei 0:03b5121a232e 15555 member = member->next;
pcercuei 0:03b5121a232e 15556 }
pcercuei 0:03b5121a232e 15557 /*
pcercuei 0:03b5121a232e 15558 * 3.3.1 If the {base type definition} is the `simple ur-type
pcercuei 0:03b5121a232e 15559 * definition`
pcercuei 0:03b5121a232e 15560 */
pcercuei 0:03b5121a232e 15561 if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
pcercuei 0:03b5121a232e 15562 /*
pcercuei 0:03b5121a232e 15563 * 3.3.1.1 All of the {member type definitions} must have a
pcercuei 0:03b5121a232e 15564 * {final} which does not contain union.
pcercuei 0:03b5121a232e 15565 */
pcercuei 0:03b5121a232e 15566 member = type->memberTypes;
pcercuei 0:03b5121a232e 15567 while (member != NULL) {
pcercuei 0:03b5121a232e 15568 if (xmlSchemaTypeFinalContains(member->type,
pcercuei 0:03b5121a232e 15569 XML_SCHEMAS_TYPE_FINAL_UNION)) {
pcercuei 0:03b5121a232e 15570 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 15571 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
pcercuei 0:03b5121a232e 15572 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15573 "The 'final' of member type '%s' contains 'union'",
pcercuei 0:03b5121a232e 15574 xmlSchemaGetComponentQName(&str, member->type));
pcercuei 0:03b5121a232e 15575 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15576 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
pcercuei 0:03b5121a232e 15577 }
pcercuei 0:03b5121a232e 15578 member = member->next;
pcercuei 0:03b5121a232e 15579 }
pcercuei 0:03b5121a232e 15580 /*
pcercuei 0:03b5121a232e 15581 * 3.3.1.2 The {facets} must be empty.
pcercuei 0:03b5121a232e 15582 */
pcercuei 0:03b5121a232e 15583 if (type->facetSet != NULL) {
pcercuei 0:03b5121a232e 15584 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 15585 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
pcercuei 0:03b5121a232e 15586 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15587 "No facets allowed", NULL);
pcercuei 0:03b5121a232e 15588 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
pcercuei 0:03b5121a232e 15589 }
pcercuei 0:03b5121a232e 15590 } else {
pcercuei 0:03b5121a232e 15591 /*
pcercuei 0:03b5121a232e 15592 * 3.3.2.1 The {base type definition} must have a {variety} of union.
pcercuei 0:03b5121a232e 15593 * I.e. the variety of "list" is inherited.
pcercuei 0:03b5121a232e 15594 */
pcercuei 0:03b5121a232e 15595 if (! WXS_IS_UNION(type->baseType)) {
pcercuei 0:03b5121a232e 15596 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 15597 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
pcercuei 0:03b5121a232e 15598 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15599 "The base type '%s' is not a union type",
pcercuei 0:03b5121a232e 15600 xmlSchemaGetComponentQName(&str, type->baseType));
pcercuei 0:03b5121a232e 15601 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15602 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
pcercuei 0:03b5121a232e 15603 }
pcercuei 0:03b5121a232e 15604 /*
pcercuei 0:03b5121a232e 15605 * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
pcercuei 0:03b5121a232e 15606 */
pcercuei 0:03b5121a232e 15607 if (xmlSchemaTypeFinalContains(type->baseType,
pcercuei 0:03b5121a232e 15608 XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
pcercuei 0:03b5121a232e 15609 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 15610 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
pcercuei 0:03b5121a232e 15611 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15612 "The 'final' of its base type '%s' must not contain 'restriction'",
pcercuei 0:03b5121a232e 15613 xmlSchemaGetComponentQName(&str, type->baseType));
pcercuei 0:03b5121a232e 15614 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15615 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
pcercuei 0:03b5121a232e 15616 }
pcercuei 0:03b5121a232e 15617 /*
pcercuei 0:03b5121a232e 15618 * 3.3.2.3 The {member type definitions}, in order, must be validly
pcercuei 0:03b5121a232e 15619 * derived from the corresponding type definitions in the {base
pcercuei 0:03b5121a232e 15620 * type definition}'s {member type definitions} given the empty set,
pcercuei 0:03b5121a232e 15621 * as defined in Type Derivation OK (Simple) ($3.14.6).
pcercuei 0:03b5121a232e 15622 */
pcercuei 0:03b5121a232e 15623 {
pcercuei 0:03b5121a232e 15624 xmlSchemaTypeLinkPtr baseMember;
pcercuei 0:03b5121a232e 15625
pcercuei 0:03b5121a232e 15626 /*
pcercuei 0:03b5121a232e 15627 * OPTIMIZE: if the type is restricting, it has no local defined
pcercuei 0:03b5121a232e 15628 * member types and inherits the member types of the base type;
pcercuei 0:03b5121a232e 15629 * thus a check for equality can be skipped.
pcercuei 0:03b5121a232e 15630 */
pcercuei 0:03b5121a232e 15631 /*
pcercuei 0:03b5121a232e 15632 * Even worse: I cannot see a scenario where a restricting
pcercuei 0:03b5121a232e 15633 * union simple type can have other member types as the member
pcercuei 0:03b5121a232e 15634 * types of it's base type. This check seems not necessary with
pcercuei 0:03b5121a232e 15635 * respect to the derivation process in libxml2.
pcercuei 0:03b5121a232e 15636 * But necessary if constructing types with an API.
pcercuei 0:03b5121a232e 15637 */
pcercuei 0:03b5121a232e 15638 if (type->memberTypes != NULL) {
pcercuei 0:03b5121a232e 15639 member = type->memberTypes;
pcercuei 0:03b5121a232e 15640 baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
pcercuei 0:03b5121a232e 15641 if ((member == NULL) && (baseMember != NULL)) {
pcercuei 0:03b5121a232e 15642 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
pcercuei 0:03b5121a232e 15643 "different number of member types in base");
pcercuei 0:03b5121a232e 15644 }
pcercuei 0:03b5121a232e 15645 while (member != NULL) {
pcercuei 0:03b5121a232e 15646 if (baseMember == NULL) {
pcercuei 0:03b5121a232e 15647 PERROR_INT("xmlSchemaCheckCOSSTRestricts",
pcercuei 0:03b5121a232e 15648 "different number of member types in base");
pcercuei 0:03b5121a232e 15649 } else if ((member->type != baseMember->type) &&
pcercuei 0:03b5121a232e 15650 (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 15651 member->type, baseMember->type, 0) != 0)) {
pcercuei 0:03b5121a232e 15652 xmlChar *strBMT = NULL, *strBT = NULL;
pcercuei 0:03b5121a232e 15653
pcercuei 0:03b5121a232e 15654 xmlSchemaPCustomErrExt(pctxt,
pcercuei 0:03b5121a232e 15655 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
pcercuei 0:03b5121a232e 15656 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 15657 "The member type %s is not validly "
pcercuei 0:03b5121a232e 15658 "derived from its corresponding member "
pcercuei 0:03b5121a232e 15659 "type %s of the base type %s",
pcercuei 0:03b5121a232e 15660 xmlSchemaGetComponentQName(&str, member->type),
pcercuei 0:03b5121a232e 15661 xmlSchemaGetComponentQName(&strBMT, baseMember->type),
pcercuei 0:03b5121a232e 15662 xmlSchemaGetComponentQName(&strBT, type->baseType));
pcercuei 0:03b5121a232e 15663 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 15664 FREE_AND_NULL(strBMT)
pcercuei 0:03b5121a232e 15665 FREE_AND_NULL(strBT)
pcercuei 0:03b5121a232e 15666 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
pcercuei 0:03b5121a232e 15667 }
pcercuei 0:03b5121a232e 15668 member = member->next;
pcercuei 0:03b5121a232e 15669 if (baseMember != NULL)
pcercuei 0:03b5121a232e 15670 baseMember = baseMember->next;
pcercuei 0:03b5121a232e 15671 }
pcercuei 0:03b5121a232e 15672 }
pcercuei 0:03b5121a232e 15673 }
pcercuei 0:03b5121a232e 15674 /*
pcercuei 0:03b5121a232e 15675 * 3.3.2.4 Only pattern and enumeration facet components are
pcercuei 0:03b5121a232e 15676 * allowed among the {facets}.
pcercuei 0:03b5121a232e 15677 */
pcercuei 0:03b5121a232e 15678 if (type->facets != NULL) {
pcercuei 0:03b5121a232e 15679 xmlSchemaFacetPtr facet;
pcercuei 0:03b5121a232e 15680 int ok = 1;
pcercuei 0:03b5121a232e 15681
pcercuei 0:03b5121a232e 15682 facet = type->facets;
pcercuei 0:03b5121a232e 15683 do {
pcercuei 0:03b5121a232e 15684 if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
pcercuei 0:03b5121a232e 15685 (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
pcercuei 0:03b5121a232e 15686 xmlSchemaPIllegalFacetListUnionErr(pctxt,
pcercuei 0:03b5121a232e 15687 XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
pcercuei 0:03b5121a232e 15688 type, facet);
pcercuei 0:03b5121a232e 15689 ok = 0;
pcercuei 0:03b5121a232e 15690 }
pcercuei 0:03b5121a232e 15691 facet = facet->next;
pcercuei 0:03b5121a232e 15692 } while (facet != NULL);
pcercuei 0:03b5121a232e 15693 if (ok == 0)
pcercuei 0:03b5121a232e 15694 return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
pcercuei 0:03b5121a232e 15695
pcercuei 0:03b5121a232e 15696 }
pcercuei 0:03b5121a232e 15697 /*
pcercuei 0:03b5121a232e 15698 * SPEC (3.3.2.5) (same as 1.3.2)
pcercuei 0:03b5121a232e 15699 *
pcercuei 0:03b5121a232e 15700 * NOTE (3.3.2.5) This is currently done in
pcercuei 0:03b5121a232e 15701 * xmlSchemaDeriveAndValidateFacets()
pcercuei 0:03b5121a232e 15702 */
pcercuei 0:03b5121a232e 15703 }
pcercuei 0:03b5121a232e 15704 }
pcercuei 0:03b5121a232e 15705
pcercuei 0:03b5121a232e 15706 return (0);
pcercuei 0:03b5121a232e 15707 }
pcercuei 0:03b5121a232e 15708
pcercuei 0:03b5121a232e 15709 /**
pcercuei 0:03b5121a232e 15710 * xmlSchemaCheckSRCSimpleType:
pcercuei 0:03b5121a232e 15711 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 15712 * @type: the simple type definition
pcercuei 0:03b5121a232e 15713 *
pcercuei 0:03b5121a232e 15714 * Checks crc-simple-type constraints.
pcercuei 0:03b5121a232e 15715 *
pcercuei 0:03b5121a232e 15716 * Returns 0 if the constraints are satisfied,
pcercuei 0:03b5121a232e 15717 * if not a positive error code and -1 on internal
pcercuei 0:03b5121a232e 15718 * errors.
pcercuei 0:03b5121a232e 15719 */
pcercuei 0:03b5121a232e 15720 #if 0
pcercuei 0:03b5121a232e 15721 static int
pcercuei 0:03b5121a232e 15722 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 15723 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 15724 {
pcercuei 0:03b5121a232e 15725 /*
pcercuei 0:03b5121a232e 15726 * src-simple-type.1 The corresponding simple type definition, if any,
pcercuei 0:03b5121a232e 15727 * must satisfy the conditions set out in Constraints on Simple Type
pcercuei 0:03b5121a232e 15728 * Definition Schema Components ($3.14.6).
pcercuei 0:03b5121a232e 15729 */
pcercuei 0:03b5121a232e 15730 if (WXS_IS_RESTRICTION(type)) {
pcercuei 0:03b5121a232e 15731 /*
pcercuei 0:03b5121a232e 15732 * src-simple-type.2 "If the <restriction> alternative is chosen,
pcercuei 0:03b5121a232e 15733 * either it must have a base [attribute] or a <simpleType> among its
pcercuei 0:03b5121a232e 15734 * [children], but not both."
pcercuei 0:03b5121a232e 15735 * NOTE: This is checked in the parse function of <restriction>.
pcercuei 0:03b5121a232e 15736 */
pcercuei 0:03b5121a232e 15737 /*
pcercuei 0:03b5121a232e 15738 *
pcercuei 0:03b5121a232e 15739 */
pcercuei 0:03b5121a232e 15740 } else if (WXS_IS_LIST(type)) {
pcercuei 0:03b5121a232e 15741 /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
pcercuei 0:03b5121a232e 15742 * an itemType [attribute] or a <simpleType> among its [children],
pcercuei 0:03b5121a232e 15743 * but not both."
pcercuei 0:03b5121a232e 15744 *
pcercuei 0:03b5121a232e 15745 * NOTE: This is checked in the parse function of <list>.
pcercuei 0:03b5121a232e 15746 */
pcercuei 0:03b5121a232e 15747 } else if (WXS_IS_UNION(type)) {
pcercuei 0:03b5121a232e 15748 /*
pcercuei 0:03b5121a232e 15749 * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
pcercuei 0:03b5121a232e 15750 */
pcercuei 0:03b5121a232e 15751 }
pcercuei 0:03b5121a232e 15752 return (0);
pcercuei 0:03b5121a232e 15753 }
pcercuei 0:03b5121a232e 15754 #endif
pcercuei 0:03b5121a232e 15755
pcercuei 0:03b5121a232e 15756 static int
pcercuei 0:03b5121a232e 15757 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 15758 {
pcercuei 0:03b5121a232e 15759 if (ctxt->vctxt == NULL) {
pcercuei 0:03b5121a232e 15760 ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
pcercuei 0:03b5121a232e 15761 if (ctxt->vctxt == NULL) {
pcercuei 0:03b5121a232e 15762 xmlSchemaPErr(ctxt, NULL,
pcercuei 0:03b5121a232e 15763 XML_SCHEMAP_INTERNAL,
pcercuei 0:03b5121a232e 15764 "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
pcercuei 0:03b5121a232e 15765 "failed to create a temp. validation context.\n",
pcercuei 0:03b5121a232e 15766 NULL, NULL);
pcercuei 0:03b5121a232e 15767 return (-1);
pcercuei 0:03b5121a232e 15768 }
pcercuei 0:03b5121a232e 15769 /* TODO: Pass user data. */
pcercuei 0:03b5121a232e 15770 xmlSchemaSetValidErrors(ctxt->vctxt,
pcercuei 0:03b5121a232e 15771 ctxt->error, ctxt->warning, ctxt->errCtxt);
pcercuei 0:03b5121a232e 15772 xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
pcercuei 0:03b5121a232e 15773 ctxt->serror, ctxt->errCtxt);
pcercuei 0:03b5121a232e 15774 }
pcercuei 0:03b5121a232e 15775 return (0);
pcercuei 0:03b5121a232e 15776 }
pcercuei 0:03b5121a232e 15777
pcercuei 0:03b5121a232e 15778 static int
pcercuei 0:03b5121a232e 15779 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 15780 xmlNodePtr node,
pcercuei 0:03b5121a232e 15781 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 15782 const xmlChar *value,
pcercuei 0:03b5121a232e 15783 xmlSchemaValPtr *retVal,
pcercuei 0:03b5121a232e 15784 int fireErrors,
pcercuei 0:03b5121a232e 15785 int normalize,
pcercuei 0:03b5121a232e 15786 int isNormalized);
pcercuei 0:03b5121a232e 15787
pcercuei 0:03b5121a232e 15788 /**
pcercuei 0:03b5121a232e 15789 * xmlSchemaParseCheckCOSValidDefault:
pcercuei 0:03b5121a232e 15790 * @pctxt: the schema parser context
pcercuei 0:03b5121a232e 15791 * @type: the simple type definition
pcercuei 0:03b5121a232e 15792 * @value: the default value
pcercuei 0:03b5121a232e 15793 * @node: an optional node (the holder of the value)
pcercuei 0:03b5121a232e 15794 *
pcercuei 0:03b5121a232e 15795 * Schema Component Constraint: Element Default Valid (Immediate)
pcercuei 0:03b5121a232e 15796 * (cos-valid-default)
pcercuei 0:03b5121a232e 15797 * This will be used by the parser only. For the validator there's
pcercuei 0:03b5121a232e 15798 * an other version.
pcercuei 0:03b5121a232e 15799 *
pcercuei 0:03b5121a232e 15800 * Returns 0 if the constraints are satisfied,
pcercuei 0:03b5121a232e 15801 * if not, a positive error code and -1 on internal
pcercuei 0:03b5121a232e 15802 * errors.
pcercuei 0:03b5121a232e 15803 */
pcercuei 0:03b5121a232e 15804 static int
pcercuei 0:03b5121a232e 15805 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 15806 xmlNodePtr node,
pcercuei 0:03b5121a232e 15807 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 15808 const xmlChar *value,
pcercuei 0:03b5121a232e 15809 xmlSchemaValPtr *val)
pcercuei 0:03b5121a232e 15810 {
pcercuei 0:03b5121a232e 15811 int ret = 0;
pcercuei 0:03b5121a232e 15812
pcercuei 0:03b5121a232e 15813 /*
pcercuei 0:03b5121a232e 15814 * cos-valid-default:
pcercuei 0:03b5121a232e 15815 * Schema Component Constraint: Element Default Valid (Immediate)
pcercuei 0:03b5121a232e 15816 * For a string to be a valid default with respect to a type
pcercuei 0:03b5121a232e 15817 * definition the appropriate case among the following must be true:
pcercuei 0:03b5121a232e 15818 */
pcercuei 0:03b5121a232e 15819 if WXS_IS_COMPLEX(type) {
pcercuei 0:03b5121a232e 15820 /*
pcercuei 0:03b5121a232e 15821 * Complex type.
pcercuei 0:03b5121a232e 15822 *
pcercuei 0:03b5121a232e 15823 * SPEC (2.1) "its {content type} must be a simple type definition
pcercuei 0:03b5121a232e 15824 * or mixed."
pcercuei 0:03b5121a232e 15825 * SPEC (2.2.2) "If the {content type} is mixed, then the {content
pcercuei 0:03b5121a232e 15826 * type}'s particle must be `emptiable` as defined by
pcercuei 0:03b5121a232e 15827 * Particle Emptiable ($3.9.6)."
pcercuei 0:03b5121a232e 15828 */
pcercuei 0:03b5121a232e 15829 if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
pcercuei 0:03b5121a232e 15830 ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
pcercuei 0:03b5121a232e 15831 /* NOTE that this covers (2.2.2) as well. */
pcercuei 0:03b5121a232e 15832 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 15833 XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
pcercuei 0:03b5121a232e 15834 WXS_BASIC_CAST type, type->node,
pcercuei 0:03b5121a232e 15835 "For a string to be a valid default, the type definition "
pcercuei 0:03b5121a232e 15836 "must be a simple type or a complex type with mixed content "
pcercuei 0:03b5121a232e 15837 "and a particle emptiable", NULL);
pcercuei 0:03b5121a232e 15838 return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
pcercuei 0:03b5121a232e 15839 }
pcercuei 0:03b5121a232e 15840 }
pcercuei 0:03b5121a232e 15841 /*
pcercuei 0:03b5121a232e 15842 * 1 If the type definition is a simple type definition, then the string
pcercuei 0:03b5121a232e 15843 * must be `valid` with respect to that definition as defined by String
pcercuei 0:03b5121a232e 15844 * Valid ($3.14.4).
pcercuei 0:03b5121a232e 15845 *
pcercuei 0:03b5121a232e 15846 * AND
pcercuei 0:03b5121a232e 15847 *
pcercuei 0:03b5121a232e 15848 * 2.2.1 If the {content type} is a simple type definition, then the
pcercuei 0:03b5121a232e 15849 * string must be `valid` with respect to that simple type definition
pcercuei 0:03b5121a232e 15850 * as defined by String Valid ($3.14.4).
pcercuei 0:03b5121a232e 15851 */
pcercuei 0:03b5121a232e 15852 if (WXS_IS_SIMPLE(type))
pcercuei 0:03b5121a232e 15853 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
pcercuei 0:03b5121a232e 15854 type, value, val, 1, 1, 0);
pcercuei 0:03b5121a232e 15855 else if (WXS_HAS_SIMPLE_CONTENT(type))
pcercuei 0:03b5121a232e 15856 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
pcercuei 0:03b5121a232e 15857 type->contentTypeDef, value, val, 1, 1, 0);
pcercuei 0:03b5121a232e 15858 else
pcercuei 0:03b5121a232e 15859 return (ret);
pcercuei 0:03b5121a232e 15860
pcercuei 0:03b5121a232e 15861 if (ret < 0) {
pcercuei 0:03b5121a232e 15862 PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
pcercuei 0:03b5121a232e 15863 "calling xmlSchemaVCheckCVCSimpleType()");
pcercuei 0:03b5121a232e 15864 }
pcercuei 0:03b5121a232e 15865
pcercuei 0:03b5121a232e 15866 return (ret);
pcercuei 0:03b5121a232e 15867 }
pcercuei 0:03b5121a232e 15868
pcercuei 0:03b5121a232e 15869 /**
pcercuei 0:03b5121a232e 15870 * xmlSchemaCheckCTPropsCorrect:
pcercuei 0:03b5121a232e 15871 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 15872 * @type: the complex type definition
pcercuei 0:03b5121a232e 15873 *
pcercuei 0:03b5121a232e 15874 *.(4.6) Constraints on Complex Type Definition Schema Components
pcercuei 0:03b5121a232e 15875 * Schema Component Constraint:
pcercuei 0:03b5121a232e 15876 * Complex Type Definition Properties Correct (ct-props-correct)
pcercuei 0:03b5121a232e 15877 * STATUS: (seems) complete
pcercuei 0:03b5121a232e 15878 *
pcercuei 0:03b5121a232e 15879 * Returns 0 if the constraints are satisfied, a positive
pcercuei 0:03b5121a232e 15880 * error code if not and -1 if an internal error occured.
pcercuei 0:03b5121a232e 15881 */
pcercuei 0:03b5121a232e 15882 static int
pcercuei 0:03b5121a232e 15883 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 15884 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 15885 {
pcercuei 0:03b5121a232e 15886 /*
pcercuei 0:03b5121a232e 15887 * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
pcercuei 0:03b5121a232e 15888 *
pcercuei 0:03b5121a232e 15889 * SPEC (1) "The values of the properties of a complex type definition must
pcercuei 0:03b5121a232e 15890 * be as described in the property tableau in The Complex Type Definition
pcercuei 0:03b5121a232e 15891 * Schema Component ($3.4.1), modulo the impact of Missing
pcercuei 0:03b5121a232e 15892 * Sub-components ($5.3)."
pcercuei 0:03b5121a232e 15893 */
pcercuei 0:03b5121a232e 15894 if ((type->baseType != NULL) &&
pcercuei 0:03b5121a232e 15895 (WXS_IS_SIMPLE(type->baseType)) &&
pcercuei 0:03b5121a232e 15896 (WXS_IS_EXTENSION(type) == 0)) {
pcercuei 0:03b5121a232e 15897 /*
pcercuei 0:03b5121a232e 15898 * SPEC (2) "If the {base type definition} is a simple type definition,
pcercuei 0:03b5121a232e 15899 * the {derivation method} must be extension."
pcercuei 0:03b5121a232e 15900 */
pcercuei 0:03b5121a232e 15901 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 15902 XML_SCHEMAP_SRC_CT_1,
pcercuei 0:03b5121a232e 15903 NULL, WXS_BASIC_CAST type,
pcercuei 0:03b5121a232e 15904 "If the base type is a simple type, the derivation method must be "
pcercuei 0:03b5121a232e 15905 "'extension'", NULL, NULL);
pcercuei 0:03b5121a232e 15906 return (XML_SCHEMAP_SRC_CT_1);
pcercuei 0:03b5121a232e 15907 }
pcercuei 0:03b5121a232e 15908 /*
pcercuei 0:03b5121a232e 15909 * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
pcercuei 0:03b5121a232e 15910 * definition`. That is, it must be possible to reach the `ur-type
pcercuei 0:03b5121a232e 15911 * definition` by repeatedly following the {base type definition}."
pcercuei 0:03b5121a232e 15912 *
pcercuei 0:03b5121a232e 15913 * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
pcercuei 0:03b5121a232e 15914 */
pcercuei 0:03b5121a232e 15915 /*
pcercuei 0:03b5121a232e 15916 * NOTE that (4) and (5) need the following:
pcercuei 0:03b5121a232e 15917 * - attribute uses need to be already inherited (apply attr. prohibitions)
pcercuei 0:03b5121a232e 15918 * - attribute group references need to be expanded already
pcercuei 0:03b5121a232e 15919 * - simple types need to be typefixed already
pcercuei 0:03b5121a232e 15920 */
pcercuei 0:03b5121a232e 15921 if (type->attrUses &&
pcercuei 0:03b5121a232e 15922 (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
pcercuei 0:03b5121a232e 15923 {
pcercuei 0:03b5121a232e 15924 xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
pcercuei 0:03b5121a232e 15925 xmlSchemaAttributeUsePtr use, tmp;
pcercuei 0:03b5121a232e 15926 int i, j, hasId = 0;
pcercuei 0:03b5121a232e 15927
pcercuei 0:03b5121a232e 15928 for (i = uses->nbItems -1; i >= 0; i--) {
pcercuei 0:03b5121a232e 15929 use = uses->items[i];
pcercuei 0:03b5121a232e 15930
pcercuei 0:03b5121a232e 15931 /*
pcercuei 0:03b5121a232e 15932 * SPEC ct-props-correct
pcercuei 0:03b5121a232e 15933 * (4) "Two distinct attribute declarations in the
pcercuei 0:03b5121a232e 15934 * {attribute uses} must not have identical {name}s and
pcercuei 0:03b5121a232e 15935 * {target namespace}s."
pcercuei 0:03b5121a232e 15936 */
pcercuei 0:03b5121a232e 15937 if (i > 0) {
pcercuei 0:03b5121a232e 15938 for (j = i -1; j >= 0; j--) {
pcercuei 0:03b5121a232e 15939 tmp = uses->items[j];
pcercuei 0:03b5121a232e 15940 if ((WXS_ATTRUSE_DECL_NAME(use) ==
pcercuei 0:03b5121a232e 15941 WXS_ATTRUSE_DECL_NAME(tmp)) &&
pcercuei 0:03b5121a232e 15942 (WXS_ATTRUSE_DECL_TNS(use) ==
pcercuei 0:03b5121a232e 15943 WXS_ATTRUSE_DECL_TNS(tmp)))
pcercuei 0:03b5121a232e 15944 {
pcercuei 0:03b5121a232e 15945 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 15946
pcercuei 0:03b5121a232e 15947 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 15948 XML_SCHEMAP_AG_PROPS_CORRECT,
pcercuei 0:03b5121a232e 15949 NULL, WXS_BASIC_CAST type,
pcercuei 0:03b5121a232e 15950 "Duplicate %s",
pcercuei 0:03b5121a232e 15951 xmlSchemaGetComponentDesignation(&str, use),
pcercuei 0:03b5121a232e 15952 NULL);
pcercuei 0:03b5121a232e 15953 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 15954 /*
pcercuei 0:03b5121a232e 15955 * Remove the duplicate.
pcercuei 0:03b5121a232e 15956 */
pcercuei 0:03b5121a232e 15957 if (xmlSchemaItemListRemove(uses, i) == -1)
pcercuei 0:03b5121a232e 15958 goto exit_failure;
pcercuei 0:03b5121a232e 15959 goto next_use;
pcercuei 0:03b5121a232e 15960 }
pcercuei 0:03b5121a232e 15961 }
pcercuei 0:03b5121a232e 15962 }
pcercuei 0:03b5121a232e 15963 /*
pcercuei 0:03b5121a232e 15964 * SPEC ct-props-correct
pcercuei 0:03b5121a232e 15965 * (5) "Two distinct attribute declarations in the
pcercuei 0:03b5121a232e 15966 * {attribute uses} must not have {type definition}s which
pcercuei 0:03b5121a232e 15967 * are or are derived from ID."
pcercuei 0:03b5121a232e 15968 */
pcercuei 0:03b5121a232e 15969 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
pcercuei 0:03b5121a232e 15970 if (xmlSchemaIsDerivedFromBuiltInType(
pcercuei 0:03b5121a232e 15971 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
pcercuei 0:03b5121a232e 15972 {
pcercuei 0:03b5121a232e 15973 if (hasId) {
pcercuei 0:03b5121a232e 15974 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 15975
pcercuei 0:03b5121a232e 15976 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 15977 XML_SCHEMAP_AG_PROPS_CORRECT,
pcercuei 0:03b5121a232e 15978 NULL, WXS_BASIC_CAST type,
pcercuei 0:03b5121a232e 15979 "There must not exist more than one attribute "
pcercuei 0:03b5121a232e 15980 "declaration of type 'xs:ID' "
pcercuei 0:03b5121a232e 15981 "(or derived from 'xs:ID'). The %s violates this "
pcercuei 0:03b5121a232e 15982 "constraint",
pcercuei 0:03b5121a232e 15983 xmlSchemaGetComponentDesignation(&str, use),
pcercuei 0:03b5121a232e 15984 NULL);
pcercuei 0:03b5121a232e 15985 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 15986 if (xmlSchemaItemListRemove(uses, i) == -1)
pcercuei 0:03b5121a232e 15987 goto exit_failure;
pcercuei 0:03b5121a232e 15988 }
pcercuei 0:03b5121a232e 15989
pcercuei 0:03b5121a232e 15990 hasId = 1;
pcercuei 0:03b5121a232e 15991 }
pcercuei 0:03b5121a232e 15992 }
pcercuei 0:03b5121a232e 15993 next_use: {}
pcercuei 0:03b5121a232e 15994 }
pcercuei 0:03b5121a232e 15995 }
pcercuei 0:03b5121a232e 15996 return (0);
pcercuei 0:03b5121a232e 15997 exit_failure:
pcercuei 0:03b5121a232e 15998 return(-1);
pcercuei 0:03b5121a232e 15999 }
pcercuei 0:03b5121a232e 16000
pcercuei 0:03b5121a232e 16001 static int
pcercuei 0:03b5121a232e 16002 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
pcercuei 0:03b5121a232e 16003 xmlSchemaTypePtr typeB)
pcercuei 0:03b5121a232e 16004 {
pcercuei 0:03b5121a232e 16005 /*
pcercuei 0:03b5121a232e 16006 * TODO: This should implement component-identity
pcercuei 0:03b5121a232e 16007 * in the future.
pcercuei 0:03b5121a232e 16008 */
pcercuei 0:03b5121a232e 16009 if ((typeA == NULL) || (typeB == NULL))
pcercuei 0:03b5121a232e 16010 return (0);
pcercuei 0:03b5121a232e 16011 return (typeA == typeB);
pcercuei 0:03b5121a232e 16012 }
pcercuei 0:03b5121a232e 16013
pcercuei 0:03b5121a232e 16014 /**
pcercuei 0:03b5121a232e 16015 * xmlSchemaCheckCOSCTDerivedOK:
pcercuei 0:03b5121a232e 16016 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 16017 * @type: the to-be derived complex type definition
pcercuei 0:03b5121a232e 16018 * @baseType: the base complex type definition
pcercuei 0:03b5121a232e 16019 * @set: the given set
pcercuei 0:03b5121a232e 16020 *
pcercuei 0:03b5121a232e 16021 * Schema Component Constraint:
pcercuei 0:03b5121a232e 16022 * Type Derivation OK (Complex) (cos-ct-derived-ok)
pcercuei 0:03b5121a232e 16023 *
pcercuei 0:03b5121a232e 16024 * STATUS: completed
pcercuei 0:03b5121a232e 16025 *
pcercuei 0:03b5121a232e 16026 * Returns 0 if the constraints are satisfied, or 1
pcercuei 0:03b5121a232e 16027 * if not.
pcercuei 0:03b5121a232e 16028 */
pcercuei 0:03b5121a232e 16029 static int
pcercuei 0:03b5121a232e 16030 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 16031 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 16032 xmlSchemaTypePtr baseType,
pcercuei 0:03b5121a232e 16033 int set)
pcercuei 0:03b5121a232e 16034 {
pcercuei 0:03b5121a232e 16035 int equal = xmlSchemaAreEqualTypes(type, baseType);
pcercuei 0:03b5121a232e 16036 /* TODO: Error codes. */
pcercuei 0:03b5121a232e 16037 /*
pcercuei 0:03b5121a232e 16038 * SPEC "For a complex type definition (call it D, for derived)
pcercuei 0:03b5121a232e 16039 * to be validly derived from a type definition (call this
pcercuei 0:03b5121a232e 16040 * B, for base) given a subset of {extension, restriction}
pcercuei 0:03b5121a232e 16041 * all of the following must be true:"
pcercuei 0:03b5121a232e 16042 */
pcercuei 0:03b5121a232e 16043 if (! equal) {
pcercuei 0:03b5121a232e 16044 /*
pcercuei 0:03b5121a232e 16045 * SPEC (1) "If B and D are not the same type definition, then the
pcercuei 0:03b5121a232e 16046 * {derivation method} of D must not be in the subset."
pcercuei 0:03b5121a232e 16047 */
pcercuei 0:03b5121a232e 16048 if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
pcercuei 0:03b5121a232e 16049 ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
pcercuei 0:03b5121a232e 16050 return (1);
pcercuei 0:03b5121a232e 16051 } else {
pcercuei 0:03b5121a232e 16052 /*
pcercuei 0:03b5121a232e 16053 * SPEC (2.1) "B and D must be the same type definition."
pcercuei 0:03b5121a232e 16054 */
pcercuei 0:03b5121a232e 16055 return (0);
pcercuei 0:03b5121a232e 16056 }
pcercuei 0:03b5121a232e 16057 /*
pcercuei 0:03b5121a232e 16058 * SPEC (2.2) "B must be D's {base type definition}."
pcercuei 0:03b5121a232e 16059 */
pcercuei 0:03b5121a232e 16060 if (type->baseType == baseType)
pcercuei 0:03b5121a232e 16061 return (0);
pcercuei 0:03b5121a232e 16062 /*
pcercuei 0:03b5121a232e 16063 * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
pcercuei 0:03b5121a232e 16064 * definition`."
pcercuei 0:03b5121a232e 16065 */
pcercuei 0:03b5121a232e 16066 if (WXS_IS_ANYTYPE(type->baseType))
pcercuei 0:03b5121a232e 16067 return (1);
pcercuei 0:03b5121a232e 16068
pcercuei 0:03b5121a232e 16069 if (WXS_IS_COMPLEX(type->baseType)) {
pcercuei 0:03b5121a232e 16070 /*
pcercuei 0:03b5121a232e 16071 * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
pcercuei 0:03b5121a232e 16072 * must be validly derived from B given the subset as defined by this
pcercuei 0:03b5121a232e 16073 * constraint."
pcercuei 0:03b5121a232e 16074 */
pcercuei 0:03b5121a232e 16075 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
pcercuei 0:03b5121a232e 16076 baseType, set));
pcercuei 0:03b5121a232e 16077 } else {
pcercuei 0:03b5121a232e 16078 /*
pcercuei 0:03b5121a232e 16079 * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
pcercuei 0:03b5121a232e 16080 * must be validly derived from B given the subset as defined in Type
pcercuei 0:03b5121a232e 16081 * Derivation OK (Simple) ($3.14.6).
pcercuei 0:03b5121a232e 16082 */
pcercuei 0:03b5121a232e 16083 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
pcercuei 0:03b5121a232e 16084 baseType, set));
pcercuei 0:03b5121a232e 16085 }
pcercuei 0:03b5121a232e 16086 }
pcercuei 0:03b5121a232e 16087
pcercuei 0:03b5121a232e 16088 /**
pcercuei 0:03b5121a232e 16089 * xmlSchemaCheckCOSDerivedOK:
pcercuei 0:03b5121a232e 16090 * @type: the derived simple type definition
pcercuei 0:03b5121a232e 16091 * @baseType: the base type definition
pcercuei 0:03b5121a232e 16092 *
pcercuei 0:03b5121a232e 16093 * Calls:
pcercuei 0:03b5121a232e 16094 * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
pcercuei 0:03b5121a232e 16095 *
pcercuei 0:03b5121a232e 16096 * Checks wheter @type can be validly derived from @baseType.
pcercuei 0:03b5121a232e 16097 *
pcercuei 0:03b5121a232e 16098 * Returns 0 on success, an positive error code otherwise.
pcercuei 0:03b5121a232e 16099 */
pcercuei 0:03b5121a232e 16100 static int
pcercuei 0:03b5121a232e 16101 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 16102 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 16103 xmlSchemaTypePtr baseType,
pcercuei 0:03b5121a232e 16104 int set)
pcercuei 0:03b5121a232e 16105 {
pcercuei 0:03b5121a232e 16106 if (WXS_IS_SIMPLE(type))
pcercuei 0:03b5121a232e 16107 return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
pcercuei 0:03b5121a232e 16108 else
pcercuei 0:03b5121a232e 16109 return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
pcercuei 0:03b5121a232e 16110 }
pcercuei 0:03b5121a232e 16111
pcercuei 0:03b5121a232e 16112 /**
pcercuei 0:03b5121a232e 16113 * xmlSchemaCheckCOSCTExtends:
pcercuei 0:03b5121a232e 16114 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 16115 * @type: the complex type definition
pcercuei 0:03b5121a232e 16116 *
pcercuei 0:03b5121a232e 16117 * (3.4.6) Constraints on Complex Type Definition Schema Components
pcercuei 0:03b5121a232e 16118 * Schema Component Constraint:
pcercuei 0:03b5121a232e 16119 * Derivation Valid (Extension) (cos-ct-extends)
pcercuei 0:03b5121a232e 16120 *
pcercuei 0:03b5121a232e 16121 * STATUS:
pcercuei 0:03b5121a232e 16122 * missing:
pcercuei 0:03b5121a232e 16123 * (1.5)
pcercuei 0:03b5121a232e 16124 * (1.4.3.2.2.2) "Particle Valid (Extension)"
pcercuei 0:03b5121a232e 16125 *
pcercuei 0:03b5121a232e 16126 * Returns 0 if the constraints are satisfied, a positive
pcercuei 0:03b5121a232e 16127 * error code if not and -1 if an internal error occured.
pcercuei 0:03b5121a232e 16128 */
pcercuei 0:03b5121a232e 16129 static int
pcercuei 0:03b5121a232e 16130 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 16131 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 16132 {
pcercuei 0:03b5121a232e 16133 xmlSchemaTypePtr base = type->baseType;
pcercuei 0:03b5121a232e 16134 /*
pcercuei 0:03b5121a232e 16135 * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
pcercuei 0:03b5121a232e 16136 * temporarily only.
pcercuei 0:03b5121a232e 16137 */
pcercuei 0:03b5121a232e 16138 /*
pcercuei 0:03b5121a232e 16139 * SPEC (1) "If the {base type definition} is a complex type definition,
pcercuei 0:03b5121a232e 16140 * then all of the following must be true:"
pcercuei 0:03b5121a232e 16141 */
pcercuei 0:03b5121a232e 16142 if (WXS_IS_COMPLEX(base)) {
pcercuei 0:03b5121a232e 16143 /*
pcercuei 0:03b5121a232e 16144 * SPEC (1.1) "The {final} of the {base type definition} must not
pcercuei 0:03b5121a232e 16145 * contain extension."
pcercuei 0:03b5121a232e 16146 */
pcercuei 0:03b5121a232e 16147 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
pcercuei 0:03b5121a232e 16148 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16149 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
pcercuei 0:03b5121a232e 16150 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16151 "The 'final' of the base type definition "
pcercuei 0:03b5121a232e 16152 "contains 'extension'", NULL);
pcercuei 0:03b5121a232e 16153 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
pcercuei 0:03b5121a232e 16154 }
pcercuei 0:03b5121a232e 16155
pcercuei 0:03b5121a232e 16156 /*
pcercuei 0:03b5121a232e 16157 * ATTENTION: The constrains (1.2) and (1.3) are not applied,
pcercuei 0:03b5121a232e 16158 * since they are automatically satisfied through the
pcercuei 0:03b5121a232e 16159 * inheriting mechanism.
pcercuei 0:03b5121a232e 16160 * Note that even if redefining components, the inheriting mechanism
pcercuei 0:03b5121a232e 16161 * is used.
pcercuei 0:03b5121a232e 16162 */
pcercuei 0:03b5121a232e 16163 #if 0
pcercuei 0:03b5121a232e 16164 /*
pcercuei 0:03b5121a232e 16165 * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
pcercuei 0:03b5121a232e 16166 * uses}
pcercuei 0:03b5121a232e 16167 * of the complex type definition itself, that is, for every attribute
pcercuei 0:03b5121a232e 16168 * use in the {attribute uses} of the {base type definition}, there
pcercuei 0:03b5121a232e 16169 * must be an attribute use in the {attribute uses} of the complex
pcercuei 0:03b5121a232e 16170 * type definition itself whose {attribute declaration} has the same
pcercuei 0:03b5121a232e 16171 * {name}, {target namespace} and {type definition} as its attribute
pcercuei 0:03b5121a232e 16172 * declaration"
pcercuei 0:03b5121a232e 16173 */
pcercuei 0:03b5121a232e 16174 if (base->attrUses != NULL) {
pcercuei 0:03b5121a232e 16175 int i, j, found;
pcercuei 0:03b5121a232e 16176 xmlSchemaAttributeUsePtr use, buse;
pcercuei 0:03b5121a232e 16177
pcercuei 0:03b5121a232e 16178 for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
pcercuei 0:03b5121a232e 16179 buse = (WXS_LIST_CAST base->attrUses)->items[i];
pcercuei 0:03b5121a232e 16180 found = 0;
pcercuei 0:03b5121a232e 16181 if (type->attrUses != NULL) {
pcercuei 0:03b5121a232e 16182 use = (WXS_LIST_CAST type->attrUses)->items[j];
pcercuei 0:03b5121a232e 16183 for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
pcercuei 0:03b5121a232e 16184 {
pcercuei 0:03b5121a232e 16185 if ((WXS_ATTRUSE_DECL_NAME(use) ==
pcercuei 0:03b5121a232e 16186 WXS_ATTRUSE_DECL_NAME(buse)) &&
pcercuei 0:03b5121a232e 16187 (WXS_ATTRUSE_DECL_TNS(use) ==
pcercuei 0:03b5121a232e 16188 WXS_ATTRUSE_DECL_TNS(buse)) &&
pcercuei 0:03b5121a232e 16189 (WXS_ATTRUSE_TYPEDEF(use) ==
pcercuei 0:03b5121a232e 16190 WXS_ATTRUSE_TYPEDEF(buse))
pcercuei 0:03b5121a232e 16191 {
pcercuei 0:03b5121a232e 16192 found = 1;
pcercuei 0:03b5121a232e 16193 break;
pcercuei 0:03b5121a232e 16194 }
pcercuei 0:03b5121a232e 16195 }
pcercuei 0:03b5121a232e 16196 }
pcercuei 0:03b5121a232e 16197 if (! found) {
pcercuei 0:03b5121a232e 16198 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 16199
pcercuei 0:03b5121a232e 16200 xmlSchemaCustomErr(ACTXT_CAST ctxt,
pcercuei 0:03b5121a232e 16201 XML_SCHEMAP_COS_CT_EXTENDS_1_2,
pcercuei 0:03b5121a232e 16202 NULL, WXS_BASIC_CAST type,
pcercuei 0:03b5121a232e 16203 /*
pcercuei 0:03b5121a232e 16204 * TODO: The report does not indicate that also the
pcercuei 0:03b5121a232e 16205 * type needs to be the same.
pcercuei 0:03b5121a232e 16206 */
pcercuei 0:03b5121a232e 16207 "This type is missing a matching correspondent "
pcercuei 0:03b5121a232e 16208 "for its {base type}'s %s in its {attribute uses}",
pcercuei 0:03b5121a232e 16209 xmlSchemaGetComponentDesignation(&str,
pcercuei 0:03b5121a232e 16210 buse->children),
pcercuei 0:03b5121a232e 16211 NULL);
pcercuei 0:03b5121a232e 16212 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 16213 }
pcercuei 0:03b5121a232e 16214 }
pcercuei 0:03b5121a232e 16215 }
pcercuei 0:03b5121a232e 16216 /*
pcercuei 0:03b5121a232e 16217 * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
pcercuei 0:03b5121a232e 16218 * definition must also have one, and the base type definition's
pcercuei 0:03b5121a232e 16219 * {attribute wildcard}'s {namespace constraint} must be a subset
pcercuei 0:03b5121a232e 16220 * of the complex type definition's {attribute wildcard}'s {namespace
pcercuei 0:03b5121a232e 16221 * constraint}, as defined by Wildcard Subset ($3.10.6)."
pcercuei 0:03b5121a232e 16222 */
pcercuei 0:03b5121a232e 16223
pcercuei 0:03b5121a232e 16224 /*
pcercuei 0:03b5121a232e 16225 * MAYBE TODO: Enable if ever needed. But this will be needed only
pcercuei 0:03b5121a232e 16226 * if created the type via a schema construction API.
pcercuei 0:03b5121a232e 16227 */
pcercuei 0:03b5121a232e 16228 if (base->attributeWildcard != NULL) {
pcercuei 0:03b5121a232e 16229 if (type->attributeWilcard == NULL) {
pcercuei 0:03b5121a232e 16230 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 16231
pcercuei 0:03b5121a232e 16232 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 16233 XML_SCHEMAP_COS_CT_EXTENDS_1_3,
pcercuei 0:03b5121a232e 16234 NULL, type,
pcercuei 0:03b5121a232e 16235 "The base %s has an attribute wildcard, "
pcercuei 0:03b5121a232e 16236 "but this type is missing an attribute wildcard",
pcercuei 0:03b5121a232e 16237 xmlSchemaGetComponentDesignation(&str, base));
pcercuei 0:03b5121a232e 16238 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 16239
pcercuei 0:03b5121a232e 16240 } else if (xmlSchemaCheckCOSNSSubset(
pcercuei 0:03b5121a232e 16241 base->attributeWildcard, type->attributeWildcard))
pcercuei 0:03b5121a232e 16242 {
pcercuei 0:03b5121a232e 16243 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 16244
pcercuei 0:03b5121a232e 16245 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 16246 XML_SCHEMAP_COS_CT_EXTENDS_1_3,
pcercuei 0:03b5121a232e 16247 NULL, type,
pcercuei 0:03b5121a232e 16248 "The attribute wildcard is not a valid "
pcercuei 0:03b5121a232e 16249 "superset of the one in the base %s",
pcercuei 0:03b5121a232e 16250 xmlSchemaGetComponentDesignation(&str, base));
pcercuei 0:03b5121a232e 16251 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 16252 }
pcercuei 0:03b5121a232e 16253 }
pcercuei 0:03b5121a232e 16254 #endif
pcercuei 0:03b5121a232e 16255 /*
pcercuei 0:03b5121a232e 16256 * SPEC (1.4) "One of the following must be true:"
pcercuei 0:03b5121a232e 16257 */
pcercuei 0:03b5121a232e 16258 if ((type->contentTypeDef != NULL) &&
pcercuei 0:03b5121a232e 16259 (type->contentTypeDef == base->contentTypeDef)) {
pcercuei 0:03b5121a232e 16260 /*
pcercuei 0:03b5121a232e 16261 * SPEC (1.4.1) "The {content type} of the {base type definition}
pcercuei 0:03b5121a232e 16262 * and the {content type} of the complex type definition itself
pcercuei 0:03b5121a232e 16263 * must be the same simple type definition"
pcercuei 0:03b5121a232e 16264 * PASS
pcercuei 0:03b5121a232e 16265 */
pcercuei 0:03b5121a232e 16266 } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
pcercuei 0:03b5121a232e 16267 (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
pcercuei 0:03b5121a232e 16268 /*
pcercuei 0:03b5121a232e 16269 * SPEC (1.4.2) "The {content type} of both the {base type
pcercuei 0:03b5121a232e 16270 * definition} and the complex type definition itself must
pcercuei 0:03b5121a232e 16271 * be empty."
pcercuei 0:03b5121a232e 16272 * PASS
pcercuei 0:03b5121a232e 16273 */
pcercuei 0:03b5121a232e 16274 } else {
pcercuei 0:03b5121a232e 16275 /*
pcercuei 0:03b5121a232e 16276 * SPEC (1.4.3) "All of the following must be true:"
pcercuei 0:03b5121a232e 16277 */
pcercuei 0:03b5121a232e 16278 if (type->subtypes == NULL) {
pcercuei 0:03b5121a232e 16279 /*
pcercuei 0:03b5121a232e 16280 * SPEC 1.4.3.1 The {content type} of the complex type
pcercuei 0:03b5121a232e 16281 * definition itself must specify a particle.
pcercuei 0:03b5121a232e 16282 */
pcercuei 0:03b5121a232e 16283 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16284 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
pcercuei 0:03b5121a232e 16285 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16286 "The content type must specify a particle", NULL);
pcercuei 0:03b5121a232e 16287 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
pcercuei 0:03b5121a232e 16288 }
pcercuei 0:03b5121a232e 16289 /*
pcercuei 0:03b5121a232e 16290 * SPEC (1.4.3.2) "One of the following must be true:"
pcercuei 0:03b5121a232e 16291 */
pcercuei 0:03b5121a232e 16292 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
pcercuei 0:03b5121a232e 16293 /*
pcercuei 0:03b5121a232e 16294 * SPEC (1.4.3.2.1) "The {content type} of the {base type
pcercuei 0:03b5121a232e 16295 * definition} must be empty.
pcercuei 0:03b5121a232e 16296 * PASS
pcercuei 0:03b5121a232e 16297 */
pcercuei 0:03b5121a232e 16298 } else {
pcercuei 0:03b5121a232e 16299 /*
pcercuei 0:03b5121a232e 16300 * SPEC (1.4.3.2.2) "All of the following must be true:"
pcercuei 0:03b5121a232e 16301 */
pcercuei 0:03b5121a232e 16302 if ((type->contentType != base->contentType) ||
pcercuei 0:03b5121a232e 16303 ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
pcercuei 0:03b5121a232e 16304 (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
pcercuei 0:03b5121a232e 16305 /*
pcercuei 0:03b5121a232e 16306 * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
pcercuei 0:03b5121a232e 16307 * or both must be element-only."
pcercuei 0:03b5121a232e 16308 */
pcercuei 0:03b5121a232e 16309 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16310 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
pcercuei 0:03b5121a232e 16311 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16312 "The content type of both, the type and its base "
pcercuei 0:03b5121a232e 16313 "type, must either 'mixed' or 'element-only'", NULL);
pcercuei 0:03b5121a232e 16314 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
pcercuei 0:03b5121a232e 16315 }
pcercuei 0:03b5121a232e 16316 /*
pcercuei 0:03b5121a232e 16317 * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
pcercuei 0:03b5121a232e 16318 * complex type definition must be a `valid extension`
pcercuei 0:03b5121a232e 16319 * of the {base type definition}'s particle, as defined
pcercuei 0:03b5121a232e 16320 * in Particle Valid (Extension) ($3.9.6)."
pcercuei 0:03b5121a232e 16321 *
pcercuei 0:03b5121a232e 16322 * NOTE that we won't check "Particle Valid (Extension)",
pcercuei 0:03b5121a232e 16323 * since it is ensured by the derivation process in
pcercuei 0:03b5121a232e 16324 * xmlSchemaTypeFixup(). We need to implement this when heading
pcercuei 0:03b5121a232e 16325 * for a construction API
pcercuei 0:03b5121a232e 16326 * TODO: !! This is needed to be checked if redefining a type !!
pcercuei 0:03b5121a232e 16327 */
pcercuei 0:03b5121a232e 16328 }
pcercuei 0:03b5121a232e 16329 /*
pcercuei 0:03b5121a232e 16330 * URGENT TODO (1.5)
pcercuei 0:03b5121a232e 16331 */
pcercuei 0:03b5121a232e 16332 }
pcercuei 0:03b5121a232e 16333 } else {
pcercuei 0:03b5121a232e 16334 /*
pcercuei 0:03b5121a232e 16335 * SPEC (2) "If the {base type definition} is a simple type definition,
pcercuei 0:03b5121a232e 16336 * then all of the following must be true:"
pcercuei 0:03b5121a232e 16337 */
pcercuei 0:03b5121a232e 16338 if (type->contentTypeDef != base) {
pcercuei 0:03b5121a232e 16339 /*
pcercuei 0:03b5121a232e 16340 * SPEC (2.1) "The {content type} must be the same simple type
pcercuei 0:03b5121a232e 16341 * definition."
pcercuei 0:03b5121a232e 16342 */
pcercuei 0:03b5121a232e 16343 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16344 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
pcercuei 0:03b5121a232e 16345 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16346 "The content type must be the simple base type", NULL);
pcercuei 0:03b5121a232e 16347 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
pcercuei 0:03b5121a232e 16348 }
pcercuei 0:03b5121a232e 16349 if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
pcercuei 0:03b5121a232e 16350 /*
pcercuei 0:03b5121a232e 16351 * SPEC (2.2) "The {final} of the {base type definition} must not
pcercuei 0:03b5121a232e 16352 * contain extension"
pcercuei 0:03b5121a232e 16353 * NOTE that this is the same as (1.1).
pcercuei 0:03b5121a232e 16354 */
pcercuei 0:03b5121a232e 16355 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16356 XML_SCHEMAP_COS_CT_EXTENDS_1_1,
pcercuei 0:03b5121a232e 16357 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16358 "The 'final' of the base type definition "
pcercuei 0:03b5121a232e 16359 "contains 'extension'", NULL);
pcercuei 0:03b5121a232e 16360 return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
pcercuei 0:03b5121a232e 16361 }
pcercuei 0:03b5121a232e 16362 }
pcercuei 0:03b5121a232e 16363 return (0);
pcercuei 0:03b5121a232e 16364 }
pcercuei 0:03b5121a232e 16365
pcercuei 0:03b5121a232e 16366 /**
pcercuei 0:03b5121a232e 16367 * xmlSchemaCheckDerivationOKRestriction:
pcercuei 0:03b5121a232e 16368 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 16369 * @type: the complex type definition
pcercuei 0:03b5121a232e 16370 *
pcercuei 0:03b5121a232e 16371 * (3.4.6) Constraints on Complex Type Definition Schema Components
pcercuei 0:03b5121a232e 16372 * Schema Component Constraint:
pcercuei 0:03b5121a232e 16373 * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
pcercuei 0:03b5121a232e 16374 *
pcercuei 0:03b5121a232e 16375 * STATUS:
pcercuei 0:03b5121a232e 16376 * missing:
pcercuei 0:03b5121a232e 16377 * (5.4.2) ???
pcercuei 0:03b5121a232e 16378 *
pcercuei 0:03b5121a232e 16379 * ATTENTION:
pcercuei 0:03b5121a232e 16380 * In XML Schema 1.1 this will be:
pcercuei 0:03b5121a232e 16381 * Validation Rule: Checking complex type subsumption
pcercuei 0:03b5121a232e 16382 *
pcercuei 0:03b5121a232e 16383 * Returns 0 if the constraints are satisfied, a positive
pcercuei 0:03b5121a232e 16384 * error code if not and -1 if an internal error occured.
pcercuei 0:03b5121a232e 16385 */
pcercuei 0:03b5121a232e 16386 static int
pcercuei 0:03b5121a232e 16387 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 16388 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 16389 {
pcercuei 0:03b5121a232e 16390 xmlSchemaTypePtr base;
pcercuei 0:03b5121a232e 16391
pcercuei 0:03b5121a232e 16392 /*
pcercuei 0:03b5121a232e 16393 * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
pcercuei 0:03b5121a232e 16394 * temporarily only.
pcercuei 0:03b5121a232e 16395 */
pcercuei 0:03b5121a232e 16396 base = type->baseType;
pcercuei 0:03b5121a232e 16397 if (! WXS_IS_COMPLEX(base)) {
pcercuei 0:03b5121a232e 16398 xmlSchemaCustomErr(ACTXT_CAST ctxt,
pcercuei 0:03b5121a232e 16399 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
pcercuei 0:03b5121a232e 16400 type->node, WXS_BASIC_CAST type,
pcercuei 0:03b5121a232e 16401 "The base type must be a complex type", NULL, NULL);
pcercuei 0:03b5121a232e 16402 return(ctxt->err);
pcercuei 0:03b5121a232e 16403 }
pcercuei 0:03b5121a232e 16404 if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
pcercuei 0:03b5121a232e 16405 /*
pcercuei 0:03b5121a232e 16406 * SPEC (1) "The {base type definition} must be a complex type
pcercuei 0:03b5121a232e 16407 * definition whose {final} does not contain restriction."
pcercuei 0:03b5121a232e 16408 */
pcercuei 0:03b5121a232e 16409 xmlSchemaCustomErr(ACTXT_CAST ctxt,
pcercuei 0:03b5121a232e 16410 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
pcercuei 0:03b5121a232e 16411 type->node, WXS_BASIC_CAST type,
pcercuei 0:03b5121a232e 16412 "The 'final' of the base type definition "
pcercuei 0:03b5121a232e 16413 "contains 'restriction'", NULL, NULL);
pcercuei 0:03b5121a232e 16414 return (ctxt->err);
pcercuei 0:03b5121a232e 16415 }
pcercuei 0:03b5121a232e 16416 /*
pcercuei 0:03b5121a232e 16417 * SPEC (2), (3) and (4)
pcercuei 0:03b5121a232e 16418 * Those are handled in a separate function, since the
pcercuei 0:03b5121a232e 16419 * same constraints are needed for redefinition of
pcercuei 0:03b5121a232e 16420 * attribute groups as well.
pcercuei 0:03b5121a232e 16421 */
pcercuei 0:03b5121a232e 16422 if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
pcercuei 0:03b5121a232e 16423 XML_SCHEMA_ACTION_DERIVE,
pcercuei 0:03b5121a232e 16424 WXS_BASIC_CAST type, WXS_BASIC_CAST base,
pcercuei 0:03b5121a232e 16425 type->attrUses, base->attrUses,
pcercuei 0:03b5121a232e 16426 type->attributeWildcard,
pcercuei 0:03b5121a232e 16427 base->attributeWildcard) == -1)
pcercuei 0:03b5121a232e 16428 {
pcercuei 0:03b5121a232e 16429 return(-1);
pcercuei 0:03b5121a232e 16430 }
pcercuei 0:03b5121a232e 16431 /*
pcercuei 0:03b5121a232e 16432 * SPEC (5) "One of the following must be true:"
pcercuei 0:03b5121a232e 16433 */
pcercuei 0:03b5121a232e 16434 if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
pcercuei 0:03b5121a232e 16435 /*
pcercuei 0:03b5121a232e 16436 * SPEC (5.1) "The {base type definition} must be the
pcercuei 0:03b5121a232e 16437 * `ur-type definition`."
pcercuei 0:03b5121a232e 16438 * PASS
pcercuei 0:03b5121a232e 16439 */
pcercuei 0:03b5121a232e 16440 } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
pcercuei 0:03b5121a232e 16441 (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
pcercuei 0:03b5121a232e 16442 /*
pcercuei 0:03b5121a232e 16443 * SPEC (5.2.1) "The {content type} of the complex type definition
pcercuei 0:03b5121a232e 16444 * must be a simple type definition"
pcercuei 0:03b5121a232e 16445 *
pcercuei 0:03b5121a232e 16446 * SPEC (5.2.2) "One of the following must be true:"
pcercuei 0:03b5121a232e 16447 */
pcercuei 0:03b5121a232e 16448 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
pcercuei 0:03b5121a232e 16449 (base->contentType == XML_SCHEMA_CONTENT_BASIC))
pcercuei 0:03b5121a232e 16450 {
pcercuei 0:03b5121a232e 16451 int err;
pcercuei 0:03b5121a232e 16452 /*
pcercuei 0:03b5121a232e 16453 * SPEC (5.2.2.1) "The {content type} of the {base type
pcercuei 0:03b5121a232e 16454 * definition} must be a simple type definition from which
pcercuei 0:03b5121a232e 16455 * the {content type} is validly derived given the empty
pcercuei 0:03b5121a232e 16456 * set as defined in Type Derivation OK (Simple) ($3.14.6)."
pcercuei 0:03b5121a232e 16457 *
pcercuei 0:03b5121a232e 16458 * ATTENTION TODO: This seems not needed if the type implicitely
pcercuei 0:03b5121a232e 16459 * derived from the base type.
pcercuei 0:03b5121a232e 16460 *
pcercuei 0:03b5121a232e 16461 */
pcercuei 0:03b5121a232e 16462 err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
pcercuei 0:03b5121a232e 16463 type->contentTypeDef, base->contentTypeDef, 0);
pcercuei 0:03b5121a232e 16464 if (err != 0) {
pcercuei 0:03b5121a232e 16465 xmlChar *strA = NULL, *strB = NULL;
pcercuei 0:03b5121a232e 16466
pcercuei 0:03b5121a232e 16467 if (err == -1)
pcercuei 0:03b5121a232e 16468 return(-1);
pcercuei 0:03b5121a232e 16469 xmlSchemaCustomErr(ACTXT_CAST ctxt,
pcercuei 0:03b5121a232e 16470 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
pcercuei 0:03b5121a232e 16471 NULL, WXS_BASIC_CAST type,
pcercuei 0:03b5121a232e 16472 "The {content type} %s is not validly derived from the "
pcercuei 0:03b5121a232e 16473 "base type's {content type} %s",
pcercuei 0:03b5121a232e 16474 xmlSchemaGetComponentDesignation(&strA,
pcercuei 0:03b5121a232e 16475 type->contentTypeDef),
pcercuei 0:03b5121a232e 16476 xmlSchemaGetComponentDesignation(&strB,
pcercuei 0:03b5121a232e 16477 base->contentTypeDef));
pcercuei 0:03b5121a232e 16478 FREE_AND_NULL(strA);
pcercuei 0:03b5121a232e 16479 FREE_AND_NULL(strB);
pcercuei 0:03b5121a232e 16480 return(ctxt->err);
pcercuei 0:03b5121a232e 16481 }
pcercuei 0:03b5121a232e 16482 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
pcercuei 0:03b5121a232e 16483 (xmlSchemaIsParticleEmptiable(
pcercuei 0:03b5121a232e 16484 (xmlSchemaParticlePtr) base->subtypes))) {
pcercuei 0:03b5121a232e 16485 /*
pcercuei 0:03b5121a232e 16486 * SPEC (5.2.2.2) "The {base type definition} must be mixed
pcercuei 0:03b5121a232e 16487 * and have a particle which is `emptiable` as defined in
pcercuei 0:03b5121a232e 16488 * Particle Emptiable ($3.9.6)."
pcercuei 0:03b5121a232e 16489 * PASS
pcercuei 0:03b5121a232e 16490 */
pcercuei 0:03b5121a232e 16491 } else {
pcercuei 0:03b5121a232e 16492 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16493 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
pcercuei 0:03b5121a232e 16494 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16495 "The content type of the base type must be either "
pcercuei 0:03b5121a232e 16496 "a simple type or 'mixed' and an emptiable particle", NULL);
pcercuei 0:03b5121a232e 16497 return (ctxt->err);
pcercuei 0:03b5121a232e 16498 }
pcercuei 0:03b5121a232e 16499 } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
pcercuei 0:03b5121a232e 16500 /*
pcercuei 0:03b5121a232e 16501 * SPEC (5.3.1) "The {content type} of the complex type itself must
pcercuei 0:03b5121a232e 16502 * be empty"
pcercuei 0:03b5121a232e 16503 */
pcercuei 0:03b5121a232e 16504 if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
pcercuei 0:03b5121a232e 16505 /*
pcercuei 0:03b5121a232e 16506 * SPEC (5.3.2.1) "The {content type} of the {base type
pcercuei 0:03b5121a232e 16507 * definition} must also be empty."
pcercuei 0:03b5121a232e 16508 * PASS
pcercuei 0:03b5121a232e 16509 */
pcercuei 0:03b5121a232e 16510 } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
pcercuei 0:03b5121a232e 16511 (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
pcercuei 0:03b5121a232e 16512 xmlSchemaIsParticleEmptiable(
pcercuei 0:03b5121a232e 16513 (xmlSchemaParticlePtr) base->subtypes)) {
pcercuei 0:03b5121a232e 16514 /*
pcercuei 0:03b5121a232e 16515 * SPEC (5.3.2.2) "The {content type} of the {base type
pcercuei 0:03b5121a232e 16516 * definition} must be elementOnly or mixed and have a particle
pcercuei 0:03b5121a232e 16517 * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
pcercuei 0:03b5121a232e 16518 * PASS
pcercuei 0:03b5121a232e 16519 */
pcercuei 0:03b5121a232e 16520 } else {
pcercuei 0:03b5121a232e 16521 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16522 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
pcercuei 0:03b5121a232e 16523 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16524 "The content type of the base type must be either "
pcercuei 0:03b5121a232e 16525 "empty or 'mixed' (or 'elements-only') and an emptiable "
pcercuei 0:03b5121a232e 16526 "particle", NULL);
pcercuei 0:03b5121a232e 16527 return (ctxt->err);
pcercuei 0:03b5121a232e 16528 }
pcercuei 0:03b5121a232e 16529 } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
pcercuei 0:03b5121a232e 16530 WXS_HAS_MIXED_CONTENT(type)) {
pcercuei 0:03b5121a232e 16531 /*
pcercuei 0:03b5121a232e 16532 * SPEC (5.4.1.1) "The {content type} of the complex type definition
pcercuei 0:03b5121a232e 16533 * itself must be element-only"
pcercuei 0:03b5121a232e 16534 */
pcercuei 0:03b5121a232e 16535 if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
pcercuei 0:03b5121a232e 16536 /*
pcercuei 0:03b5121a232e 16537 * SPEC (5.4.1.2) "The {content type} of the complex type
pcercuei 0:03b5121a232e 16538 * definition itself and of the {base type definition} must be
pcercuei 0:03b5121a232e 16539 * mixed"
pcercuei 0:03b5121a232e 16540 */
pcercuei 0:03b5121a232e 16541 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16542 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
pcercuei 0:03b5121a232e 16543 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16544 "If the content type is 'mixed', then the content type of the "
pcercuei 0:03b5121a232e 16545 "base type must also be 'mixed'", NULL);
pcercuei 0:03b5121a232e 16546 return (ctxt->err);
pcercuei 0:03b5121a232e 16547 }
pcercuei 0:03b5121a232e 16548 /*
pcercuei 0:03b5121a232e 16549 * SPEC (5.4.2) "The particle of the complex type definition itself
pcercuei 0:03b5121a232e 16550 * must be a `valid restriction` of the particle of the {content
pcercuei 0:03b5121a232e 16551 * type} of the {base type definition} as defined in Particle Valid
pcercuei 0:03b5121a232e 16552 * (Restriction) ($3.9.6).
pcercuei 0:03b5121a232e 16553 *
pcercuei 0:03b5121a232e 16554 * URGENT TODO: (5.4.2)
pcercuei 0:03b5121a232e 16555 */
pcercuei 0:03b5121a232e 16556 } else {
pcercuei 0:03b5121a232e 16557 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16558 XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
pcercuei 0:03b5121a232e 16559 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16560 "The type is not a valid restriction of its base type", NULL);
pcercuei 0:03b5121a232e 16561 return (ctxt->err);
pcercuei 0:03b5121a232e 16562 }
pcercuei 0:03b5121a232e 16563 return (0);
pcercuei 0:03b5121a232e 16564 }
pcercuei 0:03b5121a232e 16565
pcercuei 0:03b5121a232e 16566 /**
pcercuei 0:03b5121a232e 16567 * xmlSchemaCheckCTComponent:
pcercuei 0:03b5121a232e 16568 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 16569 * @type: the complex type definition
pcercuei 0:03b5121a232e 16570 *
pcercuei 0:03b5121a232e 16571 * (3.4.6) Constraints on Complex Type Definition Schema Components
pcercuei 0:03b5121a232e 16572 *
pcercuei 0:03b5121a232e 16573 * Returns 0 if the constraints are satisfied, a positive
pcercuei 0:03b5121a232e 16574 * error code if not and -1 if an internal error occured.
pcercuei 0:03b5121a232e 16575 */
pcercuei 0:03b5121a232e 16576 static int
pcercuei 0:03b5121a232e 16577 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 16578 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 16579 {
pcercuei 0:03b5121a232e 16580 int ret;
pcercuei 0:03b5121a232e 16581 /*
pcercuei 0:03b5121a232e 16582 * Complex Type Definition Properties Correct
pcercuei 0:03b5121a232e 16583 */
pcercuei 0:03b5121a232e 16584 ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
pcercuei 0:03b5121a232e 16585 if (ret != 0)
pcercuei 0:03b5121a232e 16586 return (ret);
pcercuei 0:03b5121a232e 16587 if (WXS_IS_EXTENSION(type))
pcercuei 0:03b5121a232e 16588 ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
pcercuei 0:03b5121a232e 16589 else
pcercuei 0:03b5121a232e 16590 ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
pcercuei 0:03b5121a232e 16591 return (ret);
pcercuei 0:03b5121a232e 16592 }
pcercuei 0:03b5121a232e 16593
pcercuei 0:03b5121a232e 16594 /**
pcercuei 0:03b5121a232e 16595 * xmlSchemaCheckSRCCT:
pcercuei 0:03b5121a232e 16596 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 16597 * @type: the complex type definition
pcercuei 0:03b5121a232e 16598 *
pcercuei 0:03b5121a232e 16599 * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
pcercuei 0:03b5121a232e 16600 * Schema Representation Constraint:
pcercuei 0:03b5121a232e 16601 * Complex Type Definition Representation OK (src-ct)
pcercuei 0:03b5121a232e 16602 *
pcercuei 0:03b5121a232e 16603 * Returns 0 if the constraints are satisfied, a positive
pcercuei 0:03b5121a232e 16604 * error code if not and -1 if an internal error occured.
pcercuei 0:03b5121a232e 16605 */
pcercuei 0:03b5121a232e 16606 static int
pcercuei 0:03b5121a232e 16607 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 16608 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 16609 {
pcercuei 0:03b5121a232e 16610 xmlSchemaTypePtr base;
pcercuei 0:03b5121a232e 16611 int ret = 0;
pcercuei 0:03b5121a232e 16612
pcercuei 0:03b5121a232e 16613 /*
pcercuei 0:03b5121a232e 16614 * TODO: Adjust the error codes here, as I used
pcercuei 0:03b5121a232e 16615 * XML_SCHEMAP_SRC_CT_1 only yet.
pcercuei 0:03b5121a232e 16616 */
pcercuei 0:03b5121a232e 16617 base = type->baseType;
pcercuei 0:03b5121a232e 16618 if (! WXS_HAS_SIMPLE_CONTENT(type)) {
pcercuei 0:03b5121a232e 16619 /*
pcercuei 0:03b5121a232e 16620 * 1 If the <complexContent> alternative is chosen, the type definition
pcercuei 0:03b5121a232e 16621 * `resolved` to by the `actual value` of the base [attribute]
pcercuei 0:03b5121a232e 16622 * must be a complex type definition;
pcercuei 0:03b5121a232e 16623 */
pcercuei 0:03b5121a232e 16624 if (! WXS_IS_COMPLEX(base)) {
pcercuei 0:03b5121a232e 16625 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 16626 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16627 XML_SCHEMAP_SRC_CT_1,
pcercuei 0:03b5121a232e 16628 WXS_BASIC_CAST type, type->node,
pcercuei 0:03b5121a232e 16629 "If using <complexContent>, the base type is expected to be "
pcercuei 0:03b5121a232e 16630 "a complex type. The base type '%s' is a simple type",
pcercuei 0:03b5121a232e 16631 xmlSchemaFormatQName(&str, base->targetNamespace,
pcercuei 0:03b5121a232e 16632 base->name));
pcercuei 0:03b5121a232e 16633 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 16634 return (XML_SCHEMAP_SRC_CT_1);
pcercuei 0:03b5121a232e 16635 }
pcercuei 0:03b5121a232e 16636 } else {
pcercuei 0:03b5121a232e 16637 /*
pcercuei 0:03b5121a232e 16638 * SPEC
pcercuei 0:03b5121a232e 16639 * 2 If the <simpleContent> alternative is chosen, all of the
pcercuei 0:03b5121a232e 16640 * following must be true:
pcercuei 0:03b5121a232e 16641 * 2.1 The type definition `resolved` to by the `actual value` of the
pcercuei 0:03b5121a232e 16642 * base [attribute] must be one of the following:
pcercuei 0:03b5121a232e 16643 */
pcercuei 0:03b5121a232e 16644 if (WXS_IS_SIMPLE(base)) {
pcercuei 0:03b5121a232e 16645 if (WXS_IS_EXTENSION(type) == 0) {
pcercuei 0:03b5121a232e 16646 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 16647 /*
pcercuei 0:03b5121a232e 16648 * 2.1.3 only if the <extension> alternative is also
pcercuei 0:03b5121a232e 16649 * chosen, a simple type definition.
pcercuei 0:03b5121a232e 16650 */
pcercuei 0:03b5121a232e 16651 /* TODO: Change error code to ..._SRC_CT_2_1_3. */
pcercuei 0:03b5121a232e 16652 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16653 XML_SCHEMAP_SRC_CT_1,
pcercuei 0:03b5121a232e 16654 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16655 "If using <simpleContent> and <restriction>, the base "
pcercuei 0:03b5121a232e 16656 "type must be a complex type. The base type '%s' is "
pcercuei 0:03b5121a232e 16657 "a simple type",
pcercuei 0:03b5121a232e 16658 xmlSchemaFormatQName(&str, base->targetNamespace,
pcercuei 0:03b5121a232e 16659 base->name));
pcercuei 0:03b5121a232e 16660 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 16661 return (XML_SCHEMAP_SRC_CT_1);
pcercuei 0:03b5121a232e 16662 }
pcercuei 0:03b5121a232e 16663 } else {
pcercuei 0:03b5121a232e 16664 /* Base type is a complex type. */
pcercuei 0:03b5121a232e 16665 if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
pcercuei 0:03b5121a232e 16666 (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
pcercuei 0:03b5121a232e 16667 /*
pcercuei 0:03b5121a232e 16668 * 2.1.1 a complex type definition whose {content type} is a
pcercuei 0:03b5121a232e 16669 * simple type definition;
pcercuei 0:03b5121a232e 16670 * PASS
pcercuei 0:03b5121a232e 16671 */
pcercuei 0:03b5121a232e 16672 if (base->contentTypeDef == NULL) {
pcercuei 0:03b5121a232e 16673 xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
pcercuei 0:03b5121a232e 16674 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16675 "Internal error: xmlSchemaCheckSRCCT, "
pcercuei 0:03b5121a232e 16676 "'%s', base type has no content type",
pcercuei 0:03b5121a232e 16677 type->name);
pcercuei 0:03b5121a232e 16678 return (-1);
pcercuei 0:03b5121a232e 16679 }
pcercuei 0:03b5121a232e 16680 } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
pcercuei 0:03b5121a232e 16681 (WXS_IS_RESTRICTION(type))) {
pcercuei 0:03b5121a232e 16682
pcercuei 0:03b5121a232e 16683 /*
pcercuei 0:03b5121a232e 16684 * 2.1.2 only if the <restriction> alternative is also
pcercuei 0:03b5121a232e 16685 * chosen, a complex type definition whose {content type}
pcercuei 0:03b5121a232e 16686 * is mixed and a particle emptiable.
pcercuei 0:03b5121a232e 16687 */
pcercuei 0:03b5121a232e 16688 if (! xmlSchemaIsParticleEmptiable(
pcercuei 0:03b5121a232e 16689 (xmlSchemaParticlePtr) base->subtypes)) {
pcercuei 0:03b5121a232e 16690 ret = XML_SCHEMAP_SRC_CT_1;
pcercuei 0:03b5121a232e 16691 } else
pcercuei 0:03b5121a232e 16692 /*
pcercuei 0:03b5121a232e 16693 * Attention: at this point the <simpleType> child is in
pcercuei 0:03b5121a232e 16694 * ->contentTypeDef (put there during parsing).
pcercuei 0:03b5121a232e 16695 */
pcercuei 0:03b5121a232e 16696 if (type->contentTypeDef == NULL) {
pcercuei 0:03b5121a232e 16697 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 16698 /*
pcercuei 0:03b5121a232e 16699 * 2.2 If clause 2.1.2 above is satisfied, then there
pcercuei 0:03b5121a232e 16700 * must be a <simpleType> among the [children] of
pcercuei 0:03b5121a232e 16701 * <restriction>.
pcercuei 0:03b5121a232e 16702 */
pcercuei 0:03b5121a232e 16703 /* TODO: Change error code to ..._SRC_CT_2_2. */
pcercuei 0:03b5121a232e 16704 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16705 XML_SCHEMAP_SRC_CT_1,
pcercuei 0:03b5121a232e 16706 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16707 "A <simpleType> is expected among the children "
pcercuei 0:03b5121a232e 16708 "of <restriction>, if <simpleContent> is used and "
pcercuei 0:03b5121a232e 16709 "the base type '%s' is a complex type",
pcercuei 0:03b5121a232e 16710 xmlSchemaFormatQName(&str, base->targetNamespace,
pcercuei 0:03b5121a232e 16711 base->name));
pcercuei 0:03b5121a232e 16712 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 16713 return (XML_SCHEMAP_SRC_CT_1);
pcercuei 0:03b5121a232e 16714 }
pcercuei 0:03b5121a232e 16715 } else {
pcercuei 0:03b5121a232e 16716 ret = XML_SCHEMAP_SRC_CT_1;
pcercuei 0:03b5121a232e 16717 }
pcercuei 0:03b5121a232e 16718 }
pcercuei 0:03b5121a232e 16719 if (ret > 0) {
pcercuei 0:03b5121a232e 16720 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 16721 if (WXS_IS_RESTRICTION(type)) {
pcercuei 0:03b5121a232e 16722 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16723 XML_SCHEMAP_SRC_CT_1,
pcercuei 0:03b5121a232e 16724 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16725 "If <simpleContent> and <restriction> is used, the "
pcercuei 0:03b5121a232e 16726 "base type must be a simple type or a complex type with "
pcercuei 0:03b5121a232e 16727 "mixed content and particle emptiable. The base type "
pcercuei 0:03b5121a232e 16728 "'%s' is none of those",
pcercuei 0:03b5121a232e 16729 xmlSchemaFormatQName(&str, base->targetNamespace,
pcercuei 0:03b5121a232e 16730 base->name));
pcercuei 0:03b5121a232e 16731 } else {
pcercuei 0:03b5121a232e 16732 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 16733 XML_SCHEMAP_SRC_CT_1,
pcercuei 0:03b5121a232e 16734 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 16735 "If <simpleContent> and <extension> is used, the "
pcercuei 0:03b5121a232e 16736 "base type must be a simple type. The base type '%s' "
pcercuei 0:03b5121a232e 16737 "is a complex type",
pcercuei 0:03b5121a232e 16738 xmlSchemaFormatQName(&str, base->targetNamespace,
pcercuei 0:03b5121a232e 16739 base->name));
pcercuei 0:03b5121a232e 16740 }
pcercuei 0:03b5121a232e 16741 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 16742 }
pcercuei 0:03b5121a232e 16743 }
pcercuei 0:03b5121a232e 16744 /*
pcercuei 0:03b5121a232e 16745 * SPEC (3) "The corresponding complex type definition component must
pcercuei 0:03b5121a232e 16746 * satisfy the conditions set out in Constraints on Complex Type
pcercuei 0:03b5121a232e 16747 * Definition Schema Components ($3.4.6);"
pcercuei 0:03b5121a232e 16748 * NOTE (3) will be done in xmlSchemaTypeFixup().
pcercuei 0:03b5121a232e 16749 */
pcercuei 0:03b5121a232e 16750 /*
pcercuei 0:03b5121a232e 16751 * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
pcercuei 0:03b5121a232e 16752 * above for {attribute wildcard} is satisfied, the intensional
pcercuei 0:03b5121a232e 16753 * intersection must be expressible, as defined in Attribute Wildcard
pcercuei 0:03b5121a232e 16754 * Intersection ($3.10.6).
pcercuei 0:03b5121a232e 16755 * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
pcercuei 0:03b5121a232e 16756 */
pcercuei 0:03b5121a232e 16757 return (ret);
pcercuei 0:03b5121a232e 16758 }
pcercuei 0:03b5121a232e 16759
pcercuei 0:03b5121a232e 16760 #ifdef ENABLE_PARTICLE_RESTRICTION
pcercuei 0:03b5121a232e 16761 /**
pcercuei 0:03b5121a232e 16762 * xmlSchemaCheckParticleRangeOK:
pcercuei 0:03b5121a232e 16763 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 16764 * @type: the complex type definition
pcercuei 0:03b5121a232e 16765 *
pcercuei 0:03b5121a232e 16766 * (3.9.6) Constraints on Particle Schema Components
pcercuei 0:03b5121a232e 16767 * Schema Component Constraint:
pcercuei 0:03b5121a232e 16768 * Occurrence Range OK (range-ok)
pcercuei 0:03b5121a232e 16769 *
pcercuei 0:03b5121a232e 16770 * STATUS: complete
pcercuei 0:03b5121a232e 16771 *
pcercuei 0:03b5121a232e 16772 * Returns 0 if the constraints are satisfied, a positive
pcercuei 0:03b5121a232e 16773 * error code if not and -1 if an internal error occured.
pcercuei 0:03b5121a232e 16774 */
pcercuei 0:03b5121a232e 16775 static int
pcercuei 0:03b5121a232e 16776 xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
pcercuei 0:03b5121a232e 16777 int bmin, int bmax)
pcercuei 0:03b5121a232e 16778 {
pcercuei 0:03b5121a232e 16779 if (rmin < bmin)
pcercuei 0:03b5121a232e 16780 return (1);
pcercuei 0:03b5121a232e 16781 if ((bmax != UNBOUNDED) &&
pcercuei 0:03b5121a232e 16782 (rmax > bmax))
pcercuei 0:03b5121a232e 16783 return (1);
pcercuei 0:03b5121a232e 16784 return (0);
pcercuei 0:03b5121a232e 16785 }
pcercuei 0:03b5121a232e 16786
pcercuei 0:03b5121a232e 16787 /**
pcercuei 0:03b5121a232e 16788 * xmlSchemaCheckRCaseNameAndTypeOK:
pcercuei 0:03b5121a232e 16789 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 16790 * @r: the restricting element declaration particle
pcercuei 0:03b5121a232e 16791 * @b: the base element declaration particle
pcercuei 0:03b5121a232e 16792 *
pcercuei 0:03b5121a232e 16793 * (3.9.6) Constraints on Particle Schema Components
pcercuei 0:03b5121a232e 16794 * Schema Component Constraint:
pcercuei 0:03b5121a232e 16795 * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
pcercuei 0:03b5121a232e 16796 * (rcase-NameAndTypeOK)
pcercuei 0:03b5121a232e 16797 *
pcercuei 0:03b5121a232e 16798 * STATUS:
pcercuei 0:03b5121a232e 16799 * MISSING (3.2.3)
pcercuei 0:03b5121a232e 16800 * CLARIFY: (3.2.2)
pcercuei 0:03b5121a232e 16801 *
pcercuei 0:03b5121a232e 16802 * Returns 0 if the constraints are satisfied, a positive
pcercuei 0:03b5121a232e 16803 * error code if not and -1 if an internal error occured.
pcercuei 0:03b5121a232e 16804 */
pcercuei 0:03b5121a232e 16805 static int
pcercuei 0:03b5121a232e 16806 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 16807 xmlSchemaParticlePtr r,
pcercuei 0:03b5121a232e 16808 xmlSchemaParticlePtr b)
pcercuei 0:03b5121a232e 16809 {
pcercuei 0:03b5121a232e 16810 xmlSchemaElementPtr elemR, elemB;
pcercuei 0:03b5121a232e 16811
pcercuei 0:03b5121a232e 16812 /* TODO: Error codes (rcase-NameAndTypeOK). */
pcercuei 0:03b5121a232e 16813 elemR = (xmlSchemaElementPtr) r->children;
pcercuei 0:03b5121a232e 16814 elemB = (xmlSchemaElementPtr) b->children;
pcercuei 0:03b5121a232e 16815 /*
pcercuei 0:03b5121a232e 16816 * SPEC (1) "The declarations' {name}s and {target namespace}s are
pcercuei 0:03b5121a232e 16817 * the same."
pcercuei 0:03b5121a232e 16818 */
pcercuei 0:03b5121a232e 16819 if ((elemR != elemB) &&
pcercuei 0:03b5121a232e 16820 ((! xmlStrEqual(elemR->name, elemB->name)) ||
pcercuei 0:03b5121a232e 16821 (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
pcercuei 0:03b5121a232e 16822 return (1);
pcercuei 0:03b5121a232e 16823 /*
pcercuei 0:03b5121a232e 16824 * SPEC (2) "R's occurrence range is a valid restriction of B's
pcercuei 0:03b5121a232e 16825 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
pcercuei 0:03b5121a232e 16826 */
pcercuei 0:03b5121a232e 16827 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
pcercuei 0:03b5121a232e 16828 b->minOccurs, b->maxOccurs) != 0)
pcercuei 0:03b5121a232e 16829 return (1);
pcercuei 0:03b5121a232e 16830 /*
pcercuei 0:03b5121a232e 16831 * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
pcercuei 0:03b5121a232e 16832 * {scope} are global."
pcercuei 0:03b5121a232e 16833 */
pcercuei 0:03b5121a232e 16834 if (elemR == elemB)
pcercuei 0:03b5121a232e 16835 return (0);
pcercuei 0:03b5121a232e 16836 /*
pcercuei 0:03b5121a232e 16837 * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
pcercuei 0:03b5121a232e 16838 */
pcercuei 0:03b5121a232e 16839 if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
pcercuei 0:03b5121a232e 16840 (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
pcercuei 0:03b5121a232e 16841 return (1);
pcercuei 0:03b5121a232e 16842 /*
pcercuei 0:03b5121a232e 16843 * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
pcercuei 0:03b5121a232e 16844 * or is not fixed, or R's declaration's {value constraint} is fixed
pcercuei 0:03b5121a232e 16845 * with the same value."
pcercuei 0:03b5121a232e 16846 */
pcercuei 0:03b5121a232e 16847 if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
pcercuei 0:03b5121a232e 16848 ((elemR->value == NULL) ||
pcercuei 0:03b5121a232e 16849 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
pcercuei 0:03b5121a232e 16850 /* TODO: Equality of the initial value or normalized or canonical? */
pcercuei 0:03b5121a232e 16851 (! xmlStrEqual(elemR->value, elemB->value))))
pcercuei 0:03b5121a232e 16852 return (1);
pcercuei 0:03b5121a232e 16853 /*
pcercuei 0:03b5121a232e 16854 * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
pcercuei 0:03b5121a232e 16855 * definitions} is a subset of B's declaration's {identity-constraint
pcercuei 0:03b5121a232e 16856 * definitions}, if any."
pcercuei 0:03b5121a232e 16857 */
pcercuei 0:03b5121a232e 16858 if (elemB->idcs != NULL) {
pcercuei 0:03b5121a232e 16859 /* TODO */
pcercuei 0:03b5121a232e 16860 }
pcercuei 0:03b5121a232e 16861 /*
pcercuei 0:03b5121a232e 16862 * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
pcercuei 0:03b5121a232e 16863 * superset of B's declaration's {disallowed substitutions}."
pcercuei 0:03b5121a232e 16864 */
pcercuei 0:03b5121a232e 16865 if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
pcercuei 0:03b5121a232e 16866 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
pcercuei 0:03b5121a232e 16867 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
pcercuei 0:03b5121a232e 16868 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
pcercuei 0:03b5121a232e 16869 ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
pcercuei 0:03b5121a232e 16870 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
pcercuei 0:03b5121a232e 16871 return (1);
pcercuei 0:03b5121a232e 16872 /*
pcercuei 0:03b5121a232e 16873 * SPEC (3.2.5) "R's {type definition} is validly derived given
pcercuei 0:03b5121a232e 16874 * {extension, list, union} from B's {type definition}"
pcercuei 0:03b5121a232e 16875 *
pcercuei 0:03b5121a232e 16876 * BADSPEC TODO: What's the point of adding "list" and "union" to the
pcercuei 0:03b5121a232e 16877 * set, if the corresponding constraints handle "restriction" and
pcercuei 0:03b5121a232e 16878 * "extension" only?
pcercuei 0:03b5121a232e 16879 *
pcercuei 0:03b5121a232e 16880 */
pcercuei 0:03b5121a232e 16881 {
pcercuei 0:03b5121a232e 16882 int set = 0;
pcercuei 0:03b5121a232e 16883
pcercuei 0:03b5121a232e 16884 set |= SUBSET_EXTENSION;
pcercuei 0:03b5121a232e 16885 set |= SUBSET_LIST;
pcercuei 0:03b5121a232e 16886 set |= SUBSET_UNION;
pcercuei 0:03b5121a232e 16887 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
pcercuei 0:03b5121a232e 16888 elemB->subtypes, set) != 0)
pcercuei 0:03b5121a232e 16889 return (1);
pcercuei 0:03b5121a232e 16890 }
pcercuei 0:03b5121a232e 16891 return (0);
pcercuei 0:03b5121a232e 16892 }
pcercuei 0:03b5121a232e 16893
pcercuei 0:03b5121a232e 16894 /**
pcercuei 0:03b5121a232e 16895 * xmlSchemaCheckRCaseNSCompat:
pcercuei 0:03b5121a232e 16896 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 16897 * @r: the restricting element declaration particle
pcercuei 0:03b5121a232e 16898 * @b: the base wildcard particle
pcercuei 0:03b5121a232e 16899 *
pcercuei 0:03b5121a232e 16900 * (3.9.6) Constraints on Particle Schema Components
pcercuei 0:03b5121a232e 16901 * Schema Component Constraint:
pcercuei 0:03b5121a232e 16902 * Particle Derivation OK (Elt:Any -- NSCompat)
pcercuei 0:03b5121a232e 16903 * (rcase-NSCompat)
pcercuei 0:03b5121a232e 16904 *
pcercuei 0:03b5121a232e 16905 * STATUS: complete
pcercuei 0:03b5121a232e 16906 *
pcercuei 0:03b5121a232e 16907 * Returns 0 if the constraints are satisfied, a positive
pcercuei 0:03b5121a232e 16908 * error code if not and -1 if an internal error occured.
pcercuei 0:03b5121a232e 16909 */
pcercuei 0:03b5121a232e 16910 static int
pcercuei 0:03b5121a232e 16911 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 16912 xmlSchemaParticlePtr r,
pcercuei 0:03b5121a232e 16913 xmlSchemaParticlePtr b)
pcercuei 0:03b5121a232e 16914 {
pcercuei 0:03b5121a232e 16915 /* TODO:Error codes (rcase-NSCompat). */
pcercuei 0:03b5121a232e 16916 /*
pcercuei 0:03b5121a232e 16917 * SPEC "For an element declaration particle to be a `valid restriction`
pcercuei 0:03b5121a232e 16918 * of a wildcard particle all of the following must be true:"
pcercuei 0:03b5121a232e 16919 *
pcercuei 0:03b5121a232e 16920 * SPEC (1) "The element declaration's {target namespace} is `valid`
pcercuei 0:03b5121a232e 16921 * with respect to the wildcard's {namespace constraint} as defined by
pcercuei 0:03b5121a232e 16922 * Wildcard allows Namespace Name ($3.10.4)."
pcercuei 0:03b5121a232e 16923 */
pcercuei 0:03b5121a232e 16924 if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
pcercuei 0:03b5121a232e 16925 ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
pcercuei 0:03b5121a232e 16926 return (1);
pcercuei 0:03b5121a232e 16927 /*
pcercuei 0:03b5121a232e 16928 * SPEC (2) "R's occurrence range is a valid restriction of B's
pcercuei 0:03b5121a232e 16929 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
pcercuei 0:03b5121a232e 16930 */
pcercuei 0:03b5121a232e 16931 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
pcercuei 0:03b5121a232e 16932 b->minOccurs, b->maxOccurs) != 0)
pcercuei 0:03b5121a232e 16933 return (1);
pcercuei 0:03b5121a232e 16934
pcercuei 0:03b5121a232e 16935 return (0);
pcercuei 0:03b5121a232e 16936 }
pcercuei 0:03b5121a232e 16937
pcercuei 0:03b5121a232e 16938 /**
pcercuei 0:03b5121a232e 16939 * xmlSchemaCheckRCaseRecurseAsIfGroup:
pcercuei 0:03b5121a232e 16940 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 16941 * @r: the restricting element declaration particle
pcercuei 0:03b5121a232e 16942 * @b: the base model group particle
pcercuei 0:03b5121a232e 16943 *
pcercuei 0:03b5121a232e 16944 * (3.9.6) Constraints on Particle Schema Components
pcercuei 0:03b5121a232e 16945 * Schema Component Constraint:
pcercuei 0:03b5121a232e 16946 * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
pcercuei 0:03b5121a232e 16947 * (rcase-RecurseAsIfGroup)
pcercuei 0:03b5121a232e 16948 *
pcercuei 0:03b5121a232e 16949 * STATUS: TODO
pcercuei 0:03b5121a232e 16950 *
pcercuei 0:03b5121a232e 16951 * Returns 0 if the constraints are satisfied, a positive
pcercuei 0:03b5121a232e 16952 * error code if not and -1 if an internal error occured.
pcercuei 0:03b5121a232e 16953 */
pcercuei 0:03b5121a232e 16954 static int
pcercuei 0:03b5121a232e 16955 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 16956 xmlSchemaParticlePtr r,
pcercuei 0:03b5121a232e 16957 xmlSchemaParticlePtr b)
pcercuei 0:03b5121a232e 16958 {
pcercuei 0:03b5121a232e 16959 /* TODO: Error codes (rcase-RecurseAsIfGroup). */
pcercuei 0:03b5121a232e 16960 TODO
pcercuei 0:03b5121a232e 16961 return (0);
pcercuei 0:03b5121a232e 16962 }
pcercuei 0:03b5121a232e 16963
pcercuei 0:03b5121a232e 16964 /**
pcercuei 0:03b5121a232e 16965 * xmlSchemaCheckRCaseNSSubset:
pcercuei 0:03b5121a232e 16966 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 16967 * @r: the restricting wildcard particle
pcercuei 0:03b5121a232e 16968 * @b: the base wildcard particle
pcercuei 0:03b5121a232e 16969 *
pcercuei 0:03b5121a232e 16970 * (3.9.6) Constraints on Particle Schema Components
pcercuei 0:03b5121a232e 16971 * Schema Component Constraint:
pcercuei 0:03b5121a232e 16972 * Particle Derivation OK (Any:Any -- NSSubset)
pcercuei 0:03b5121a232e 16973 * (rcase-NSSubset)
pcercuei 0:03b5121a232e 16974 *
pcercuei 0:03b5121a232e 16975 * STATUS: complete
pcercuei 0:03b5121a232e 16976 *
pcercuei 0:03b5121a232e 16977 * Returns 0 if the constraints are satisfied, a positive
pcercuei 0:03b5121a232e 16978 * error code if not and -1 if an internal error occured.
pcercuei 0:03b5121a232e 16979 */
pcercuei 0:03b5121a232e 16980 static int
pcercuei 0:03b5121a232e 16981 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 16982 xmlSchemaParticlePtr r,
pcercuei 0:03b5121a232e 16983 xmlSchemaParticlePtr b,
pcercuei 0:03b5121a232e 16984 int isAnyTypeBase)
pcercuei 0:03b5121a232e 16985 {
pcercuei 0:03b5121a232e 16986 /* TODO: Error codes (rcase-NSSubset). */
pcercuei 0:03b5121a232e 16987 /*
pcercuei 0:03b5121a232e 16988 * SPEC (1) "R's occurrence range is a valid restriction of B's
pcercuei 0:03b5121a232e 16989 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
pcercuei 0:03b5121a232e 16990 */
pcercuei 0:03b5121a232e 16991 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
pcercuei 0:03b5121a232e 16992 b->minOccurs, b->maxOccurs))
pcercuei 0:03b5121a232e 16993 return (1);
pcercuei 0:03b5121a232e 16994 /*
pcercuei 0:03b5121a232e 16995 * SPEC (2) "R's {namespace constraint} must be an intensional subset
pcercuei 0:03b5121a232e 16996 * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
pcercuei 0:03b5121a232e 16997 */
pcercuei 0:03b5121a232e 16998 if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
pcercuei 0:03b5121a232e 16999 (xmlSchemaWildcardPtr) b->children))
pcercuei 0:03b5121a232e 17000 return (1);
pcercuei 0:03b5121a232e 17001 /*
pcercuei 0:03b5121a232e 17002 * SPEC (3) "Unless B is the content model wildcard of the `ur-type
pcercuei 0:03b5121a232e 17003 * definition`, R's {process contents} must be identical to or stronger
pcercuei 0:03b5121a232e 17004 * than B's {process contents}, where strict is stronger than lax is
pcercuei 0:03b5121a232e 17005 * stronger than skip."
pcercuei 0:03b5121a232e 17006 */
pcercuei 0:03b5121a232e 17007 if (! isAnyTypeBase) {
pcercuei 0:03b5121a232e 17008 if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
pcercuei 0:03b5121a232e 17009 ((xmlSchemaWildcardPtr) b->children)->processContents)
pcercuei 0:03b5121a232e 17010 return (1);
pcercuei 0:03b5121a232e 17011 }
pcercuei 0:03b5121a232e 17012
pcercuei 0:03b5121a232e 17013 return (0);
pcercuei 0:03b5121a232e 17014 }
pcercuei 0:03b5121a232e 17015
pcercuei 0:03b5121a232e 17016 /**
pcercuei 0:03b5121a232e 17017 * xmlSchemaCheckCOSParticleRestrict:
pcercuei 0:03b5121a232e 17018 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 17019 * @type: the complex type definition
pcercuei 0:03b5121a232e 17020 *
pcercuei 0:03b5121a232e 17021 * (3.9.6) Constraints on Particle Schema Components
pcercuei 0:03b5121a232e 17022 * Schema Component Constraint:
pcercuei 0:03b5121a232e 17023 * Particle Valid (Restriction) (cos-particle-restrict)
pcercuei 0:03b5121a232e 17024 *
pcercuei 0:03b5121a232e 17025 * STATUS: TODO
pcercuei 0:03b5121a232e 17026 *
pcercuei 0:03b5121a232e 17027 * Returns 0 if the constraints are satisfied, a positive
pcercuei 0:03b5121a232e 17028 * error code if not and -1 if an internal error occured.
pcercuei 0:03b5121a232e 17029 */
pcercuei 0:03b5121a232e 17030 static int
pcercuei 0:03b5121a232e 17031 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 17032 xmlSchemaParticlePtr r,
pcercuei 0:03b5121a232e 17033 xmlSchemaParticlePtr b)
pcercuei 0:03b5121a232e 17034 {
pcercuei 0:03b5121a232e 17035 int ret = 0;
pcercuei 0:03b5121a232e 17036
pcercuei 0:03b5121a232e 17037 /*part = WXS_TYPE_PARTICLE(type);
pcercuei 0:03b5121a232e 17038 basePart = WXS_TYPE_PARTICLE(base);
pcercuei 0:03b5121a232e 17039 */
pcercuei 0:03b5121a232e 17040
pcercuei 0:03b5121a232e 17041 TODO
pcercuei 0:03b5121a232e 17042
pcercuei 0:03b5121a232e 17043 /*
pcercuei 0:03b5121a232e 17044 * SPEC (1) "They are the same particle."
pcercuei 0:03b5121a232e 17045 */
pcercuei 0:03b5121a232e 17046 if (r == b)
pcercuei 0:03b5121a232e 17047 return (0);
pcercuei 0:03b5121a232e 17048
pcercuei 0:03b5121a232e 17049
pcercuei 0:03b5121a232e 17050 return (0);
pcercuei 0:03b5121a232e 17051 }
pcercuei 0:03b5121a232e 17052
pcercuei 0:03b5121a232e 17053 #if 0
pcercuei 0:03b5121a232e 17054 /**
pcercuei 0:03b5121a232e 17055 * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
pcercuei 0:03b5121a232e 17056 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 17057 * @r: the model group particle
pcercuei 0:03b5121a232e 17058 * @b: the base wildcard particle
pcercuei 0:03b5121a232e 17059 *
pcercuei 0:03b5121a232e 17060 * (3.9.6) Constraints on Particle Schema Components
pcercuei 0:03b5121a232e 17061 * Schema Component Constraint:
pcercuei 0:03b5121a232e 17062 * Particle Derivation OK (All/Choice/Sequence:Any --
pcercuei 0:03b5121a232e 17063 * NSRecurseCheckCardinality)
pcercuei 0:03b5121a232e 17064 * (rcase-NSRecurseCheckCardinality)
pcercuei 0:03b5121a232e 17065 *
pcercuei 0:03b5121a232e 17066 * STATUS: TODO: subst-groups
pcercuei 0:03b5121a232e 17067 *
pcercuei 0:03b5121a232e 17068 * Returns 0 if the constraints are satisfied, a positive
pcercuei 0:03b5121a232e 17069 * error code if not and -1 if an internal error occured.
pcercuei 0:03b5121a232e 17070 */
pcercuei 0:03b5121a232e 17071 static int
pcercuei 0:03b5121a232e 17072 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 17073 xmlSchemaParticlePtr r,
pcercuei 0:03b5121a232e 17074 xmlSchemaParticlePtr b)
pcercuei 0:03b5121a232e 17075 {
pcercuei 0:03b5121a232e 17076 xmlSchemaParticlePtr part;
pcercuei 0:03b5121a232e 17077 /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
pcercuei 0:03b5121a232e 17078 if ((r->children == NULL) || (r->children->children == NULL))
pcercuei 0:03b5121a232e 17079 return (-1);
pcercuei 0:03b5121a232e 17080 /*
pcercuei 0:03b5121a232e 17081 * SPEC "For a group particle to be a `valid restriction` of a
pcercuei 0:03b5121a232e 17082 * wildcard particle..."
pcercuei 0:03b5121a232e 17083 *
pcercuei 0:03b5121a232e 17084 * SPEC (1) "Every member of the {particles} of the group is a `valid
pcercuei 0:03b5121a232e 17085 * restriction` of the wildcard as defined by
pcercuei 0:03b5121a232e 17086 * Particle Valid (Restriction) ($3.9.6)."
pcercuei 0:03b5121a232e 17087 */
pcercuei 0:03b5121a232e 17088 part = (xmlSchemaParticlePtr) r->children->children;
pcercuei 0:03b5121a232e 17089 do {
pcercuei 0:03b5121a232e 17090 if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
pcercuei 0:03b5121a232e 17091 return (1);
pcercuei 0:03b5121a232e 17092 part = (xmlSchemaParticlePtr) part->next;
pcercuei 0:03b5121a232e 17093 } while (part != NULL);
pcercuei 0:03b5121a232e 17094 /*
pcercuei 0:03b5121a232e 17095 * SPEC (2) "The effective total range of the group [...] is a
pcercuei 0:03b5121a232e 17096 * valid restriction of B's occurrence range as defined by
pcercuei 0:03b5121a232e 17097 * Occurrence Range OK ($3.9.6)."
pcercuei 0:03b5121a232e 17098 */
pcercuei 0:03b5121a232e 17099 if (xmlSchemaCheckParticleRangeOK(
pcercuei 0:03b5121a232e 17100 xmlSchemaGetParticleTotalRangeMin(r),
pcercuei 0:03b5121a232e 17101 xmlSchemaGetParticleTotalRangeMax(r),
pcercuei 0:03b5121a232e 17102 b->minOccurs, b->maxOccurs) != 0)
pcercuei 0:03b5121a232e 17103 return (1);
pcercuei 0:03b5121a232e 17104 return (0);
pcercuei 0:03b5121a232e 17105 }
pcercuei 0:03b5121a232e 17106 #endif
pcercuei 0:03b5121a232e 17107
pcercuei 0:03b5121a232e 17108 /**
pcercuei 0:03b5121a232e 17109 * xmlSchemaCheckRCaseRecurse:
pcercuei 0:03b5121a232e 17110 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 17111 * @r: the <all> or <sequence> model group particle
pcercuei 0:03b5121a232e 17112 * @b: the base <all> or <sequence> model group particle
pcercuei 0:03b5121a232e 17113 *
pcercuei 0:03b5121a232e 17114 * (3.9.6) Constraints on Particle Schema Components
pcercuei 0:03b5121a232e 17115 * Schema Component Constraint:
pcercuei 0:03b5121a232e 17116 * Particle Derivation OK (All:All,Sequence:Sequence --
pcercuei 0:03b5121a232e 17117 Recurse)
pcercuei 0:03b5121a232e 17118 * (rcase-Recurse)
pcercuei 0:03b5121a232e 17119 *
pcercuei 0:03b5121a232e 17120 * STATUS: ?
pcercuei 0:03b5121a232e 17121 * TODO: subst-groups
pcercuei 0:03b5121a232e 17122 *
pcercuei 0:03b5121a232e 17123 * Returns 0 if the constraints are satisfied, a positive
pcercuei 0:03b5121a232e 17124 * error code if not and -1 if an internal error occured.
pcercuei 0:03b5121a232e 17125 */
pcercuei 0:03b5121a232e 17126 static int
pcercuei 0:03b5121a232e 17127 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 17128 xmlSchemaParticlePtr r,
pcercuei 0:03b5121a232e 17129 xmlSchemaParticlePtr b)
pcercuei 0:03b5121a232e 17130 {
pcercuei 0:03b5121a232e 17131 /* xmlSchemaParticlePtr part; */
pcercuei 0:03b5121a232e 17132 /* TODO: Error codes (rcase-Recurse). */
pcercuei 0:03b5121a232e 17133 if ((r->children == NULL) || (b->children == NULL) ||
pcercuei 0:03b5121a232e 17134 (r->children->type != b->children->type))
pcercuei 0:03b5121a232e 17135 return (-1);
pcercuei 0:03b5121a232e 17136 /*
pcercuei 0:03b5121a232e 17137 * SPEC "For an all or sequence group particle to be a `valid
pcercuei 0:03b5121a232e 17138 * restriction` of another group particle with the same {compositor}..."
pcercuei 0:03b5121a232e 17139 *
pcercuei 0:03b5121a232e 17140 * SPEC (1) "R's occurrence range is a valid restriction of B's
pcercuei 0:03b5121a232e 17141 * occurrence range as defined by Occurrence Range OK ($3.9.6)."
pcercuei 0:03b5121a232e 17142 */
pcercuei 0:03b5121a232e 17143 if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
pcercuei 0:03b5121a232e 17144 b->minOccurs, b->maxOccurs))
pcercuei 0:03b5121a232e 17145 return (1);
pcercuei 0:03b5121a232e 17146
pcercuei 0:03b5121a232e 17147
pcercuei 0:03b5121a232e 17148 return (0);
pcercuei 0:03b5121a232e 17149 }
pcercuei 0:03b5121a232e 17150
pcercuei 0:03b5121a232e 17151 #endif
pcercuei 0:03b5121a232e 17152
pcercuei 0:03b5121a232e 17153 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
pcercuei 0:03b5121a232e 17154 xmlSchemaPCustomErrExt(pctxt, \
pcercuei 0:03b5121a232e 17155 XML_SCHEMAP_INVALID_FACET_VALUE, \
pcercuei 0:03b5121a232e 17156 WXS_BASIC_CAST fac1, fac1->node, \
pcercuei 0:03b5121a232e 17157 "It is an error for both '%s' and '%s' to be specified on the "\
pcercuei 0:03b5121a232e 17158 "same type definition", \
pcercuei 0:03b5121a232e 17159 BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
pcercuei 0:03b5121a232e 17160 BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
pcercuei 0:03b5121a232e 17161
pcercuei 0:03b5121a232e 17162 #define FACET_RESTR_ERR(fac1, msg) \
pcercuei 0:03b5121a232e 17163 xmlSchemaPCustomErr(pctxt, \
pcercuei 0:03b5121a232e 17164 XML_SCHEMAP_INVALID_FACET_VALUE, \
pcercuei 0:03b5121a232e 17165 WXS_BASIC_CAST fac1, fac1->node, \
pcercuei 0:03b5121a232e 17166 msg, NULL);
pcercuei 0:03b5121a232e 17167
pcercuei 0:03b5121a232e 17168 #define FACET_RESTR_FIXED_ERR(fac) \
pcercuei 0:03b5121a232e 17169 xmlSchemaPCustomErr(pctxt, \
pcercuei 0:03b5121a232e 17170 XML_SCHEMAP_INVALID_FACET_VALUE, \
pcercuei 0:03b5121a232e 17171 WXS_BASIC_CAST fac, fac->node, \
pcercuei 0:03b5121a232e 17172 "The base type's facet is 'fixed', thus the value must not " \
pcercuei 0:03b5121a232e 17173 "differ", NULL);
pcercuei 0:03b5121a232e 17174
pcercuei 0:03b5121a232e 17175 static void
pcercuei 0:03b5121a232e 17176 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 17177 xmlSchemaFacetPtr facet1,
pcercuei 0:03b5121a232e 17178 xmlSchemaFacetPtr facet2,
pcercuei 0:03b5121a232e 17179 int lessGreater,
pcercuei 0:03b5121a232e 17180 int orEqual,
pcercuei 0:03b5121a232e 17181 int ofBase)
pcercuei 0:03b5121a232e 17182 {
pcercuei 0:03b5121a232e 17183 xmlChar *msg = NULL;
pcercuei 0:03b5121a232e 17184
pcercuei 0:03b5121a232e 17185 msg = xmlStrdup(BAD_CAST "'");
pcercuei 0:03b5121a232e 17186 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
pcercuei 0:03b5121a232e 17187 msg = xmlStrcat(msg, BAD_CAST "' has to be");
pcercuei 0:03b5121a232e 17188 if (lessGreater == 0)
pcercuei 0:03b5121a232e 17189 msg = xmlStrcat(msg, BAD_CAST " equal to");
pcercuei 0:03b5121a232e 17190 if (lessGreater == 1)
pcercuei 0:03b5121a232e 17191 msg = xmlStrcat(msg, BAD_CAST " greater than");
pcercuei 0:03b5121a232e 17192 else
pcercuei 0:03b5121a232e 17193 msg = xmlStrcat(msg, BAD_CAST " less than");
pcercuei 0:03b5121a232e 17194
pcercuei 0:03b5121a232e 17195 if (orEqual)
pcercuei 0:03b5121a232e 17196 msg = xmlStrcat(msg, BAD_CAST " or equal to");
pcercuei 0:03b5121a232e 17197 msg = xmlStrcat(msg, BAD_CAST " '");
pcercuei 0:03b5121a232e 17198 msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
pcercuei 0:03b5121a232e 17199 if (ofBase)
pcercuei 0:03b5121a232e 17200 msg = xmlStrcat(msg, BAD_CAST "' of the base type");
pcercuei 0:03b5121a232e 17201 else
pcercuei 0:03b5121a232e 17202 msg = xmlStrcat(msg, BAD_CAST "'");
pcercuei 0:03b5121a232e 17203
pcercuei 0:03b5121a232e 17204 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 17205 XML_SCHEMAP_INVALID_FACET_VALUE,
pcercuei 0:03b5121a232e 17206 WXS_BASIC_CAST facet1, NULL,
pcercuei 0:03b5121a232e 17207 (const char *) msg, NULL);
pcercuei 0:03b5121a232e 17208
pcercuei 0:03b5121a232e 17209 if (msg != NULL)
pcercuei 0:03b5121a232e 17210 xmlFree(msg);
pcercuei 0:03b5121a232e 17211 }
pcercuei 0:03b5121a232e 17212
pcercuei 0:03b5121a232e 17213 /*
pcercuei 0:03b5121a232e 17214 * xmlSchemaDeriveAndValidateFacets:
pcercuei 0:03b5121a232e 17215 *
pcercuei 0:03b5121a232e 17216 * Schema Component Constraint: Simple Type Restriction (Facets)
pcercuei 0:03b5121a232e 17217 * (st-restrict-facets)
pcercuei 0:03b5121a232e 17218 */
pcercuei 0:03b5121a232e 17219 static int
pcercuei 0:03b5121a232e 17220 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 17221 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 17222 {
pcercuei 0:03b5121a232e 17223 xmlSchemaTypePtr base = type->baseType;
pcercuei 0:03b5121a232e 17224 xmlSchemaFacetLinkPtr link, cur, last = NULL;
pcercuei 0:03b5121a232e 17225 xmlSchemaFacetPtr facet, bfacet,
pcercuei 0:03b5121a232e 17226 flength = NULL, ftotdig = NULL, ffracdig = NULL,
pcercuei 0:03b5121a232e 17227 fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
pcercuei 0:03b5121a232e 17228 fmininc = NULL, fmaxinc = NULL,
pcercuei 0:03b5121a232e 17229 fminexc = NULL, fmaxexc = NULL,
pcercuei 0:03b5121a232e 17230 bflength = NULL, bftotdig = NULL, bffracdig = NULL,
pcercuei 0:03b5121a232e 17231 bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
pcercuei 0:03b5121a232e 17232 bfmininc = NULL, bfmaxinc = NULL,
pcercuei 0:03b5121a232e 17233 bfminexc = NULL, bfmaxexc = NULL;
pcercuei 0:03b5121a232e 17234 int res; /* err = 0, fixedErr; */
pcercuei 0:03b5121a232e 17235
pcercuei 0:03b5121a232e 17236 /*
pcercuei 0:03b5121a232e 17237 * SPEC st-restrict-facets 1:
pcercuei 0:03b5121a232e 17238 * "The {variety} of R is the same as that of B."
pcercuei 0:03b5121a232e 17239 */
pcercuei 0:03b5121a232e 17240 /*
pcercuei 0:03b5121a232e 17241 * SPEC st-restrict-facets 2:
pcercuei 0:03b5121a232e 17242 * "If {variety} is atomic, the {primitive type definition}
pcercuei 0:03b5121a232e 17243 * of R is the same as that of B."
pcercuei 0:03b5121a232e 17244 *
pcercuei 0:03b5121a232e 17245 * NOTE: we leave 1 & 2 out for now, since this will be
pcercuei 0:03b5121a232e 17246 * satisfied by the derivation process.
pcercuei 0:03b5121a232e 17247 * CONSTRUCTION TODO: Maybe needed if using a construction API.
pcercuei 0:03b5121a232e 17248 */
pcercuei 0:03b5121a232e 17249 /*
pcercuei 0:03b5121a232e 17250 * SPEC st-restrict-facets 3:
pcercuei 0:03b5121a232e 17251 * "The {facets} of R are the union of S and the {facets}
pcercuei 0:03b5121a232e 17252 * of B, eliminating duplicates. To eliminate duplicates,
pcercuei 0:03b5121a232e 17253 * when a facet of the same kind occurs in both S and the
pcercuei 0:03b5121a232e 17254 * {facets} of B, the one in the {facets} of B is not
pcercuei 0:03b5121a232e 17255 * included, with the exception of enumeration and pattern
pcercuei 0:03b5121a232e 17256 * facets, for which multiple occurrences with distinct values
pcercuei 0:03b5121a232e 17257 * are allowed."
pcercuei 0:03b5121a232e 17258 */
pcercuei 0:03b5121a232e 17259
pcercuei 0:03b5121a232e 17260 if ((type->facetSet == NULL) && (base->facetSet == NULL))
pcercuei 0:03b5121a232e 17261 return (0);
pcercuei 0:03b5121a232e 17262
pcercuei 0:03b5121a232e 17263 last = type->facetSet;
pcercuei 0:03b5121a232e 17264 if (last != NULL)
pcercuei 0:03b5121a232e 17265 while (last->next != NULL)
pcercuei 0:03b5121a232e 17266 last = last->next;
pcercuei 0:03b5121a232e 17267
pcercuei 0:03b5121a232e 17268 for (cur = type->facetSet; cur != NULL; cur = cur->next) {
pcercuei 0:03b5121a232e 17269 facet = cur->facet;
pcercuei 0:03b5121a232e 17270 switch (facet->type) {
pcercuei 0:03b5121a232e 17271 case XML_SCHEMA_FACET_LENGTH:
pcercuei 0:03b5121a232e 17272 flength = facet; break;
pcercuei 0:03b5121a232e 17273 case XML_SCHEMA_FACET_MINLENGTH:
pcercuei 0:03b5121a232e 17274 fminlen = facet; break;
pcercuei 0:03b5121a232e 17275 case XML_SCHEMA_FACET_MININCLUSIVE:
pcercuei 0:03b5121a232e 17276 fmininc = facet; break;
pcercuei 0:03b5121a232e 17277 case XML_SCHEMA_FACET_MINEXCLUSIVE:
pcercuei 0:03b5121a232e 17278 fminexc = facet; break;
pcercuei 0:03b5121a232e 17279 case XML_SCHEMA_FACET_MAXLENGTH:
pcercuei 0:03b5121a232e 17280 fmaxlen = facet; break;
pcercuei 0:03b5121a232e 17281 case XML_SCHEMA_FACET_MAXINCLUSIVE:
pcercuei 0:03b5121a232e 17282 fmaxinc = facet; break;
pcercuei 0:03b5121a232e 17283 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
pcercuei 0:03b5121a232e 17284 fmaxexc = facet; break;
pcercuei 0:03b5121a232e 17285 case XML_SCHEMA_FACET_TOTALDIGITS:
pcercuei 0:03b5121a232e 17286 ftotdig = facet; break;
pcercuei 0:03b5121a232e 17287 case XML_SCHEMA_FACET_FRACTIONDIGITS:
pcercuei 0:03b5121a232e 17288 ffracdig = facet; break;
pcercuei 0:03b5121a232e 17289 default:
pcercuei 0:03b5121a232e 17290 break;
pcercuei 0:03b5121a232e 17291 }
pcercuei 0:03b5121a232e 17292 }
pcercuei 0:03b5121a232e 17293 for (cur = base->facetSet; cur != NULL; cur = cur->next) {
pcercuei 0:03b5121a232e 17294 facet = cur->facet;
pcercuei 0:03b5121a232e 17295 switch (facet->type) {
pcercuei 0:03b5121a232e 17296 case XML_SCHEMA_FACET_LENGTH:
pcercuei 0:03b5121a232e 17297 bflength = facet; break;
pcercuei 0:03b5121a232e 17298 case XML_SCHEMA_FACET_MINLENGTH:
pcercuei 0:03b5121a232e 17299 bfminlen = facet; break;
pcercuei 0:03b5121a232e 17300 case XML_SCHEMA_FACET_MININCLUSIVE:
pcercuei 0:03b5121a232e 17301 bfmininc = facet; break;
pcercuei 0:03b5121a232e 17302 case XML_SCHEMA_FACET_MINEXCLUSIVE:
pcercuei 0:03b5121a232e 17303 bfminexc = facet; break;
pcercuei 0:03b5121a232e 17304 case XML_SCHEMA_FACET_MAXLENGTH:
pcercuei 0:03b5121a232e 17305 bfmaxlen = facet; break;
pcercuei 0:03b5121a232e 17306 case XML_SCHEMA_FACET_MAXINCLUSIVE:
pcercuei 0:03b5121a232e 17307 bfmaxinc = facet; break;
pcercuei 0:03b5121a232e 17308 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
pcercuei 0:03b5121a232e 17309 bfmaxexc = facet; break;
pcercuei 0:03b5121a232e 17310 case XML_SCHEMA_FACET_TOTALDIGITS:
pcercuei 0:03b5121a232e 17311 bftotdig = facet; break;
pcercuei 0:03b5121a232e 17312 case XML_SCHEMA_FACET_FRACTIONDIGITS:
pcercuei 0:03b5121a232e 17313 bffracdig = facet; break;
pcercuei 0:03b5121a232e 17314 default:
pcercuei 0:03b5121a232e 17315 break;
pcercuei 0:03b5121a232e 17316 }
pcercuei 0:03b5121a232e 17317 }
pcercuei 0:03b5121a232e 17318 /*
pcercuei 0:03b5121a232e 17319 * length and minLength or maxLength (2.2) + (3.2)
pcercuei 0:03b5121a232e 17320 */
pcercuei 0:03b5121a232e 17321 if (flength && (fminlen || fmaxlen)) {
pcercuei 0:03b5121a232e 17322 FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
pcercuei 0:03b5121a232e 17323 "either of 'minLength' or 'maxLength' to be specified on "
pcercuei 0:03b5121a232e 17324 "the same type definition")
pcercuei 0:03b5121a232e 17325 }
pcercuei 0:03b5121a232e 17326 /*
pcercuei 0:03b5121a232e 17327 * Mutual exclusions in the same derivation step.
pcercuei 0:03b5121a232e 17328 */
pcercuei 0:03b5121a232e 17329 if ((fmaxinc) && (fmaxexc)) {
pcercuei 0:03b5121a232e 17330 /*
pcercuei 0:03b5121a232e 17331 * SCC "maxInclusive and maxExclusive"
pcercuei 0:03b5121a232e 17332 */
pcercuei 0:03b5121a232e 17333 FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
pcercuei 0:03b5121a232e 17334 }
pcercuei 0:03b5121a232e 17335 if ((fmininc) && (fminexc)) {
pcercuei 0:03b5121a232e 17336 /*
pcercuei 0:03b5121a232e 17337 * SCC "minInclusive and minExclusive"
pcercuei 0:03b5121a232e 17338 */
pcercuei 0:03b5121a232e 17339 FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
pcercuei 0:03b5121a232e 17340 }
pcercuei 0:03b5121a232e 17341
pcercuei 0:03b5121a232e 17342 if (flength && bflength) {
pcercuei 0:03b5121a232e 17343 /*
pcercuei 0:03b5121a232e 17344 * SCC "length valid restriction"
pcercuei 0:03b5121a232e 17345 * The values have to be equal.
pcercuei 0:03b5121a232e 17346 */
pcercuei 0:03b5121a232e 17347 res = xmlSchemaCompareValues(flength->val, bflength->val);
pcercuei 0:03b5121a232e 17348 if (res == -2)
pcercuei 0:03b5121a232e 17349 goto internal_error;
pcercuei 0:03b5121a232e 17350 if (res != 0)
pcercuei 0:03b5121a232e 17351 xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
pcercuei 0:03b5121a232e 17352 if ((res != 0) && (bflength->fixed)) {
pcercuei 0:03b5121a232e 17353 FACET_RESTR_FIXED_ERR(flength)
pcercuei 0:03b5121a232e 17354 }
pcercuei 0:03b5121a232e 17355
pcercuei 0:03b5121a232e 17356 }
pcercuei 0:03b5121a232e 17357 if (fminlen && bfminlen) {
pcercuei 0:03b5121a232e 17358 /*
pcercuei 0:03b5121a232e 17359 * SCC "minLength valid restriction"
pcercuei 0:03b5121a232e 17360 * minLength >= BASE minLength
pcercuei 0:03b5121a232e 17361 */
pcercuei 0:03b5121a232e 17362 res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
pcercuei 0:03b5121a232e 17363 if (res == -2)
pcercuei 0:03b5121a232e 17364 goto internal_error;
pcercuei 0:03b5121a232e 17365 if (res == -1)
pcercuei 0:03b5121a232e 17366 xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
pcercuei 0:03b5121a232e 17367 if ((res != 0) && (bfminlen->fixed)) {
pcercuei 0:03b5121a232e 17368 FACET_RESTR_FIXED_ERR(fminlen)
pcercuei 0:03b5121a232e 17369 }
pcercuei 0:03b5121a232e 17370 }
pcercuei 0:03b5121a232e 17371 if (fmaxlen && bfmaxlen) {
pcercuei 0:03b5121a232e 17372 /*
pcercuei 0:03b5121a232e 17373 * SCC "maxLength valid restriction"
pcercuei 0:03b5121a232e 17374 * maxLength <= BASE minLength
pcercuei 0:03b5121a232e 17375 */
pcercuei 0:03b5121a232e 17376 res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
pcercuei 0:03b5121a232e 17377 if (res == -2)
pcercuei 0:03b5121a232e 17378 goto internal_error;
pcercuei 0:03b5121a232e 17379 if (res == 1)
pcercuei 0:03b5121a232e 17380 xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
pcercuei 0:03b5121a232e 17381 if ((res != 0) && (bfmaxlen->fixed)) {
pcercuei 0:03b5121a232e 17382 FACET_RESTR_FIXED_ERR(fmaxlen)
pcercuei 0:03b5121a232e 17383 }
pcercuei 0:03b5121a232e 17384 }
pcercuei 0:03b5121a232e 17385 /*
pcercuei 0:03b5121a232e 17386 * SCC "length and minLength or maxLength"
pcercuei 0:03b5121a232e 17387 */
pcercuei 0:03b5121a232e 17388 if (! flength)
pcercuei 0:03b5121a232e 17389 flength = bflength;
pcercuei 0:03b5121a232e 17390 if (flength) {
pcercuei 0:03b5121a232e 17391 if (! fminlen)
pcercuei 0:03b5121a232e 17392 fminlen = bfminlen;
pcercuei 0:03b5121a232e 17393 if (fminlen) {
pcercuei 0:03b5121a232e 17394 /* (1.1) length >= minLength */
pcercuei 0:03b5121a232e 17395 res = xmlSchemaCompareValues(flength->val, fminlen->val);
pcercuei 0:03b5121a232e 17396 if (res == -2)
pcercuei 0:03b5121a232e 17397 goto internal_error;
pcercuei 0:03b5121a232e 17398 if (res == -1)
pcercuei 0:03b5121a232e 17399 xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
pcercuei 0:03b5121a232e 17400 }
pcercuei 0:03b5121a232e 17401 if (! fmaxlen)
pcercuei 0:03b5121a232e 17402 fmaxlen = bfmaxlen;
pcercuei 0:03b5121a232e 17403 if (fmaxlen) {
pcercuei 0:03b5121a232e 17404 /* (2.1) length <= maxLength */
pcercuei 0:03b5121a232e 17405 res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
pcercuei 0:03b5121a232e 17406 if (res == -2)
pcercuei 0:03b5121a232e 17407 goto internal_error;
pcercuei 0:03b5121a232e 17408 if (res == 1)
pcercuei 0:03b5121a232e 17409 xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
pcercuei 0:03b5121a232e 17410 }
pcercuei 0:03b5121a232e 17411 }
pcercuei 0:03b5121a232e 17412 if (fmaxinc) {
pcercuei 0:03b5121a232e 17413 /*
pcercuei 0:03b5121a232e 17414 * "maxInclusive"
pcercuei 0:03b5121a232e 17415 */
pcercuei 0:03b5121a232e 17416 if (fmininc) {
pcercuei 0:03b5121a232e 17417 /* SCC "maxInclusive >= minInclusive" */
pcercuei 0:03b5121a232e 17418 res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
pcercuei 0:03b5121a232e 17419 if (res == -2)
pcercuei 0:03b5121a232e 17420 goto internal_error;
pcercuei 0:03b5121a232e 17421 if (res == -1) {
pcercuei 0:03b5121a232e 17422 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
pcercuei 0:03b5121a232e 17423 }
pcercuei 0:03b5121a232e 17424 }
pcercuei 0:03b5121a232e 17425 /*
pcercuei 0:03b5121a232e 17426 * SCC "maxInclusive valid restriction"
pcercuei 0:03b5121a232e 17427 */
pcercuei 0:03b5121a232e 17428 if (bfmaxinc) {
pcercuei 0:03b5121a232e 17429 /* maxInclusive <= BASE maxInclusive */
pcercuei 0:03b5121a232e 17430 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
pcercuei 0:03b5121a232e 17431 if (res == -2)
pcercuei 0:03b5121a232e 17432 goto internal_error;
pcercuei 0:03b5121a232e 17433 if (res == 1)
pcercuei 0:03b5121a232e 17434 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
pcercuei 0:03b5121a232e 17435 if ((res != 0) && (bfmaxinc->fixed)) {
pcercuei 0:03b5121a232e 17436 FACET_RESTR_FIXED_ERR(fmaxinc)
pcercuei 0:03b5121a232e 17437 }
pcercuei 0:03b5121a232e 17438 }
pcercuei 0:03b5121a232e 17439 if (bfmaxexc) {
pcercuei 0:03b5121a232e 17440 /* maxInclusive < BASE maxExclusive */
pcercuei 0:03b5121a232e 17441 res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
pcercuei 0:03b5121a232e 17442 if (res == -2)
pcercuei 0:03b5121a232e 17443 goto internal_error;
pcercuei 0:03b5121a232e 17444 if (res != -1) {
pcercuei 0:03b5121a232e 17445 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
pcercuei 0:03b5121a232e 17446 }
pcercuei 0:03b5121a232e 17447 }
pcercuei 0:03b5121a232e 17448 if (bfmininc) {
pcercuei 0:03b5121a232e 17449 /* maxInclusive >= BASE minInclusive */
pcercuei 0:03b5121a232e 17450 res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
pcercuei 0:03b5121a232e 17451 if (res == -2)
pcercuei 0:03b5121a232e 17452 goto internal_error;
pcercuei 0:03b5121a232e 17453 if (res == -1) {
pcercuei 0:03b5121a232e 17454 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
pcercuei 0:03b5121a232e 17455 }
pcercuei 0:03b5121a232e 17456 }
pcercuei 0:03b5121a232e 17457 if (bfminexc) {
pcercuei 0:03b5121a232e 17458 /* maxInclusive > BASE minExclusive */
pcercuei 0:03b5121a232e 17459 res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
pcercuei 0:03b5121a232e 17460 if (res == -2)
pcercuei 0:03b5121a232e 17461 goto internal_error;
pcercuei 0:03b5121a232e 17462 if (res != 1) {
pcercuei 0:03b5121a232e 17463 xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
pcercuei 0:03b5121a232e 17464 }
pcercuei 0:03b5121a232e 17465 }
pcercuei 0:03b5121a232e 17466 }
pcercuei 0:03b5121a232e 17467 if (fmaxexc) {
pcercuei 0:03b5121a232e 17468 /*
pcercuei 0:03b5121a232e 17469 * "maxExclusive >= minExclusive"
pcercuei 0:03b5121a232e 17470 */
pcercuei 0:03b5121a232e 17471 if (fminexc) {
pcercuei 0:03b5121a232e 17472 res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
pcercuei 0:03b5121a232e 17473 if (res == -2)
pcercuei 0:03b5121a232e 17474 goto internal_error;
pcercuei 0:03b5121a232e 17475 if (res == -1) {
pcercuei 0:03b5121a232e 17476 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
pcercuei 0:03b5121a232e 17477 }
pcercuei 0:03b5121a232e 17478 }
pcercuei 0:03b5121a232e 17479 /*
pcercuei 0:03b5121a232e 17480 * "maxExclusive valid restriction"
pcercuei 0:03b5121a232e 17481 */
pcercuei 0:03b5121a232e 17482 if (bfmaxexc) {
pcercuei 0:03b5121a232e 17483 /* maxExclusive <= BASE maxExclusive */
pcercuei 0:03b5121a232e 17484 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
pcercuei 0:03b5121a232e 17485 if (res == -2)
pcercuei 0:03b5121a232e 17486 goto internal_error;
pcercuei 0:03b5121a232e 17487 if (res == 1) {
pcercuei 0:03b5121a232e 17488 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
pcercuei 0:03b5121a232e 17489 }
pcercuei 0:03b5121a232e 17490 if ((res != 0) && (bfmaxexc->fixed)) {
pcercuei 0:03b5121a232e 17491 FACET_RESTR_FIXED_ERR(fmaxexc)
pcercuei 0:03b5121a232e 17492 }
pcercuei 0:03b5121a232e 17493 }
pcercuei 0:03b5121a232e 17494 if (bfmaxinc) {
pcercuei 0:03b5121a232e 17495 /* maxExclusive <= BASE maxInclusive */
pcercuei 0:03b5121a232e 17496 res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
pcercuei 0:03b5121a232e 17497 if (res == -2)
pcercuei 0:03b5121a232e 17498 goto internal_error;
pcercuei 0:03b5121a232e 17499 if (res == 1) {
pcercuei 0:03b5121a232e 17500 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
pcercuei 0:03b5121a232e 17501 }
pcercuei 0:03b5121a232e 17502 }
pcercuei 0:03b5121a232e 17503 if (bfmininc) {
pcercuei 0:03b5121a232e 17504 /* maxExclusive > BASE minInclusive */
pcercuei 0:03b5121a232e 17505 res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
pcercuei 0:03b5121a232e 17506 if (res == -2)
pcercuei 0:03b5121a232e 17507 goto internal_error;
pcercuei 0:03b5121a232e 17508 if (res != 1) {
pcercuei 0:03b5121a232e 17509 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
pcercuei 0:03b5121a232e 17510 }
pcercuei 0:03b5121a232e 17511 }
pcercuei 0:03b5121a232e 17512 if (bfminexc) {
pcercuei 0:03b5121a232e 17513 /* maxExclusive > BASE minExclusive */
pcercuei 0:03b5121a232e 17514 res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
pcercuei 0:03b5121a232e 17515 if (res == -2)
pcercuei 0:03b5121a232e 17516 goto internal_error;
pcercuei 0:03b5121a232e 17517 if (res != 1) {
pcercuei 0:03b5121a232e 17518 xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
pcercuei 0:03b5121a232e 17519 }
pcercuei 0:03b5121a232e 17520 }
pcercuei 0:03b5121a232e 17521 }
pcercuei 0:03b5121a232e 17522 if (fminexc) {
pcercuei 0:03b5121a232e 17523 /*
pcercuei 0:03b5121a232e 17524 * "minExclusive < maxInclusive"
pcercuei 0:03b5121a232e 17525 */
pcercuei 0:03b5121a232e 17526 if (fmaxinc) {
pcercuei 0:03b5121a232e 17527 res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
pcercuei 0:03b5121a232e 17528 if (res == -2)
pcercuei 0:03b5121a232e 17529 goto internal_error;
pcercuei 0:03b5121a232e 17530 if (res != -1) {
pcercuei 0:03b5121a232e 17531 xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
pcercuei 0:03b5121a232e 17532 }
pcercuei 0:03b5121a232e 17533 }
pcercuei 0:03b5121a232e 17534 /*
pcercuei 0:03b5121a232e 17535 * "minExclusive valid restriction"
pcercuei 0:03b5121a232e 17536 */
pcercuei 0:03b5121a232e 17537 if (bfminexc) {
pcercuei 0:03b5121a232e 17538 /* minExclusive >= BASE minExclusive */
pcercuei 0:03b5121a232e 17539 res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
pcercuei 0:03b5121a232e 17540 if (res == -2)
pcercuei 0:03b5121a232e 17541 goto internal_error;
pcercuei 0:03b5121a232e 17542 if (res == -1) {
pcercuei 0:03b5121a232e 17543 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
pcercuei 0:03b5121a232e 17544 }
pcercuei 0:03b5121a232e 17545 if ((res != 0) && (bfminexc->fixed)) {
pcercuei 0:03b5121a232e 17546 FACET_RESTR_FIXED_ERR(fminexc)
pcercuei 0:03b5121a232e 17547 }
pcercuei 0:03b5121a232e 17548 }
pcercuei 0:03b5121a232e 17549 if (bfmaxinc) {
pcercuei 0:03b5121a232e 17550 /* minExclusive <= BASE maxInclusive */
pcercuei 0:03b5121a232e 17551 res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
pcercuei 0:03b5121a232e 17552 if (res == -2)
pcercuei 0:03b5121a232e 17553 goto internal_error;
pcercuei 0:03b5121a232e 17554 if (res == 1) {
pcercuei 0:03b5121a232e 17555 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
pcercuei 0:03b5121a232e 17556 }
pcercuei 0:03b5121a232e 17557 }
pcercuei 0:03b5121a232e 17558 if (bfmininc) {
pcercuei 0:03b5121a232e 17559 /* minExclusive >= BASE minInclusive */
pcercuei 0:03b5121a232e 17560 res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
pcercuei 0:03b5121a232e 17561 if (res == -2)
pcercuei 0:03b5121a232e 17562 goto internal_error;
pcercuei 0:03b5121a232e 17563 if (res == -1) {
pcercuei 0:03b5121a232e 17564 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
pcercuei 0:03b5121a232e 17565 }
pcercuei 0:03b5121a232e 17566 }
pcercuei 0:03b5121a232e 17567 if (bfmaxexc) {
pcercuei 0:03b5121a232e 17568 /* minExclusive < BASE maxExclusive */
pcercuei 0:03b5121a232e 17569 res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
pcercuei 0:03b5121a232e 17570 if (res == -2)
pcercuei 0:03b5121a232e 17571 goto internal_error;
pcercuei 0:03b5121a232e 17572 if (res != -1) {
pcercuei 0:03b5121a232e 17573 xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
pcercuei 0:03b5121a232e 17574 }
pcercuei 0:03b5121a232e 17575 }
pcercuei 0:03b5121a232e 17576 }
pcercuei 0:03b5121a232e 17577 if (fmininc) {
pcercuei 0:03b5121a232e 17578 /*
pcercuei 0:03b5121a232e 17579 * "minInclusive < maxExclusive"
pcercuei 0:03b5121a232e 17580 */
pcercuei 0:03b5121a232e 17581 if (fmaxexc) {
pcercuei 0:03b5121a232e 17582 res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
pcercuei 0:03b5121a232e 17583 if (res == -2)
pcercuei 0:03b5121a232e 17584 goto internal_error;
pcercuei 0:03b5121a232e 17585 if (res != -1) {
pcercuei 0:03b5121a232e 17586 xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
pcercuei 0:03b5121a232e 17587 }
pcercuei 0:03b5121a232e 17588 }
pcercuei 0:03b5121a232e 17589 /*
pcercuei 0:03b5121a232e 17590 * "minExclusive valid restriction"
pcercuei 0:03b5121a232e 17591 */
pcercuei 0:03b5121a232e 17592 if (bfmininc) {
pcercuei 0:03b5121a232e 17593 /* minInclusive >= BASE minInclusive */
pcercuei 0:03b5121a232e 17594 res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
pcercuei 0:03b5121a232e 17595 if (res == -2)
pcercuei 0:03b5121a232e 17596 goto internal_error;
pcercuei 0:03b5121a232e 17597 if (res == -1) {
pcercuei 0:03b5121a232e 17598 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
pcercuei 0:03b5121a232e 17599 }
pcercuei 0:03b5121a232e 17600 if ((res != 0) && (bfmininc->fixed)) {
pcercuei 0:03b5121a232e 17601 FACET_RESTR_FIXED_ERR(fmininc)
pcercuei 0:03b5121a232e 17602 }
pcercuei 0:03b5121a232e 17603 }
pcercuei 0:03b5121a232e 17604 if (bfmaxinc) {
pcercuei 0:03b5121a232e 17605 /* minInclusive <= BASE maxInclusive */
pcercuei 0:03b5121a232e 17606 res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
pcercuei 0:03b5121a232e 17607 if (res == -2)
pcercuei 0:03b5121a232e 17608 goto internal_error;
pcercuei 0:03b5121a232e 17609 if (res == 1) {
pcercuei 0:03b5121a232e 17610 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
pcercuei 0:03b5121a232e 17611 }
pcercuei 0:03b5121a232e 17612 }
pcercuei 0:03b5121a232e 17613 if (bfminexc) {
pcercuei 0:03b5121a232e 17614 /* minInclusive > BASE minExclusive */
pcercuei 0:03b5121a232e 17615 res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
pcercuei 0:03b5121a232e 17616 if (res == -2)
pcercuei 0:03b5121a232e 17617 goto internal_error;
pcercuei 0:03b5121a232e 17618 if (res != 1)
pcercuei 0:03b5121a232e 17619 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
pcercuei 0:03b5121a232e 17620 }
pcercuei 0:03b5121a232e 17621 if (bfmaxexc) {
pcercuei 0:03b5121a232e 17622 /* minInclusive < BASE maxExclusive */
pcercuei 0:03b5121a232e 17623 res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
pcercuei 0:03b5121a232e 17624 if (res == -2)
pcercuei 0:03b5121a232e 17625 goto internal_error;
pcercuei 0:03b5121a232e 17626 if (res != -1)
pcercuei 0:03b5121a232e 17627 xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
pcercuei 0:03b5121a232e 17628 }
pcercuei 0:03b5121a232e 17629 }
pcercuei 0:03b5121a232e 17630 if (ftotdig && bftotdig) {
pcercuei 0:03b5121a232e 17631 /*
pcercuei 0:03b5121a232e 17632 * SCC " totalDigits valid restriction"
pcercuei 0:03b5121a232e 17633 * totalDigits <= BASE totalDigits
pcercuei 0:03b5121a232e 17634 */
pcercuei 0:03b5121a232e 17635 res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
pcercuei 0:03b5121a232e 17636 if (res == -2)
pcercuei 0:03b5121a232e 17637 goto internal_error;
pcercuei 0:03b5121a232e 17638 if (res == 1)
pcercuei 0:03b5121a232e 17639 xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
pcercuei 0:03b5121a232e 17640 -1, 1, 1);
pcercuei 0:03b5121a232e 17641 if ((res != 0) && (bftotdig->fixed)) {
pcercuei 0:03b5121a232e 17642 FACET_RESTR_FIXED_ERR(ftotdig)
pcercuei 0:03b5121a232e 17643 }
pcercuei 0:03b5121a232e 17644 }
pcercuei 0:03b5121a232e 17645 if (ffracdig && bffracdig) {
pcercuei 0:03b5121a232e 17646 /*
pcercuei 0:03b5121a232e 17647 * SCC "fractionDigits valid restriction"
pcercuei 0:03b5121a232e 17648 * fractionDigits <= BASE fractionDigits
pcercuei 0:03b5121a232e 17649 */
pcercuei 0:03b5121a232e 17650 res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
pcercuei 0:03b5121a232e 17651 if (res == -2)
pcercuei 0:03b5121a232e 17652 goto internal_error;
pcercuei 0:03b5121a232e 17653 if (res == 1)
pcercuei 0:03b5121a232e 17654 xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
pcercuei 0:03b5121a232e 17655 -1, 1, 1);
pcercuei 0:03b5121a232e 17656 if ((res != 0) && (bffracdig->fixed)) {
pcercuei 0:03b5121a232e 17657 FACET_RESTR_FIXED_ERR(ffracdig)
pcercuei 0:03b5121a232e 17658 }
pcercuei 0:03b5121a232e 17659 }
pcercuei 0:03b5121a232e 17660 /*
pcercuei 0:03b5121a232e 17661 * SCC "fractionDigits less than or equal to totalDigits"
pcercuei 0:03b5121a232e 17662 */
pcercuei 0:03b5121a232e 17663 if (! ftotdig)
pcercuei 0:03b5121a232e 17664 ftotdig = bftotdig;
pcercuei 0:03b5121a232e 17665 if (! ffracdig)
pcercuei 0:03b5121a232e 17666 ffracdig = bffracdig;
pcercuei 0:03b5121a232e 17667 if (ftotdig && ffracdig) {
pcercuei 0:03b5121a232e 17668 res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
pcercuei 0:03b5121a232e 17669 if (res == -2)
pcercuei 0:03b5121a232e 17670 goto internal_error;
pcercuei 0:03b5121a232e 17671 if (res == 1)
pcercuei 0:03b5121a232e 17672 xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
pcercuei 0:03b5121a232e 17673 -1, 1, 0);
pcercuei 0:03b5121a232e 17674 }
pcercuei 0:03b5121a232e 17675 /*
pcercuei 0:03b5121a232e 17676 * *Enumerations* won' be added here, since only the first set
pcercuei 0:03b5121a232e 17677 * of enumerations in the ancestor-or-self axis is used
pcercuei 0:03b5121a232e 17678 * for validation, plus we need to use the base type of those
pcercuei 0:03b5121a232e 17679 * enumerations for whitespace.
pcercuei 0:03b5121a232e 17680 *
pcercuei 0:03b5121a232e 17681 * *Patterns*: won't be add here, since they are ORed at
pcercuei 0:03b5121a232e 17682 * type level and ANDed at ancestor level. This will
pcercuei 0:03b5121a232e 17683 * happed during validation by walking the base axis
pcercuei 0:03b5121a232e 17684 * of the type.
pcercuei 0:03b5121a232e 17685 */
pcercuei 0:03b5121a232e 17686 for (cur = base->facetSet; cur != NULL; cur = cur->next) {
pcercuei 0:03b5121a232e 17687 bfacet = cur->facet;
pcercuei 0:03b5121a232e 17688 /*
pcercuei 0:03b5121a232e 17689 * Special handling of enumerations and patterns.
pcercuei 0:03b5121a232e 17690 * TODO: hmm, they should not appear in the set, so remove this.
pcercuei 0:03b5121a232e 17691 */
pcercuei 0:03b5121a232e 17692 if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
pcercuei 0:03b5121a232e 17693 (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
pcercuei 0:03b5121a232e 17694 continue;
pcercuei 0:03b5121a232e 17695 /*
pcercuei 0:03b5121a232e 17696 * Search for a duplicate facet in the current type.
pcercuei 0:03b5121a232e 17697 */
pcercuei 0:03b5121a232e 17698 link = type->facetSet;
pcercuei 0:03b5121a232e 17699 /* err = 0; */
pcercuei 0:03b5121a232e 17700 /* fixedErr = 0; */
pcercuei 0:03b5121a232e 17701 while (link != NULL) {
pcercuei 0:03b5121a232e 17702 facet = link->facet;
pcercuei 0:03b5121a232e 17703 if (facet->type == bfacet->type) {
pcercuei 0:03b5121a232e 17704 switch (facet->type) {
pcercuei 0:03b5121a232e 17705 case XML_SCHEMA_FACET_WHITESPACE:
pcercuei 0:03b5121a232e 17706 /*
pcercuei 0:03b5121a232e 17707 * The whitespace must be stronger.
pcercuei 0:03b5121a232e 17708 */
pcercuei 0:03b5121a232e 17709 if (facet->whitespace < bfacet->whitespace) {
pcercuei 0:03b5121a232e 17710 FACET_RESTR_ERR(facet,
pcercuei 0:03b5121a232e 17711 "The 'whitespace' value has to be equal to "
pcercuei 0:03b5121a232e 17712 "or stronger than the 'whitespace' value of "
pcercuei 0:03b5121a232e 17713 "the base type")
pcercuei 0:03b5121a232e 17714 }
pcercuei 0:03b5121a232e 17715 if ((bfacet->fixed) &&
pcercuei 0:03b5121a232e 17716 (facet->whitespace != bfacet->whitespace)) {
pcercuei 0:03b5121a232e 17717 FACET_RESTR_FIXED_ERR(facet)
pcercuei 0:03b5121a232e 17718 }
pcercuei 0:03b5121a232e 17719 break;
pcercuei 0:03b5121a232e 17720 default:
pcercuei 0:03b5121a232e 17721 break;
pcercuei 0:03b5121a232e 17722 }
pcercuei 0:03b5121a232e 17723 /* Duplicate found. */
pcercuei 0:03b5121a232e 17724 break;
pcercuei 0:03b5121a232e 17725 }
pcercuei 0:03b5121a232e 17726 link = link->next;
pcercuei 0:03b5121a232e 17727 }
pcercuei 0:03b5121a232e 17728 /*
pcercuei 0:03b5121a232e 17729 * If no duplicate was found: add the base types's facet
pcercuei 0:03b5121a232e 17730 * to the set.
pcercuei 0:03b5121a232e 17731 */
pcercuei 0:03b5121a232e 17732 if (link == NULL) {
pcercuei 0:03b5121a232e 17733 link = (xmlSchemaFacetLinkPtr)
pcercuei 0:03b5121a232e 17734 xmlMalloc(sizeof(xmlSchemaFacetLink));
pcercuei 0:03b5121a232e 17735 if (link == NULL) {
pcercuei 0:03b5121a232e 17736 xmlSchemaPErrMemory(pctxt,
pcercuei 0:03b5121a232e 17737 "deriving facets, creating a facet link", NULL);
pcercuei 0:03b5121a232e 17738 return (-1);
pcercuei 0:03b5121a232e 17739 }
pcercuei 0:03b5121a232e 17740 link->facet = cur->facet;
pcercuei 0:03b5121a232e 17741 link->next = NULL;
pcercuei 0:03b5121a232e 17742 if (last == NULL)
pcercuei 0:03b5121a232e 17743 type->facetSet = link;
pcercuei 0:03b5121a232e 17744 else
pcercuei 0:03b5121a232e 17745 last->next = link;
pcercuei 0:03b5121a232e 17746 last = link;
pcercuei 0:03b5121a232e 17747 }
pcercuei 0:03b5121a232e 17748
pcercuei 0:03b5121a232e 17749 }
pcercuei 0:03b5121a232e 17750
pcercuei 0:03b5121a232e 17751 return (0);
pcercuei 0:03b5121a232e 17752 internal_error:
pcercuei 0:03b5121a232e 17753 PERROR_INT("xmlSchemaDeriveAndValidateFacets",
pcercuei 0:03b5121a232e 17754 "an error occured");
pcercuei 0:03b5121a232e 17755 return (-1);
pcercuei 0:03b5121a232e 17756 }
pcercuei 0:03b5121a232e 17757
pcercuei 0:03b5121a232e 17758 static int
pcercuei 0:03b5121a232e 17759 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 17760 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 17761 {
pcercuei 0:03b5121a232e 17762 xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
pcercuei 0:03b5121a232e 17763 /*
pcercuei 0:03b5121a232e 17764 * The actual value is then formed by replacing any union type
pcercuei 0:03b5121a232e 17765 * definition in the `explicit members` with the members of their
pcercuei 0:03b5121a232e 17766 * {member type definitions}, in order.
pcercuei 0:03b5121a232e 17767 *
pcercuei 0:03b5121a232e 17768 * TODO: There's a bug entry at
pcercuei 0:03b5121a232e 17769 * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
pcercuei 0:03b5121a232e 17770 * which indicates that we'll keep the union types the future.
pcercuei 0:03b5121a232e 17771 */
pcercuei 0:03b5121a232e 17772 link = type->memberTypes;
pcercuei 0:03b5121a232e 17773 while (link != NULL) {
pcercuei 0:03b5121a232e 17774
pcercuei 0:03b5121a232e 17775 if (WXS_IS_TYPE_NOT_FIXED(link->type))
pcercuei 0:03b5121a232e 17776 xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
pcercuei 0:03b5121a232e 17777
pcercuei 0:03b5121a232e 17778 if (WXS_IS_UNION(link->type)) {
pcercuei 0:03b5121a232e 17779 subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
pcercuei 0:03b5121a232e 17780 if (subLink != NULL) {
pcercuei 0:03b5121a232e 17781 link->type = subLink->type;
pcercuei 0:03b5121a232e 17782 if (subLink->next != NULL) {
pcercuei 0:03b5121a232e 17783 lastLink = link->next;
pcercuei 0:03b5121a232e 17784 subLink = subLink->next;
pcercuei 0:03b5121a232e 17785 prevLink = link;
pcercuei 0:03b5121a232e 17786 while (subLink != NULL) {
pcercuei 0:03b5121a232e 17787 newLink = (xmlSchemaTypeLinkPtr)
pcercuei 0:03b5121a232e 17788 xmlMalloc(sizeof(xmlSchemaTypeLink));
pcercuei 0:03b5121a232e 17789 if (newLink == NULL) {
pcercuei 0:03b5121a232e 17790 xmlSchemaPErrMemory(pctxt, "allocating a type link",
pcercuei 0:03b5121a232e 17791 NULL);
pcercuei 0:03b5121a232e 17792 return (-1);
pcercuei 0:03b5121a232e 17793 }
pcercuei 0:03b5121a232e 17794 newLink->type = subLink->type;
pcercuei 0:03b5121a232e 17795 prevLink->next = newLink;
pcercuei 0:03b5121a232e 17796 prevLink = newLink;
pcercuei 0:03b5121a232e 17797 newLink->next = lastLink;
pcercuei 0:03b5121a232e 17798
pcercuei 0:03b5121a232e 17799 subLink = subLink->next;
pcercuei 0:03b5121a232e 17800 }
pcercuei 0:03b5121a232e 17801 }
pcercuei 0:03b5121a232e 17802 }
pcercuei 0:03b5121a232e 17803 }
pcercuei 0:03b5121a232e 17804 link = link->next;
pcercuei 0:03b5121a232e 17805 }
pcercuei 0:03b5121a232e 17806 return (0);
pcercuei 0:03b5121a232e 17807 }
pcercuei 0:03b5121a232e 17808
pcercuei 0:03b5121a232e 17809 static void
pcercuei 0:03b5121a232e 17810 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 17811 {
pcercuei 0:03b5121a232e 17812 int has = 0, needVal = 0, normVal = 0;
pcercuei 0:03b5121a232e 17813
pcercuei 0:03b5121a232e 17814 has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
pcercuei 0:03b5121a232e 17815 if (has) {
pcercuei 0:03b5121a232e 17816 needVal = (type->baseType->flags &
pcercuei 0:03b5121a232e 17817 XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
pcercuei 0:03b5121a232e 17818 normVal = (type->baseType->flags &
pcercuei 0:03b5121a232e 17819 XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
pcercuei 0:03b5121a232e 17820 }
pcercuei 0:03b5121a232e 17821 if (type->facets != NULL) {
pcercuei 0:03b5121a232e 17822 xmlSchemaFacetPtr fac;
pcercuei 0:03b5121a232e 17823
pcercuei 0:03b5121a232e 17824 for (fac = type->facets; fac != NULL; fac = fac->next) {
pcercuei 0:03b5121a232e 17825 switch (fac->type) {
pcercuei 0:03b5121a232e 17826 case XML_SCHEMA_FACET_WHITESPACE:
pcercuei 0:03b5121a232e 17827 break;
pcercuei 0:03b5121a232e 17828 case XML_SCHEMA_FACET_PATTERN:
pcercuei 0:03b5121a232e 17829 normVal = 1;
pcercuei 0:03b5121a232e 17830 has = 1;
pcercuei 0:03b5121a232e 17831 break;
pcercuei 0:03b5121a232e 17832 case XML_SCHEMA_FACET_ENUMERATION:
pcercuei 0:03b5121a232e 17833 needVal = 1;
pcercuei 0:03b5121a232e 17834 normVal = 1;
pcercuei 0:03b5121a232e 17835 has = 1;
pcercuei 0:03b5121a232e 17836 break;
pcercuei 0:03b5121a232e 17837 default:
pcercuei 0:03b5121a232e 17838 has = 1;
pcercuei 0:03b5121a232e 17839 break;
pcercuei 0:03b5121a232e 17840 }
pcercuei 0:03b5121a232e 17841 }
pcercuei 0:03b5121a232e 17842 }
pcercuei 0:03b5121a232e 17843 if (normVal)
pcercuei 0:03b5121a232e 17844 type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
pcercuei 0:03b5121a232e 17845 if (needVal)
pcercuei 0:03b5121a232e 17846 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
pcercuei 0:03b5121a232e 17847 if (has)
pcercuei 0:03b5121a232e 17848 type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
pcercuei 0:03b5121a232e 17849
pcercuei 0:03b5121a232e 17850 if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
pcercuei 0:03b5121a232e 17851 xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
pcercuei 0:03b5121a232e 17852 /*
pcercuei 0:03b5121a232e 17853 * OPTIMIZE VAL TODO: Some facets need a computed value.
pcercuei 0:03b5121a232e 17854 */
pcercuei 0:03b5121a232e 17855 if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
pcercuei 0:03b5121a232e 17856 (prim->builtInType != XML_SCHEMAS_STRING)) {
pcercuei 0:03b5121a232e 17857 type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
pcercuei 0:03b5121a232e 17858 }
pcercuei 0:03b5121a232e 17859 }
pcercuei 0:03b5121a232e 17860 }
pcercuei 0:03b5121a232e 17861
pcercuei 0:03b5121a232e 17862 static int
pcercuei 0:03b5121a232e 17863 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 17864 {
pcercuei 0:03b5121a232e 17865
pcercuei 0:03b5121a232e 17866
pcercuei 0:03b5121a232e 17867 /*
pcercuei 0:03b5121a232e 17868 * Evaluate the whitespace-facet value.
pcercuei 0:03b5121a232e 17869 */
pcercuei 0:03b5121a232e 17870 if (WXS_IS_LIST(type)) {
pcercuei 0:03b5121a232e 17871 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
pcercuei 0:03b5121a232e 17872 return (0);
pcercuei 0:03b5121a232e 17873 } else if (WXS_IS_UNION(type))
pcercuei 0:03b5121a232e 17874 return (0);
pcercuei 0:03b5121a232e 17875
pcercuei 0:03b5121a232e 17876 if (type->facetSet != NULL) {
pcercuei 0:03b5121a232e 17877 xmlSchemaFacetLinkPtr lin;
pcercuei 0:03b5121a232e 17878
pcercuei 0:03b5121a232e 17879 for (lin = type->facetSet; lin != NULL; lin = lin->next) {
pcercuei 0:03b5121a232e 17880 if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
pcercuei 0:03b5121a232e 17881 switch (lin->facet->whitespace) {
pcercuei 0:03b5121a232e 17882 case XML_SCHEMAS_FACET_PRESERVE:
pcercuei 0:03b5121a232e 17883 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
pcercuei 0:03b5121a232e 17884 break;
pcercuei 0:03b5121a232e 17885 case XML_SCHEMAS_FACET_REPLACE:
pcercuei 0:03b5121a232e 17886 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
pcercuei 0:03b5121a232e 17887 break;
pcercuei 0:03b5121a232e 17888 case XML_SCHEMAS_FACET_COLLAPSE:
pcercuei 0:03b5121a232e 17889 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
pcercuei 0:03b5121a232e 17890 break;
pcercuei 0:03b5121a232e 17891 default:
pcercuei 0:03b5121a232e 17892 return (-1);
pcercuei 0:03b5121a232e 17893 }
pcercuei 0:03b5121a232e 17894 return (0);
pcercuei 0:03b5121a232e 17895 }
pcercuei 0:03b5121a232e 17896 }
pcercuei 0:03b5121a232e 17897 }
pcercuei 0:03b5121a232e 17898 /*
pcercuei 0:03b5121a232e 17899 * For all `atomic` datatypes other than string (and types `derived`
pcercuei 0:03b5121a232e 17900 * by `restriction` from it) the value of whiteSpace is fixed to
pcercuei 0:03b5121a232e 17901 * collapse
pcercuei 0:03b5121a232e 17902 */
pcercuei 0:03b5121a232e 17903 {
pcercuei 0:03b5121a232e 17904 xmlSchemaTypePtr anc;
pcercuei 0:03b5121a232e 17905
pcercuei 0:03b5121a232e 17906 for (anc = type->baseType; anc != NULL &&
pcercuei 0:03b5121a232e 17907 anc->builtInType != XML_SCHEMAS_ANYTYPE;
pcercuei 0:03b5121a232e 17908 anc = anc->baseType) {
pcercuei 0:03b5121a232e 17909
pcercuei 0:03b5121a232e 17910 if (anc->type == XML_SCHEMA_TYPE_BASIC) {
pcercuei 0:03b5121a232e 17911 if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
pcercuei 0:03b5121a232e 17912 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
pcercuei 0:03b5121a232e 17913
pcercuei 0:03b5121a232e 17914 } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
pcercuei 0:03b5121a232e 17915 (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
pcercuei 0:03b5121a232e 17916 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
pcercuei 0:03b5121a232e 17917
pcercuei 0:03b5121a232e 17918 } else
pcercuei 0:03b5121a232e 17919 type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
pcercuei 0:03b5121a232e 17920 break;
pcercuei 0:03b5121a232e 17921 }
pcercuei 0:03b5121a232e 17922 }
pcercuei 0:03b5121a232e 17923 }
pcercuei 0:03b5121a232e 17924 return (0);
pcercuei 0:03b5121a232e 17925 }
pcercuei 0:03b5121a232e 17926
pcercuei 0:03b5121a232e 17927 static int
pcercuei 0:03b5121a232e 17928 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 17929 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 17930 {
pcercuei 0:03b5121a232e 17931 if (type->type != XML_SCHEMA_TYPE_SIMPLE)
pcercuei 0:03b5121a232e 17932 return(0);
pcercuei 0:03b5121a232e 17933 if (! WXS_IS_TYPE_NOT_FIXED_1(type))
pcercuei 0:03b5121a232e 17934 return(0);
pcercuei 0:03b5121a232e 17935 type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
pcercuei 0:03b5121a232e 17936
pcercuei 0:03b5121a232e 17937 if (WXS_IS_LIST(type)) {
pcercuei 0:03b5121a232e 17938 /*
pcercuei 0:03b5121a232e 17939 * Corresponds to <simpleType><list>...
pcercuei 0:03b5121a232e 17940 */
pcercuei 0:03b5121a232e 17941 if (type->subtypes == NULL) {
pcercuei 0:03b5121a232e 17942 /*
pcercuei 0:03b5121a232e 17943 * This one is really needed, so get out.
pcercuei 0:03b5121a232e 17944 */
pcercuei 0:03b5121a232e 17945 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
pcercuei 0:03b5121a232e 17946 "list type has no item-type assigned");
pcercuei 0:03b5121a232e 17947 return(-1);
pcercuei 0:03b5121a232e 17948 }
pcercuei 0:03b5121a232e 17949 } else if (WXS_IS_UNION(type)) {
pcercuei 0:03b5121a232e 17950 /*
pcercuei 0:03b5121a232e 17951 * Corresponds to <simpleType><union>...
pcercuei 0:03b5121a232e 17952 */
pcercuei 0:03b5121a232e 17953 if (type->memberTypes == NULL) {
pcercuei 0:03b5121a232e 17954 /*
pcercuei 0:03b5121a232e 17955 * This one is really needed, so get out.
pcercuei 0:03b5121a232e 17956 */
pcercuei 0:03b5121a232e 17957 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
pcercuei 0:03b5121a232e 17958 "union type has no member-types assigned");
pcercuei 0:03b5121a232e 17959 return(-1);
pcercuei 0:03b5121a232e 17960 }
pcercuei 0:03b5121a232e 17961 } else {
pcercuei 0:03b5121a232e 17962 /*
pcercuei 0:03b5121a232e 17963 * Corresponds to <simpleType><restriction>...
pcercuei 0:03b5121a232e 17964 */
pcercuei 0:03b5121a232e 17965 if (type->baseType == NULL) {
pcercuei 0:03b5121a232e 17966 PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
pcercuei 0:03b5121a232e 17967 "type has no base-type assigned");
pcercuei 0:03b5121a232e 17968 return(-1);
pcercuei 0:03b5121a232e 17969 }
pcercuei 0:03b5121a232e 17970 if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
pcercuei 0:03b5121a232e 17971 if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
pcercuei 0:03b5121a232e 17972 return(-1);
pcercuei 0:03b5121a232e 17973 /*
pcercuei 0:03b5121a232e 17974 * Variety
pcercuei 0:03b5121a232e 17975 * If the <restriction> alternative is chosen, then the
pcercuei 0:03b5121a232e 17976 * {variety} of the {base type definition}.
pcercuei 0:03b5121a232e 17977 */
pcercuei 0:03b5121a232e 17978 if (WXS_IS_ATOMIC(type->baseType))
pcercuei 0:03b5121a232e 17979 type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
pcercuei 0:03b5121a232e 17980 else if (WXS_IS_LIST(type->baseType)) {
pcercuei 0:03b5121a232e 17981 type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
pcercuei 0:03b5121a232e 17982 /*
pcercuei 0:03b5121a232e 17983 * Inherit the itemType.
pcercuei 0:03b5121a232e 17984 */
pcercuei 0:03b5121a232e 17985 type->subtypes = type->baseType->subtypes;
pcercuei 0:03b5121a232e 17986 } else if (WXS_IS_UNION(type->baseType)) {
pcercuei 0:03b5121a232e 17987 type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
pcercuei 0:03b5121a232e 17988 /*
pcercuei 0:03b5121a232e 17989 * NOTE that we won't assign the memberTypes of the base,
pcercuei 0:03b5121a232e 17990 * since this will make trouble when freeing them; we will
pcercuei 0:03b5121a232e 17991 * use a lookup function to access them instead.
pcercuei 0:03b5121a232e 17992 */
pcercuei 0:03b5121a232e 17993 }
pcercuei 0:03b5121a232e 17994 }
pcercuei 0:03b5121a232e 17995 return(0);
pcercuei 0:03b5121a232e 17996 }
pcercuei 0:03b5121a232e 17997
pcercuei 0:03b5121a232e 17998 #ifdef DEBUG_TYPE
pcercuei 0:03b5121a232e 17999 static void
pcercuei 0:03b5121a232e 18000 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 18001 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 18002 {
pcercuei 0:03b5121a232e 18003 if (type->node != NULL) {
pcercuei 0:03b5121a232e 18004 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 18005 "Type of %s : %s:%d :", name,
pcercuei 0:03b5121a232e 18006 type->node->doc->URL,
pcercuei 0:03b5121a232e 18007 xmlGetLineNo(type->node));
pcercuei 0:03b5121a232e 18008 } else {
pcercuei 0:03b5121a232e 18009 xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
pcercuei 0:03b5121a232e 18010 }
pcercuei 0:03b5121a232e 18011 if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
pcercuei 0:03b5121a232e 18012 switch (type->contentType) {
pcercuei 0:03b5121a232e 18013 case XML_SCHEMA_CONTENT_SIMPLE:
pcercuei 0:03b5121a232e 18014 xmlGenericError(xmlGenericErrorContext, "simple\n");
pcercuei 0:03b5121a232e 18015 break;
pcercuei 0:03b5121a232e 18016 case XML_SCHEMA_CONTENT_ELEMENTS:
pcercuei 0:03b5121a232e 18017 xmlGenericError(xmlGenericErrorContext, "elements\n");
pcercuei 0:03b5121a232e 18018 break;
pcercuei 0:03b5121a232e 18019 case XML_SCHEMA_CONTENT_UNKNOWN:
pcercuei 0:03b5121a232e 18020 xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
pcercuei 0:03b5121a232e 18021 break;
pcercuei 0:03b5121a232e 18022 case XML_SCHEMA_CONTENT_EMPTY:
pcercuei 0:03b5121a232e 18023 xmlGenericError(xmlGenericErrorContext, "empty\n");
pcercuei 0:03b5121a232e 18024 break;
pcercuei 0:03b5121a232e 18025 case XML_SCHEMA_CONTENT_MIXED:
pcercuei 0:03b5121a232e 18026 if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
pcercuei 0:03b5121a232e 18027 type->subtypes))
pcercuei 0:03b5121a232e 18028 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 18029 "mixed as emptiable particle\n");
pcercuei 0:03b5121a232e 18030 else
pcercuei 0:03b5121a232e 18031 xmlGenericError(xmlGenericErrorContext, "mixed\n");
pcercuei 0:03b5121a232e 18032 break;
pcercuei 0:03b5121a232e 18033 /* Removed, since not used. */
pcercuei 0:03b5121a232e 18034 /*
pcercuei 0:03b5121a232e 18035 case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
pcercuei 0:03b5121a232e 18036 xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
pcercuei 0:03b5121a232e 18037 break;
pcercuei 0:03b5121a232e 18038 */
pcercuei 0:03b5121a232e 18039 case XML_SCHEMA_CONTENT_BASIC:
pcercuei 0:03b5121a232e 18040 xmlGenericError(xmlGenericErrorContext, "basic\n");
pcercuei 0:03b5121a232e 18041 break;
pcercuei 0:03b5121a232e 18042 default:
pcercuei 0:03b5121a232e 18043 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 18044 "not registered !!!\n");
pcercuei 0:03b5121a232e 18045 break;
pcercuei 0:03b5121a232e 18046 }
pcercuei 0:03b5121a232e 18047 }
pcercuei 0:03b5121a232e 18048 }
pcercuei 0:03b5121a232e 18049 #endif
pcercuei 0:03b5121a232e 18050
pcercuei 0:03b5121a232e 18051 /*
pcercuei 0:03b5121a232e 18052 * 3.14.6 Constraints on Simple Type Definition Schema Components
pcercuei 0:03b5121a232e 18053 */
pcercuei 0:03b5121a232e 18054 static int
pcercuei 0:03b5121a232e 18055 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 18056 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 18057 {
pcercuei 0:03b5121a232e 18058 int res, olderrs = pctxt->nberrors;
pcercuei 0:03b5121a232e 18059
pcercuei 0:03b5121a232e 18060 if (type->type != XML_SCHEMA_TYPE_SIMPLE)
pcercuei 0:03b5121a232e 18061 return(-1);
pcercuei 0:03b5121a232e 18062
pcercuei 0:03b5121a232e 18063 if (! WXS_IS_TYPE_NOT_FIXED(type))
pcercuei 0:03b5121a232e 18064 return(0);
pcercuei 0:03b5121a232e 18065
pcercuei 0:03b5121a232e 18066 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
pcercuei 0:03b5121a232e 18067 type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
pcercuei 0:03b5121a232e 18068
pcercuei 0:03b5121a232e 18069 if (type->baseType == NULL) {
pcercuei 0:03b5121a232e 18070 PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
pcercuei 0:03b5121a232e 18071 "missing baseType");
pcercuei 0:03b5121a232e 18072 goto exit_failure;
pcercuei 0:03b5121a232e 18073 }
pcercuei 0:03b5121a232e 18074 if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
pcercuei 0:03b5121a232e 18075 xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
pcercuei 0:03b5121a232e 18076 /*
pcercuei 0:03b5121a232e 18077 * If a member type of a union is a union itself, we need to substitute
pcercuei 0:03b5121a232e 18078 * that member type for its member types.
pcercuei 0:03b5121a232e 18079 * NOTE that this might change in WXS 1.1; i.e. we will keep the union
pcercuei 0:03b5121a232e 18080 * types in WXS 1.1.
pcercuei 0:03b5121a232e 18081 */
pcercuei 0:03b5121a232e 18082 if ((type->memberTypes != NULL) &&
pcercuei 0:03b5121a232e 18083 (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
pcercuei 0:03b5121a232e 18084 return(-1);
pcercuei 0:03b5121a232e 18085 /*
pcercuei 0:03b5121a232e 18086 * SPEC src-simple-type 1
pcercuei 0:03b5121a232e 18087 * "The corresponding simple type definition, if any, must satisfy
pcercuei 0:03b5121a232e 18088 * the conditions set out in Constraints on Simple Type Definition
pcercuei 0:03b5121a232e 18089 * Schema Components ($3.14.6)."
pcercuei 0:03b5121a232e 18090 */
pcercuei 0:03b5121a232e 18091 /*
pcercuei 0:03b5121a232e 18092 * Schema Component Constraint: Simple Type Definition Properties Correct
pcercuei 0:03b5121a232e 18093 * (st-props-correct)
pcercuei 0:03b5121a232e 18094 */
pcercuei 0:03b5121a232e 18095 res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
pcercuei 0:03b5121a232e 18096 HFAILURE HERROR
pcercuei 0:03b5121a232e 18097 /*
pcercuei 0:03b5121a232e 18098 * Schema Component Constraint: Derivation Valid (Restriction, Simple)
pcercuei 0:03b5121a232e 18099 * (cos-st-restricts)
pcercuei 0:03b5121a232e 18100 */
pcercuei 0:03b5121a232e 18101 res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
pcercuei 0:03b5121a232e 18102 HFAILURE HERROR
pcercuei 0:03b5121a232e 18103 /*
pcercuei 0:03b5121a232e 18104 * TODO: Removed the error report, since it got annoying to get an
pcercuei 0:03b5121a232e 18105 * extra error report, if anything failed until now.
pcercuei 0:03b5121a232e 18106 * Enable this if needed.
pcercuei 0:03b5121a232e 18107 *
pcercuei 0:03b5121a232e 18108 * xmlSchemaPErr(ctxt, type->node,
pcercuei 0:03b5121a232e 18109 * XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
pcercuei 0:03b5121a232e 18110 * "Simple type '%s' does not satisfy the constraints "
pcercuei 0:03b5121a232e 18111 * "on simple type definitions.\n",
pcercuei 0:03b5121a232e 18112 * type->name, NULL);
pcercuei 0:03b5121a232e 18113 */
pcercuei 0:03b5121a232e 18114 /*
pcercuei 0:03b5121a232e 18115 * Schema Component Constraint: Simple Type Restriction (Facets)
pcercuei 0:03b5121a232e 18116 * (st-restrict-facets)
pcercuei 0:03b5121a232e 18117 */
pcercuei 0:03b5121a232e 18118 res = xmlSchemaCheckFacetValues(type, pctxt);
pcercuei 0:03b5121a232e 18119 HFAILURE HERROR
pcercuei 0:03b5121a232e 18120 if ((type->facetSet != NULL) ||
pcercuei 0:03b5121a232e 18121 (type->baseType->facetSet != NULL)) {
pcercuei 0:03b5121a232e 18122 res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
pcercuei 0:03b5121a232e 18123 HFAILURE HERROR
pcercuei 0:03b5121a232e 18124 }
pcercuei 0:03b5121a232e 18125 /*
pcercuei 0:03b5121a232e 18126 * Whitespace value.
pcercuei 0:03b5121a232e 18127 */
pcercuei 0:03b5121a232e 18128 res = xmlSchemaTypeFixupWhitespace(type);
pcercuei 0:03b5121a232e 18129 HFAILURE HERROR
pcercuei 0:03b5121a232e 18130 xmlSchemaTypeFixupOptimFacets(type);
pcercuei 0:03b5121a232e 18131
pcercuei 0:03b5121a232e 18132 exit_error:
pcercuei 0:03b5121a232e 18133 #ifdef DEBUG_TYPE
pcercuei 0:03b5121a232e 18134 xmlSchemaDebugFixedType(pctxt, type);
pcercuei 0:03b5121a232e 18135 #endif
pcercuei 0:03b5121a232e 18136 if (olderrs != pctxt->nberrors)
pcercuei 0:03b5121a232e 18137 return(pctxt->err);
pcercuei 0:03b5121a232e 18138 return(0);
pcercuei 0:03b5121a232e 18139
pcercuei 0:03b5121a232e 18140 exit_failure:
pcercuei 0:03b5121a232e 18141 #ifdef DEBUG_TYPE
pcercuei 0:03b5121a232e 18142 xmlSchemaDebugFixedType(pctxt, type);
pcercuei 0:03b5121a232e 18143 #endif
pcercuei 0:03b5121a232e 18144 return(-1);
pcercuei 0:03b5121a232e 18145 }
pcercuei 0:03b5121a232e 18146
pcercuei 0:03b5121a232e 18147 static int
pcercuei 0:03b5121a232e 18148 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 18149 xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 18150 {
pcercuei 0:03b5121a232e 18151 int res = 0, olderrs = pctxt->nberrors;
pcercuei 0:03b5121a232e 18152 xmlSchemaTypePtr baseType = type->baseType;
pcercuei 0:03b5121a232e 18153
pcercuei 0:03b5121a232e 18154 if (! WXS_IS_TYPE_NOT_FIXED(type))
pcercuei 0:03b5121a232e 18155 return(0);
pcercuei 0:03b5121a232e 18156 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
pcercuei 0:03b5121a232e 18157 if (baseType == NULL) {
pcercuei 0:03b5121a232e 18158 PERROR_INT("xmlSchemaFixupComplexType",
pcercuei 0:03b5121a232e 18159 "missing baseType");
pcercuei 0:03b5121a232e 18160 goto exit_failure;
pcercuei 0:03b5121a232e 18161 }
pcercuei 0:03b5121a232e 18162 /*
pcercuei 0:03b5121a232e 18163 * Fixup the base type.
pcercuei 0:03b5121a232e 18164 */
pcercuei 0:03b5121a232e 18165 if (WXS_IS_TYPE_NOT_FIXED(baseType))
pcercuei 0:03b5121a232e 18166 xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
pcercuei 0:03b5121a232e 18167 if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
pcercuei 0:03b5121a232e 18168 /*
pcercuei 0:03b5121a232e 18169 * Skip fixup if the base type is invalid.
pcercuei 0:03b5121a232e 18170 * TODO: Generate a warning!
pcercuei 0:03b5121a232e 18171 */
pcercuei 0:03b5121a232e 18172 return(0);
pcercuei 0:03b5121a232e 18173 }
pcercuei 0:03b5121a232e 18174 /*
pcercuei 0:03b5121a232e 18175 * This basically checks if the base type can be derived.
pcercuei 0:03b5121a232e 18176 */
pcercuei 0:03b5121a232e 18177 res = xmlSchemaCheckSRCCT(pctxt, type);
pcercuei 0:03b5121a232e 18178 HFAILURE HERROR
pcercuei 0:03b5121a232e 18179 /*
pcercuei 0:03b5121a232e 18180 * Fixup the content type.
pcercuei 0:03b5121a232e 18181 */
pcercuei 0:03b5121a232e 18182 if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
pcercuei 0:03b5121a232e 18183 /*
pcercuei 0:03b5121a232e 18184 * Corresponds to <complexType><simpleContent>...
pcercuei 0:03b5121a232e 18185 */
pcercuei 0:03b5121a232e 18186 if ((WXS_IS_COMPLEX(baseType)) &&
pcercuei 0:03b5121a232e 18187 (baseType->contentTypeDef != NULL) &&
pcercuei 0:03b5121a232e 18188 (WXS_IS_RESTRICTION(type))) {
pcercuei 0:03b5121a232e 18189 xmlSchemaTypePtr contentBase, content;
pcercuei 0:03b5121a232e 18190 #ifdef ENABLE_NAMED_LOCALS
pcercuei 0:03b5121a232e 18191 char buf[30];
pcercuei 0:03b5121a232e 18192 const xmlChar *tmpname;
pcercuei 0:03b5121a232e 18193 #endif
pcercuei 0:03b5121a232e 18194 /*
pcercuei 0:03b5121a232e 18195 * SPEC (1) If <restriction> + base type is <complexType>,
pcercuei 0:03b5121a232e 18196 * "whose own {content type} is a simple type..."
pcercuei 0:03b5121a232e 18197 */
pcercuei 0:03b5121a232e 18198 if (type->contentTypeDef != NULL) {
pcercuei 0:03b5121a232e 18199 /*
pcercuei 0:03b5121a232e 18200 * SPEC (1.1) "the simple type definition corresponding to the
pcercuei 0:03b5121a232e 18201 * <simpleType> among the [children] of <restriction> if there
pcercuei 0:03b5121a232e 18202 * is one;"
pcercuei 0:03b5121a232e 18203 * Note that this "<simpleType> among the [children]" was put
pcercuei 0:03b5121a232e 18204 * into ->contentTypeDef during parsing.
pcercuei 0:03b5121a232e 18205 */
pcercuei 0:03b5121a232e 18206 contentBase = type->contentTypeDef;
pcercuei 0:03b5121a232e 18207 type->contentTypeDef = NULL;
pcercuei 0:03b5121a232e 18208 } else {
pcercuei 0:03b5121a232e 18209 /*
pcercuei 0:03b5121a232e 18210 * (1.2) "...otherwise (<restriction> has no <simpleType>
pcercuei 0:03b5121a232e 18211 * among its [children]), the simple type definition which
pcercuei 0:03b5121a232e 18212 * is the {content type} of the ... base type."
pcercuei 0:03b5121a232e 18213 */
pcercuei 0:03b5121a232e 18214 contentBase = baseType->contentTypeDef;
pcercuei 0:03b5121a232e 18215 }
pcercuei 0:03b5121a232e 18216 /*
pcercuei 0:03b5121a232e 18217 * SPEC
pcercuei 0:03b5121a232e 18218 * "... a simple type definition which restricts the simple
pcercuei 0:03b5121a232e 18219 * type definition identified in clause 1.1 or clause 1.2
pcercuei 0:03b5121a232e 18220 * with a set of facet components"
pcercuei 0:03b5121a232e 18221 *
pcercuei 0:03b5121a232e 18222 * Create the anonymous simple type, which will be the content
pcercuei 0:03b5121a232e 18223 * type of the complex type.
pcercuei 0:03b5121a232e 18224 */
pcercuei 0:03b5121a232e 18225 #ifdef ENABLE_NAMED_LOCALS
pcercuei 0:03b5121a232e 18226 snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
pcercuei 0:03b5121a232e 18227 tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
pcercuei 0:03b5121a232e 18228 content = xmlSchemaAddType(pctxt, pctxt->schema,
pcercuei 0:03b5121a232e 18229 XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
pcercuei 0:03b5121a232e 18230 type->node, 0);
pcercuei 0:03b5121a232e 18231 #else
pcercuei 0:03b5121a232e 18232 content = xmlSchemaAddType(pctxt, pctxt->schema,
pcercuei 0:03b5121a232e 18233 XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
pcercuei 0:03b5121a232e 18234 type->node, 0);
pcercuei 0:03b5121a232e 18235 #endif
pcercuei 0:03b5121a232e 18236 if (content == NULL)
pcercuei 0:03b5121a232e 18237 goto exit_failure;
pcercuei 0:03b5121a232e 18238 /*
pcercuei 0:03b5121a232e 18239 * We will use the same node as for the <complexType>
pcercuei 0:03b5121a232e 18240 * to have it somehow anchored in the schema doc.
pcercuei 0:03b5121a232e 18241 */
pcercuei 0:03b5121a232e 18242 content->type = XML_SCHEMA_TYPE_SIMPLE;
pcercuei 0:03b5121a232e 18243 content->baseType = contentBase;
pcercuei 0:03b5121a232e 18244 /*
pcercuei 0:03b5121a232e 18245 * Move the facets, previously anchored on the
pcercuei 0:03b5121a232e 18246 * complexType during parsing.
pcercuei 0:03b5121a232e 18247 */
pcercuei 0:03b5121a232e 18248 content->facets = type->facets;
pcercuei 0:03b5121a232e 18249 type->facets = NULL;
pcercuei 0:03b5121a232e 18250 content->facetSet = type->facetSet;
pcercuei 0:03b5121a232e 18251 type->facetSet = NULL;
pcercuei 0:03b5121a232e 18252
pcercuei 0:03b5121a232e 18253 type->contentTypeDef = content;
pcercuei 0:03b5121a232e 18254 if (WXS_IS_TYPE_NOT_FIXED(contentBase))
pcercuei 0:03b5121a232e 18255 xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
pcercuei 0:03b5121a232e 18256 /*
pcercuei 0:03b5121a232e 18257 * Fixup the newly created type. We don't need to check
pcercuei 0:03b5121a232e 18258 * for circularity here.
pcercuei 0:03b5121a232e 18259 */
pcercuei 0:03b5121a232e 18260 res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
pcercuei 0:03b5121a232e 18261 HFAILURE HERROR
pcercuei 0:03b5121a232e 18262 res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
pcercuei 0:03b5121a232e 18263 HFAILURE HERROR
pcercuei 0:03b5121a232e 18264
pcercuei 0:03b5121a232e 18265 } else if ((WXS_IS_COMPLEX(baseType)) &&
pcercuei 0:03b5121a232e 18266 (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
pcercuei 0:03b5121a232e 18267 (WXS_IS_RESTRICTION(type))) {
pcercuei 0:03b5121a232e 18268 /*
pcercuei 0:03b5121a232e 18269 * SPEC (2) If <restriction> + base is a mixed <complexType> with
pcercuei 0:03b5121a232e 18270 * an emptiable particle, then a simple type definition which
pcercuei 0:03b5121a232e 18271 * restricts the <restriction>'s <simpleType> child.
pcercuei 0:03b5121a232e 18272 */
pcercuei 0:03b5121a232e 18273 if ((type->contentTypeDef == NULL) ||
pcercuei 0:03b5121a232e 18274 (type->contentTypeDef->baseType == NULL)) {
pcercuei 0:03b5121a232e 18275 /*
pcercuei 0:03b5121a232e 18276 * TODO: Check if this ever happens.
pcercuei 0:03b5121a232e 18277 */
pcercuei 0:03b5121a232e 18278 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 18279 XML_SCHEMAP_INTERNAL,
pcercuei 0:03b5121a232e 18280 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 18281 "Internal error: xmlSchemaTypeFixup, "
pcercuei 0:03b5121a232e 18282 "complex type '%s': the <simpleContent><restriction> "
pcercuei 0:03b5121a232e 18283 "is missing a <simpleType> child, but was not catched "
pcercuei 0:03b5121a232e 18284 "by xmlSchemaCheckSRCCT()", type->name);
pcercuei 0:03b5121a232e 18285 goto exit_failure;
pcercuei 0:03b5121a232e 18286 }
pcercuei 0:03b5121a232e 18287 } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
pcercuei 0:03b5121a232e 18288 /*
pcercuei 0:03b5121a232e 18289 * SPEC (3) If <extension> + base is <complexType> with
pcercuei 0:03b5121a232e 18290 * <simpleType> content, "...then the {content type} of that
pcercuei 0:03b5121a232e 18291 * complex type definition"
pcercuei 0:03b5121a232e 18292 */
pcercuei 0:03b5121a232e 18293 if (baseType->contentTypeDef == NULL) {
pcercuei 0:03b5121a232e 18294 /*
pcercuei 0:03b5121a232e 18295 * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
pcercuei 0:03b5121a232e 18296 * should have catched this already.
pcercuei 0:03b5121a232e 18297 */
pcercuei 0:03b5121a232e 18298 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 18299 XML_SCHEMAP_INTERNAL,
pcercuei 0:03b5121a232e 18300 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 18301 "Internal error: xmlSchemaTypeFixup, "
pcercuei 0:03b5121a232e 18302 "complex type '%s': the <extension>ed base type is "
pcercuei 0:03b5121a232e 18303 "a complex type with no simple content type",
pcercuei 0:03b5121a232e 18304 type->name);
pcercuei 0:03b5121a232e 18305 goto exit_failure;
pcercuei 0:03b5121a232e 18306 }
pcercuei 0:03b5121a232e 18307 type->contentTypeDef = baseType->contentTypeDef;
pcercuei 0:03b5121a232e 18308 } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
pcercuei 0:03b5121a232e 18309 /*
pcercuei 0:03b5121a232e 18310 * SPEC (4) <extension> + base is <simpleType>
pcercuei 0:03b5121a232e 18311 * "... then that simple type definition"
pcercuei 0:03b5121a232e 18312 */
pcercuei 0:03b5121a232e 18313 type->contentTypeDef = baseType;
pcercuei 0:03b5121a232e 18314 } else {
pcercuei 0:03b5121a232e 18315 /*
pcercuei 0:03b5121a232e 18316 * TODO: Check if this ever happens.
pcercuei 0:03b5121a232e 18317 */
pcercuei 0:03b5121a232e 18318 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 18319 XML_SCHEMAP_INTERNAL,
pcercuei 0:03b5121a232e 18320 WXS_BASIC_CAST type, NULL,
pcercuei 0:03b5121a232e 18321 "Internal error: xmlSchemaTypeFixup, "
pcercuei 0:03b5121a232e 18322 "complex type '%s' with <simpleContent>: unhandled "
pcercuei 0:03b5121a232e 18323 "derivation case", type->name);
pcercuei 0:03b5121a232e 18324 goto exit_failure;
pcercuei 0:03b5121a232e 18325 }
pcercuei 0:03b5121a232e 18326 } else {
pcercuei 0:03b5121a232e 18327 int dummySequence = 0;
pcercuei 0:03b5121a232e 18328 xmlSchemaParticlePtr particle =
pcercuei 0:03b5121a232e 18329 (xmlSchemaParticlePtr) type->subtypes;
pcercuei 0:03b5121a232e 18330 /*
pcercuei 0:03b5121a232e 18331 * Corresponds to <complexType><complexContent>...
pcercuei 0:03b5121a232e 18332 *
pcercuei 0:03b5121a232e 18333 * NOTE that the effective mixed was already set during parsing of
pcercuei 0:03b5121a232e 18334 * <complexType> and <complexContent>; its flag value is
pcercuei 0:03b5121a232e 18335 * XML_SCHEMAS_TYPE_MIXED.
pcercuei 0:03b5121a232e 18336 *
pcercuei 0:03b5121a232e 18337 * Compute the "effective content":
pcercuei 0:03b5121a232e 18338 * (2.1.1) + (2.1.2) + (2.1.3)
pcercuei 0:03b5121a232e 18339 */
pcercuei 0:03b5121a232e 18340 if ((particle == NULL) ||
pcercuei 0:03b5121a232e 18341 ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
pcercuei 0:03b5121a232e 18342 ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
pcercuei 0:03b5121a232e 18343 (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
pcercuei 0:03b5121a232e 18344 ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
pcercuei 0:03b5121a232e 18345 (particle->minOccurs == 0))) &&
pcercuei 0:03b5121a232e 18346 ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
pcercuei 0:03b5121a232e 18347 if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
pcercuei 0:03b5121a232e 18348 /*
pcercuei 0:03b5121a232e 18349 * SPEC (2.1.4) "If the `effective mixed` is true, then
pcercuei 0:03b5121a232e 18350 * a particle whose properties are as follows:..."
pcercuei 0:03b5121a232e 18351 *
pcercuei 0:03b5121a232e 18352 * Empty sequence model group with
pcercuei 0:03b5121a232e 18353 * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
pcercuei 0:03b5121a232e 18354 * NOTE that we sill assign it the <complexType> node to
pcercuei 0:03b5121a232e 18355 * somehow anchor it in the doc.
pcercuei 0:03b5121a232e 18356 */
pcercuei 0:03b5121a232e 18357 if ((particle == NULL) ||
pcercuei 0:03b5121a232e 18358 (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
pcercuei 0:03b5121a232e 18359 /*
pcercuei 0:03b5121a232e 18360 * Create the particle.
pcercuei 0:03b5121a232e 18361 */
pcercuei 0:03b5121a232e 18362 particle = xmlSchemaAddParticle(pctxt,
pcercuei 0:03b5121a232e 18363 type->node, 1, 1);
pcercuei 0:03b5121a232e 18364 if (particle == NULL)
pcercuei 0:03b5121a232e 18365 goto exit_failure;
pcercuei 0:03b5121a232e 18366 /*
pcercuei 0:03b5121a232e 18367 * Create the model group.
pcercuei 0:03b5121a232e 18368 */ /* URGENT TODO: avoid adding to pending items. */
pcercuei 0:03b5121a232e 18369 particle->children = (xmlSchemaTreeItemPtr)
pcercuei 0:03b5121a232e 18370 xmlSchemaAddModelGroup(pctxt, pctxt->schema,
pcercuei 0:03b5121a232e 18371 XML_SCHEMA_TYPE_SEQUENCE, type->node);
pcercuei 0:03b5121a232e 18372 if (particle->children == NULL)
pcercuei 0:03b5121a232e 18373 goto exit_failure;
pcercuei 0:03b5121a232e 18374
pcercuei 0:03b5121a232e 18375 type->subtypes = (xmlSchemaTypePtr) particle;
pcercuei 0:03b5121a232e 18376 }
pcercuei 0:03b5121a232e 18377 dummySequence = 1;
pcercuei 0:03b5121a232e 18378 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
pcercuei 0:03b5121a232e 18379 } else {
pcercuei 0:03b5121a232e 18380 /*
pcercuei 0:03b5121a232e 18381 * SPEC (2.1.5) "otherwise empty"
pcercuei 0:03b5121a232e 18382 */
pcercuei 0:03b5121a232e 18383 type->contentType = XML_SCHEMA_CONTENT_EMPTY;
pcercuei 0:03b5121a232e 18384 }
pcercuei 0:03b5121a232e 18385 } else {
pcercuei 0:03b5121a232e 18386 /*
pcercuei 0:03b5121a232e 18387 * SPEC (2.2) "otherwise the particle corresponding to the
pcercuei 0:03b5121a232e 18388 * <all>, <choice>, <group> or <sequence> among the
pcercuei 0:03b5121a232e 18389 * [children]."
pcercuei 0:03b5121a232e 18390 */
pcercuei 0:03b5121a232e 18391 type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
pcercuei 0:03b5121a232e 18392 }
pcercuei 0:03b5121a232e 18393 /*
pcercuei 0:03b5121a232e 18394 * Compute the "content type".
pcercuei 0:03b5121a232e 18395 */
pcercuei 0:03b5121a232e 18396 if (WXS_IS_RESTRICTION(type)) {
pcercuei 0:03b5121a232e 18397 /*
pcercuei 0:03b5121a232e 18398 * SPEC (3.1) "If <restriction>..."
pcercuei 0:03b5121a232e 18399 * (3.1.1) + (3.1.2) */
pcercuei 0:03b5121a232e 18400 if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
pcercuei 0:03b5121a232e 18401 if (type->flags & XML_SCHEMAS_TYPE_MIXED)
pcercuei 0:03b5121a232e 18402 type->contentType = XML_SCHEMA_CONTENT_MIXED;
pcercuei 0:03b5121a232e 18403 }
pcercuei 0:03b5121a232e 18404 } else {
pcercuei 0:03b5121a232e 18405 /*
pcercuei 0:03b5121a232e 18406 * SPEC (3.2) "If <extension>..."
pcercuei 0:03b5121a232e 18407 */
pcercuei 0:03b5121a232e 18408 if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
pcercuei 0:03b5121a232e 18409 /*
pcercuei 0:03b5121a232e 18410 * SPEC (3.2.1)
pcercuei 0:03b5121a232e 18411 * "If the `effective content` is empty, then the
pcercuei 0:03b5121a232e 18412 * {content type} of the [...] base ..."
pcercuei 0:03b5121a232e 18413 */
pcercuei 0:03b5121a232e 18414 type->contentType = baseType->contentType;
pcercuei 0:03b5121a232e 18415 type->subtypes = baseType->subtypes;
pcercuei 0:03b5121a232e 18416 /*
pcercuei 0:03b5121a232e 18417 * Fixes bug #347316:
pcercuei 0:03b5121a232e 18418 * This is the case when the base type has a simple
pcercuei 0:03b5121a232e 18419 * type definition as content.
pcercuei 0:03b5121a232e 18420 */
pcercuei 0:03b5121a232e 18421 type->contentTypeDef = baseType->contentTypeDef;
pcercuei 0:03b5121a232e 18422 /*
pcercuei 0:03b5121a232e 18423 * NOTE that the effective mixed is ignored here.
pcercuei 0:03b5121a232e 18424 */
pcercuei 0:03b5121a232e 18425 } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
pcercuei 0:03b5121a232e 18426 /*
pcercuei 0:03b5121a232e 18427 * SPEC (3.2.2)
pcercuei 0:03b5121a232e 18428 */
pcercuei 0:03b5121a232e 18429 if (type->flags & XML_SCHEMAS_TYPE_MIXED)
pcercuei 0:03b5121a232e 18430 type->contentType = XML_SCHEMA_CONTENT_MIXED;
pcercuei 0:03b5121a232e 18431 } else {
pcercuei 0:03b5121a232e 18432 /*
pcercuei 0:03b5121a232e 18433 * SPEC (3.2.3)
pcercuei 0:03b5121a232e 18434 */
pcercuei 0:03b5121a232e 18435 if (type->flags & XML_SCHEMAS_TYPE_MIXED)
pcercuei 0:03b5121a232e 18436 type->contentType = XML_SCHEMA_CONTENT_MIXED;
pcercuei 0:03b5121a232e 18437 /*
pcercuei 0:03b5121a232e 18438 * "A model group whose {compositor} is sequence and whose
pcercuei 0:03b5121a232e 18439 * {particles} are..."
pcercuei 0:03b5121a232e 18440 */
pcercuei 0:03b5121a232e 18441 if ((WXS_TYPE_PARTICLE(type) != NULL) &&
pcercuei 0:03b5121a232e 18442 (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
pcercuei 0:03b5121a232e 18443 ((WXS_TYPE_PARTICLE_TERM(type))->type ==
pcercuei 0:03b5121a232e 18444 XML_SCHEMA_TYPE_ALL))
pcercuei 0:03b5121a232e 18445 {
pcercuei 0:03b5121a232e 18446 /*
pcercuei 0:03b5121a232e 18447 * SPEC cos-all-limited (1)
pcercuei 0:03b5121a232e 18448 */
pcercuei 0:03b5121a232e 18449 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 18450 /* TODO: error code */
pcercuei 0:03b5121a232e 18451 XML_SCHEMAP_COS_ALL_LIMITED,
pcercuei 0:03b5121a232e 18452 WXS_ITEM_NODE(type), NULL,
pcercuei 0:03b5121a232e 18453 "The type has an 'all' model group in its "
pcercuei 0:03b5121a232e 18454 "{content type} and thus cannot be derived from "
pcercuei 0:03b5121a232e 18455 "a non-empty type, since this would produce a "
pcercuei 0:03b5121a232e 18456 "'sequence' model group containing the 'all' "
pcercuei 0:03b5121a232e 18457 "model group; 'all' model groups are not "
pcercuei 0:03b5121a232e 18458 "allowed to appear inside other model groups",
pcercuei 0:03b5121a232e 18459 NULL, NULL);
pcercuei 0:03b5121a232e 18460
pcercuei 0:03b5121a232e 18461 } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
pcercuei 0:03b5121a232e 18462 (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
pcercuei 0:03b5121a232e 18463 ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
pcercuei 0:03b5121a232e 18464 XML_SCHEMA_TYPE_ALL))
pcercuei 0:03b5121a232e 18465 {
pcercuei 0:03b5121a232e 18466 /*
pcercuei 0:03b5121a232e 18467 * SPEC cos-all-limited (1)
pcercuei 0:03b5121a232e 18468 */
pcercuei 0:03b5121a232e 18469 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 18470 /* TODO: error code */
pcercuei 0:03b5121a232e 18471 XML_SCHEMAP_COS_ALL_LIMITED,
pcercuei 0:03b5121a232e 18472 WXS_ITEM_NODE(type), NULL,
pcercuei 0:03b5121a232e 18473 "A type cannot be derived by extension from a type "
pcercuei 0:03b5121a232e 18474 "which has an 'all' model group in its "
pcercuei 0:03b5121a232e 18475 "{content type}, since this would produce a "
pcercuei 0:03b5121a232e 18476 "'sequence' model group containing the 'all' "
pcercuei 0:03b5121a232e 18477 "model group; 'all' model groups are not "
pcercuei 0:03b5121a232e 18478 "allowed to appear inside other model groups",
pcercuei 0:03b5121a232e 18479 NULL, NULL);
pcercuei 0:03b5121a232e 18480
pcercuei 0:03b5121a232e 18481 } else if (! dummySequence) {
pcercuei 0:03b5121a232e 18482 xmlSchemaTreeItemPtr effectiveContent =
pcercuei 0:03b5121a232e 18483 (xmlSchemaTreeItemPtr) type->subtypes;
pcercuei 0:03b5121a232e 18484 /*
pcercuei 0:03b5121a232e 18485 * Create the particle.
pcercuei 0:03b5121a232e 18486 */
pcercuei 0:03b5121a232e 18487 particle = xmlSchemaAddParticle(pctxt,
pcercuei 0:03b5121a232e 18488 type->node, 1, 1);
pcercuei 0:03b5121a232e 18489 if (particle == NULL)
pcercuei 0:03b5121a232e 18490 goto exit_failure;
pcercuei 0:03b5121a232e 18491 /*
pcercuei 0:03b5121a232e 18492 * Create the "sequence" model group.
pcercuei 0:03b5121a232e 18493 */
pcercuei 0:03b5121a232e 18494 particle->children = (xmlSchemaTreeItemPtr)
pcercuei 0:03b5121a232e 18495 xmlSchemaAddModelGroup(pctxt, pctxt->schema,
pcercuei 0:03b5121a232e 18496 XML_SCHEMA_TYPE_SEQUENCE, type->node);
pcercuei 0:03b5121a232e 18497 if (particle->children == NULL)
pcercuei 0:03b5121a232e 18498 goto exit_failure;
pcercuei 0:03b5121a232e 18499 WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
pcercuei 0:03b5121a232e 18500 /*
pcercuei 0:03b5121a232e 18501 * SPEC "the particle of the {content type} of
pcercuei 0:03b5121a232e 18502 * the ... base ..."
pcercuei 0:03b5121a232e 18503 * Create a duplicate of the base type's particle
pcercuei 0:03b5121a232e 18504 * and assign its "term" to it.
pcercuei 0:03b5121a232e 18505 */
pcercuei 0:03b5121a232e 18506 particle->children->children =
pcercuei 0:03b5121a232e 18507 (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
pcercuei 0:03b5121a232e 18508 type->node,
pcercuei 0:03b5121a232e 18509 ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
pcercuei 0:03b5121a232e 18510 ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
pcercuei 0:03b5121a232e 18511 if (particle->children->children == NULL)
pcercuei 0:03b5121a232e 18512 goto exit_failure;
pcercuei 0:03b5121a232e 18513 particle = (xmlSchemaParticlePtr)
pcercuei 0:03b5121a232e 18514 particle->children->children;
pcercuei 0:03b5121a232e 18515 particle->children =
pcercuei 0:03b5121a232e 18516 ((xmlSchemaParticlePtr) baseType->subtypes)->children;
pcercuei 0:03b5121a232e 18517 /*
pcercuei 0:03b5121a232e 18518 * SPEC "followed by the `effective content`."
pcercuei 0:03b5121a232e 18519 */
pcercuei 0:03b5121a232e 18520 particle->next = effectiveContent;
pcercuei 0:03b5121a232e 18521 /*
pcercuei 0:03b5121a232e 18522 * This all will result in:
pcercuei 0:03b5121a232e 18523 * new-particle
pcercuei 0:03b5121a232e 18524 * --> new-sequence(
pcercuei 0:03b5121a232e 18525 * new-particle
pcercuei 0:03b5121a232e 18526 * --> base-model,
pcercuei 0:03b5121a232e 18527 * this-particle
pcercuei 0:03b5121a232e 18528 * --> this-model
pcercuei 0:03b5121a232e 18529 * )
pcercuei 0:03b5121a232e 18530 */
pcercuei 0:03b5121a232e 18531 } else {
pcercuei 0:03b5121a232e 18532 /*
pcercuei 0:03b5121a232e 18533 * This is the case when there is already an empty
pcercuei 0:03b5121a232e 18534 * <sequence> with minOccurs==maxOccurs==1.
pcercuei 0:03b5121a232e 18535 * Just add the base types's content type.
pcercuei 0:03b5121a232e 18536 * NOTE that, although we miss to add an intermediate
pcercuei 0:03b5121a232e 18537 * <sequence>, this should produce no difference to
pcercuei 0:03b5121a232e 18538 * neither the regex compilation of the content model,
pcercuei 0:03b5121a232e 18539 * nor to the complex type contraints.
pcercuei 0:03b5121a232e 18540 */
pcercuei 0:03b5121a232e 18541 particle->children->children =
pcercuei 0:03b5121a232e 18542 (xmlSchemaTreeItemPtr) baseType->subtypes;
pcercuei 0:03b5121a232e 18543 }
pcercuei 0:03b5121a232e 18544 }
pcercuei 0:03b5121a232e 18545 }
pcercuei 0:03b5121a232e 18546 }
pcercuei 0:03b5121a232e 18547 /*
pcercuei 0:03b5121a232e 18548 * Now fixup attribute uses:
pcercuei 0:03b5121a232e 18549 * - expand attr. group references
pcercuei 0:03b5121a232e 18550 * - intersect attribute wildcards
pcercuei 0:03b5121a232e 18551 * - inherit attribute uses of the base type
pcercuei 0:03b5121a232e 18552 * - inherit or union attr. wildcards if extending
pcercuei 0:03b5121a232e 18553 * - apply attr. use prohibitions if restricting
pcercuei 0:03b5121a232e 18554 */
pcercuei 0:03b5121a232e 18555 res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
pcercuei 0:03b5121a232e 18556 HFAILURE HERROR
pcercuei 0:03b5121a232e 18557 /*
pcercuei 0:03b5121a232e 18558 * Apply the complex type component constraints; this will not
pcercuei 0:03b5121a232e 18559 * check attributes, since this is done in
pcercuei 0:03b5121a232e 18560 * xmlSchemaFixupTypeAttributeUses().
pcercuei 0:03b5121a232e 18561 */
pcercuei 0:03b5121a232e 18562 res = xmlSchemaCheckCTComponent(pctxt, type);
pcercuei 0:03b5121a232e 18563 HFAILURE HERROR
pcercuei 0:03b5121a232e 18564
pcercuei 0:03b5121a232e 18565 #ifdef DEBUG_TYPE
pcercuei 0:03b5121a232e 18566 xmlSchemaDebugFixedType(pctxt, type);
pcercuei 0:03b5121a232e 18567 #endif
pcercuei 0:03b5121a232e 18568 if (olderrs != pctxt->nberrors)
pcercuei 0:03b5121a232e 18569 return(pctxt->err);
pcercuei 0:03b5121a232e 18570 else
pcercuei 0:03b5121a232e 18571 return(0);
pcercuei 0:03b5121a232e 18572
pcercuei 0:03b5121a232e 18573 exit_error:
pcercuei 0:03b5121a232e 18574 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
pcercuei 0:03b5121a232e 18575 #ifdef DEBUG_TYPE
pcercuei 0:03b5121a232e 18576 xmlSchemaDebugFixedType(pctxt, type);
pcercuei 0:03b5121a232e 18577 #endif
pcercuei 0:03b5121a232e 18578 return(pctxt->err);
pcercuei 0:03b5121a232e 18579
pcercuei 0:03b5121a232e 18580 exit_failure:
pcercuei 0:03b5121a232e 18581 type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
pcercuei 0:03b5121a232e 18582 #ifdef DEBUG_TYPE
pcercuei 0:03b5121a232e 18583 xmlSchemaDebugFixedType(pctxt, type);
pcercuei 0:03b5121a232e 18584 #endif
pcercuei 0:03b5121a232e 18585 return(-1);
pcercuei 0:03b5121a232e 18586 }
pcercuei 0:03b5121a232e 18587
pcercuei 0:03b5121a232e 18588
pcercuei 0:03b5121a232e 18589 /**
pcercuei 0:03b5121a232e 18590 * xmlSchemaTypeFixup:
pcercuei 0:03b5121a232e 18591 * @typeDecl: the schema type definition
pcercuei 0:03b5121a232e 18592 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 18593 *
pcercuei 0:03b5121a232e 18594 * Fixes the content model of the type.
pcercuei 0:03b5121a232e 18595 * URGENT TODO: We need an int result!
pcercuei 0:03b5121a232e 18596 */
pcercuei 0:03b5121a232e 18597 static int
pcercuei 0:03b5121a232e 18598 xmlSchemaTypeFixup(xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 18599 xmlSchemaAbstractCtxtPtr actxt)
pcercuei 0:03b5121a232e 18600 {
pcercuei 0:03b5121a232e 18601 if (type == NULL)
pcercuei 0:03b5121a232e 18602 return(0);
pcercuei 0:03b5121a232e 18603 if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
pcercuei 0:03b5121a232e 18604 AERROR_INT("xmlSchemaTypeFixup",
pcercuei 0:03b5121a232e 18605 "this function needs a parser context");
pcercuei 0:03b5121a232e 18606 return(-1);
pcercuei 0:03b5121a232e 18607 }
pcercuei 0:03b5121a232e 18608 if (! WXS_IS_TYPE_NOT_FIXED(type))
pcercuei 0:03b5121a232e 18609 return(0);
pcercuei 0:03b5121a232e 18610 if (type->type == XML_SCHEMA_TYPE_COMPLEX)
pcercuei 0:03b5121a232e 18611 return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
pcercuei 0:03b5121a232e 18612 else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
pcercuei 0:03b5121a232e 18613 return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
pcercuei 0:03b5121a232e 18614 return(0);
pcercuei 0:03b5121a232e 18615 }
pcercuei 0:03b5121a232e 18616
pcercuei 0:03b5121a232e 18617 /**
pcercuei 0:03b5121a232e 18618 * xmlSchemaCheckFacet:
pcercuei 0:03b5121a232e 18619 * @facet: the facet
pcercuei 0:03b5121a232e 18620 * @typeDecl: the schema type definition
pcercuei 0:03b5121a232e 18621 * @pctxt: the schema parser context or NULL
pcercuei 0:03b5121a232e 18622 * @name: the optional name of the type
pcercuei 0:03b5121a232e 18623 *
pcercuei 0:03b5121a232e 18624 * Checks and computes the values of facets.
pcercuei 0:03b5121a232e 18625 *
pcercuei 0:03b5121a232e 18626 * Returns 0 if valid, a positive error code if not valid and
pcercuei 0:03b5121a232e 18627 * -1 in case of an internal or API error.
pcercuei 0:03b5121a232e 18628 */
pcercuei 0:03b5121a232e 18629 int
pcercuei 0:03b5121a232e 18630 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
pcercuei 0:03b5121a232e 18631 xmlSchemaTypePtr typeDecl,
pcercuei 0:03b5121a232e 18632 xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 18633 const xmlChar * name ATTRIBUTE_UNUSED)
pcercuei 0:03b5121a232e 18634 {
pcercuei 0:03b5121a232e 18635 int ret = 0, ctxtGiven;
pcercuei 0:03b5121a232e 18636
pcercuei 0:03b5121a232e 18637 if ((facet == NULL) || (typeDecl == NULL))
pcercuei 0:03b5121a232e 18638 return(-1);
pcercuei 0:03b5121a232e 18639 /*
pcercuei 0:03b5121a232e 18640 * TODO: will the parser context be given if used from
pcercuei 0:03b5121a232e 18641 * the relaxNG module?
pcercuei 0:03b5121a232e 18642 */
pcercuei 0:03b5121a232e 18643 if (pctxt == NULL)
pcercuei 0:03b5121a232e 18644 ctxtGiven = 0;
pcercuei 0:03b5121a232e 18645 else
pcercuei 0:03b5121a232e 18646 ctxtGiven = 1;
pcercuei 0:03b5121a232e 18647
pcercuei 0:03b5121a232e 18648 switch (facet->type) {
pcercuei 0:03b5121a232e 18649 case XML_SCHEMA_FACET_MININCLUSIVE:
pcercuei 0:03b5121a232e 18650 case XML_SCHEMA_FACET_MINEXCLUSIVE:
pcercuei 0:03b5121a232e 18651 case XML_SCHEMA_FACET_MAXINCLUSIVE:
pcercuei 0:03b5121a232e 18652 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
pcercuei 0:03b5121a232e 18653 case XML_SCHEMA_FACET_ENUMERATION: {
pcercuei 0:03b5121a232e 18654 /*
pcercuei 0:03b5121a232e 18655 * Okay we need to validate the value
pcercuei 0:03b5121a232e 18656 * at that point.
pcercuei 0:03b5121a232e 18657 */
pcercuei 0:03b5121a232e 18658 xmlSchemaTypePtr base;
pcercuei 0:03b5121a232e 18659
pcercuei 0:03b5121a232e 18660 /* 4.3.5.5 Constraints on enumeration Schema Components
pcercuei 0:03b5121a232e 18661 * Schema Component Constraint: enumeration valid restriction
pcercuei 0:03b5121a232e 18662 * It is an `error` if any member of {value} is not in the
pcercuei 0:03b5121a232e 18663 * `value space` of {base type definition}.
pcercuei 0:03b5121a232e 18664 *
pcercuei 0:03b5121a232e 18665 * minInclusive, maxInclusive, minExclusive, maxExclusive:
pcercuei 0:03b5121a232e 18666 * The value `must` be in the
pcercuei 0:03b5121a232e 18667 * `value space` of the `base type`.
pcercuei 0:03b5121a232e 18668 */
pcercuei 0:03b5121a232e 18669 /*
pcercuei 0:03b5121a232e 18670 * This function is intended to deliver a compiled value
pcercuei 0:03b5121a232e 18671 * on the facet. In this implementation of XML Schemata the
pcercuei 0:03b5121a232e 18672 * type holding a facet, won't be a built-in type.
pcercuei 0:03b5121a232e 18673 * Thus to ensure that other API
pcercuei 0:03b5121a232e 18674 * calls (relaxng) do work, if the given type is a built-in
pcercuei 0:03b5121a232e 18675 * type, we will assume that the given built-in type *is
pcercuei 0:03b5121a232e 18676 * already* the base type.
pcercuei 0:03b5121a232e 18677 */
pcercuei 0:03b5121a232e 18678 if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
pcercuei 0:03b5121a232e 18679 base = typeDecl->baseType;
pcercuei 0:03b5121a232e 18680 if (base == NULL) {
pcercuei 0:03b5121a232e 18681 PERROR_INT("xmlSchemaCheckFacet",
pcercuei 0:03b5121a232e 18682 "a type user derived type has no base type");
pcercuei 0:03b5121a232e 18683 return (-1);
pcercuei 0:03b5121a232e 18684 }
pcercuei 0:03b5121a232e 18685 } else
pcercuei 0:03b5121a232e 18686 base = typeDecl;
pcercuei 0:03b5121a232e 18687
pcercuei 0:03b5121a232e 18688 if (! ctxtGiven) {
pcercuei 0:03b5121a232e 18689 /*
pcercuei 0:03b5121a232e 18690 * A context is needed if called from RelaxNG.
pcercuei 0:03b5121a232e 18691 */
pcercuei 0:03b5121a232e 18692 pctxt = xmlSchemaNewParserCtxt("*");
pcercuei 0:03b5121a232e 18693 if (pctxt == NULL)
pcercuei 0:03b5121a232e 18694 return (-1);
pcercuei 0:03b5121a232e 18695 }
pcercuei 0:03b5121a232e 18696 /*
pcercuei 0:03b5121a232e 18697 * NOTE: This call does not check the content nodes,
pcercuei 0:03b5121a232e 18698 * since they are not available:
pcercuei 0:03b5121a232e 18699 * facet->node is just the node holding the facet
pcercuei 0:03b5121a232e 18700 * definition, *not* the attribute holding the *value*
pcercuei 0:03b5121a232e 18701 * of the facet.
pcercuei 0:03b5121a232e 18702 */
pcercuei 0:03b5121a232e 18703 ret = xmlSchemaVCheckCVCSimpleType(
pcercuei 0:03b5121a232e 18704 ACTXT_CAST pctxt, facet->node, base,
pcercuei 0:03b5121a232e 18705 facet->value, &(facet->val), 1, 1, 0);
pcercuei 0:03b5121a232e 18706 if (ret != 0) {
pcercuei 0:03b5121a232e 18707 if (ret < 0) {
pcercuei 0:03b5121a232e 18708 /* No error message for RelaxNG. */
pcercuei 0:03b5121a232e 18709 if (ctxtGiven) {
pcercuei 0:03b5121a232e 18710 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 18711 XML_SCHEMAP_INTERNAL, facet->node, NULL,
pcercuei 0:03b5121a232e 18712 "Internal error: xmlSchemaCheckFacet, "
pcercuei 0:03b5121a232e 18713 "failed to validate the value '%s' of the "
pcercuei 0:03b5121a232e 18714 "facet '%s' against the base type",
pcercuei 0:03b5121a232e 18715 facet->value, xmlSchemaFacetTypeToString(facet->type));
pcercuei 0:03b5121a232e 18716 }
pcercuei 0:03b5121a232e 18717 goto internal_error;
pcercuei 0:03b5121a232e 18718 }
pcercuei 0:03b5121a232e 18719 ret = XML_SCHEMAP_INVALID_FACET_VALUE;
pcercuei 0:03b5121a232e 18720 /* No error message for RelaxNG. */
pcercuei 0:03b5121a232e 18721 if (ctxtGiven) {
pcercuei 0:03b5121a232e 18722 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 18723
pcercuei 0:03b5121a232e 18724 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 18725 ret, facet->node, WXS_BASIC_CAST facet,
pcercuei 0:03b5121a232e 18726 "The value '%s' of the facet does not validate "
pcercuei 0:03b5121a232e 18727 "against the base type '%s'",
pcercuei 0:03b5121a232e 18728 facet->value,
pcercuei 0:03b5121a232e 18729 xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 18730 base->targetNamespace, base->name));
pcercuei 0:03b5121a232e 18731 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 18732 }
pcercuei 0:03b5121a232e 18733 goto exit;
pcercuei 0:03b5121a232e 18734 } else if (facet->val == NULL) {
pcercuei 0:03b5121a232e 18735 if (ctxtGiven) {
pcercuei 0:03b5121a232e 18736 PERROR_INT("xmlSchemaCheckFacet",
pcercuei 0:03b5121a232e 18737 "value was not computed");
pcercuei 0:03b5121a232e 18738 }
pcercuei 0:03b5121a232e 18739 TODO
pcercuei 0:03b5121a232e 18740 }
pcercuei 0:03b5121a232e 18741 break;
pcercuei 0:03b5121a232e 18742 }
pcercuei 0:03b5121a232e 18743 case XML_SCHEMA_FACET_PATTERN:
pcercuei 0:03b5121a232e 18744 facet->regexp = xmlRegexpCompile(facet->value);
pcercuei 0:03b5121a232e 18745 if (facet->regexp == NULL) {
pcercuei 0:03b5121a232e 18746 ret = XML_SCHEMAP_REGEXP_INVALID;
pcercuei 0:03b5121a232e 18747 /* No error message for RelaxNG. */
pcercuei 0:03b5121a232e 18748 if (ctxtGiven) {
pcercuei 0:03b5121a232e 18749 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 18750 ret, facet->node, WXS_BASIC_CAST typeDecl,
pcercuei 0:03b5121a232e 18751 "The value '%s' of the facet 'pattern' is not a "
pcercuei 0:03b5121a232e 18752 "valid regular expression",
pcercuei 0:03b5121a232e 18753 facet->value, NULL);
pcercuei 0:03b5121a232e 18754 }
pcercuei 0:03b5121a232e 18755 }
pcercuei 0:03b5121a232e 18756 break;
pcercuei 0:03b5121a232e 18757 case XML_SCHEMA_FACET_TOTALDIGITS:
pcercuei 0:03b5121a232e 18758 case XML_SCHEMA_FACET_FRACTIONDIGITS:
pcercuei 0:03b5121a232e 18759 case XML_SCHEMA_FACET_LENGTH:
pcercuei 0:03b5121a232e 18760 case XML_SCHEMA_FACET_MAXLENGTH:
pcercuei 0:03b5121a232e 18761 case XML_SCHEMA_FACET_MINLENGTH:
pcercuei 0:03b5121a232e 18762
pcercuei 0:03b5121a232e 18763 if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
pcercuei 0:03b5121a232e 18764 ret = xmlSchemaValidatePredefinedType(
pcercuei 0:03b5121a232e 18765 xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
pcercuei 0:03b5121a232e 18766 facet->value, &(facet->val));
pcercuei 0:03b5121a232e 18767 } else {
pcercuei 0:03b5121a232e 18768 ret = xmlSchemaValidatePredefinedType(
pcercuei 0:03b5121a232e 18769 xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
pcercuei 0:03b5121a232e 18770 facet->value, &(facet->val));
pcercuei 0:03b5121a232e 18771 }
pcercuei 0:03b5121a232e 18772 if (ret != 0) {
pcercuei 0:03b5121a232e 18773 if (ret < 0) {
pcercuei 0:03b5121a232e 18774 /* No error message for RelaxNG. */
pcercuei 0:03b5121a232e 18775 if (ctxtGiven) {
pcercuei 0:03b5121a232e 18776 PERROR_INT("xmlSchemaCheckFacet",
pcercuei 0:03b5121a232e 18777 "validating facet value");
pcercuei 0:03b5121a232e 18778 }
pcercuei 0:03b5121a232e 18779 goto internal_error;
pcercuei 0:03b5121a232e 18780 }
pcercuei 0:03b5121a232e 18781 ret = XML_SCHEMAP_INVALID_FACET_VALUE;
pcercuei 0:03b5121a232e 18782 /* No error message for RelaxNG. */
pcercuei 0:03b5121a232e 18783 if (ctxtGiven) {
pcercuei 0:03b5121a232e 18784 /* error code */
pcercuei 0:03b5121a232e 18785 xmlSchemaCustomErr4(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 18786 ret, facet->node, WXS_BASIC_CAST typeDecl,
pcercuei 0:03b5121a232e 18787 "The value '%s' of the facet '%s' is not a valid '%s'",
pcercuei 0:03b5121a232e 18788 facet->value,
pcercuei 0:03b5121a232e 18789 xmlSchemaFacetTypeToString(facet->type),
pcercuei 0:03b5121a232e 18790 (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
pcercuei 0:03b5121a232e 18791 BAD_CAST "nonNegativeInteger" :
pcercuei 0:03b5121a232e 18792 BAD_CAST "positiveInteger",
pcercuei 0:03b5121a232e 18793 NULL);
pcercuei 0:03b5121a232e 18794 }
pcercuei 0:03b5121a232e 18795 }
pcercuei 0:03b5121a232e 18796 break;
pcercuei 0:03b5121a232e 18797
pcercuei 0:03b5121a232e 18798 case XML_SCHEMA_FACET_WHITESPACE:{
pcercuei 0:03b5121a232e 18799 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
pcercuei 0:03b5121a232e 18800 facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
pcercuei 0:03b5121a232e 18801 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
pcercuei 0:03b5121a232e 18802 facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
pcercuei 0:03b5121a232e 18803 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
pcercuei 0:03b5121a232e 18804 facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
pcercuei 0:03b5121a232e 18805 } else {
pcercuei 0:03b5121a232e 18806 ret = XML_SCHEMAP_INVALID_FACET_VALUE;
pcercuei 0:03b5121a232e 18807 /* No error message for RelaxNG. */
pcercuei 0:03b5121a232e 18808 if (ctxtGiven) {
pcercuei 0:03b5121a232e 18809 /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
pcercuei 0:03b5121a232e 18810 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 18811 ret, facet->node, WXS_BASIC_CAST typeDecl,
pcercuei 0:03b5121a232e 18812 "The value '%s' of the facet 'whitespace' is not "
pcercuei 0:03b5121a232e 18813 "valid", facet->value, NULL);
pcercuei 0:03b5121a232e 18814 }
pcercuei 0:03b5121a232e 18815 }
pcercuei 0:03b5121a232e 18816 }
pcercuei 0:03b5121a232e 18817 default:
pcercuei 0:03b5121a232e 18818 break;
pcercuei 0:03b5121a232e 18819 }
pcercuei 0:03b5121a232e 18820 exit:
pcercuei 0:03b5121a232e 18821 if ((! ctxtGiven) && (pctxt != NULL))
pcercuei 0:03b5121a232e 18822 xmlSchemaFreeParserCtxt(pctxt);
pcercuei 0:03b5121a232e 18823 return (ret);
pcercuei 0:03b5121a232e 18824 internal_error:
pcercuei 0:03b5121a232e 18825 if ((! ctxtGiven) && (pctxt != NULL))
pcercuei 0:03b5121a232e 18826 xmlSchemaFreeParserCtxt(pctxt);
pcercuei 0:03b5121a232e 18827 return (-1);
pcercuei 0:03b5121a232e 18828 }
pcercuei 0:03b5121a232e 18829
pcercuei 0:03b5121a232e 18830 /**
pcercuei 0:03b5121a232e 18831 * xmlSchemaCheckFacetValues:
pcercuei 0:03b5121a232e 18832 * @typeDecl: the schema type definition
pcercuei 0:03b5121a232e 18833 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 18834 *
pcercuei 0:03b5121a232e 18835 * Checks the default values types, especially for facets
pcercuei 0:03b5121a232e 18836 */
pcercuei 0:03b5121a232e 18837 static int
pcercuei 0:03b5121a232e 18838 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
pcercuei 0:03b5121a232e 18839 xmlSchemaParserCtxtPtr pctxt)
pcercuei 0:03b5121a232e 18840 {
pcercuei 0:03b5121a232e 18841 int res, olderrs = pctxt->nberrors;
pcercuei 0:03b5121a232e 18842 const xmlChar *name = typeDecl->name;
pcercuei 0:03b5121a232e 18843 /*
pcercuei 0:03b5121a232e 18844 * NOTE: It is intended to use the facets list, instead
pcercuei 0:03b5121a232e 18845 * of facetSet.
pcercuei 0:03b5121a232e 18846 */
pcercuei 0:03b5121a232e 18847 if (typeDecl->facets != NULL) {
pcercuei 0:03b5121a232e 18848 xmlSchemaFacetPtr facet = typeDecl->facets;
pcercuei 0:03b5121a232e 18849
pcercuei 0:03b5121a232e 18850 /*
pcercuei 0:03b5121a232e 18851 * Temporarily assign the "schema" to the validation context
pcercuei 0:03b5121a232e 18852 * of the parser context. This is needed for NOTATION validation.
pcercuei 0:03b5121a232e 18853 */
pcercuei 0:03b5121a232e 18854 if (pctxt->vctxt == NULL) {
pcercuei 0:03b5121a232e 18855 if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
pcercuei 0:03b5121a232e 18856 return(-1);
pcercuei 0:03b5121a232e 18857 }
pcercuei 0:03b5121a232e 18858 pctxt->vctxt->schema = pctxt->schema;
pcercuei 0:03b5121a232e 18859 while (facet != NULL) {
pcercuei 0:03b5121a232e 18860 res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
pcercuei 0:03b5121a232e 18861 HFAILURE
pcercuei 0:03b5121a232e 18862 facet = facet->next;
pcercuei 0:03b5121a232e 18863 }
pcercuei 0:03b5121a232e 18864 pctxt->vctxt->schema = NULL;
pcercuei 0:03b5121a232e 18865 }
pcercuei 0:03b5121a232e 18866 if (olderrs != pctxt->nberrors)
pcercuei 0:03b5121a232e 18867 return(pctxt->err);
pcercuei 0:03b5121a232e 18868 return(0);
pcercuei 0:03b5121a232e 18869 exit_failure:
pcercuei 0:03b5121a232e 18870 return(-1);
pcercuei 0:03b5121a232e 18871 }
pcercuei 0:03b5121a232e 18872
pcercuei 0:03b5121a232e 18873 /**
pcercuei 0:03b5121a232e 18874 * xmlSchemaGetCircModelGrDefRef:
pcercuei 0:03b5121a232e 18875 * @ctxtMGroup: the searched model group
pcercuei 0:03b5121a232e 18876 * @selfMGroup: the second searched model group
pcercuei 0:03b5121a232e 18877 * @particle: the first particle
pcercuei 0:03b5121a232e 18878 *
pcercuei 0:03b5121a232e 18879 * This one is intended to be used by
pcercuei 0:03b5121a232e 18880 * xmlSchemaCheckGroupDefCircular only.
pcercuei 0:03b5121a232e 18881 *
pcercuei 0:03b5121a232e 18882 * Returns the particle with the circular model group definition reference,
pcercuei 0:03b5121a232e 18883 * otherwise NULL.
pcercuei 0:03b5121a232e 18884 */
pcercuei 0:03b5121a232e 18885 static xmlSchemaTreeItemPtr
pcercuei 0:03b5121a232e 18886 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
pcercuei 0:03b5121a232e 18887 xmlSchemaTreeItemPtr particle)
pcercuei 0:03b5121a232e 18888 {
pcercuei 0:03b5121a232e 18889 xmlSchemaTreeItemPtr circ = NULL;
pcercuei 0:03b5121a232e 18890 xmlSchemaTreeItemPtr term;
pcercuei 0:03b5121a232e 18891 xmlSchemaModelGroupDefPtr gdef;
pcercuei 0:03b5121a232e 18892
pcercuei 0:03b5121a232e 18893 for (; particle != NULL; particle = particle->next) {
pcercuei 0:03b5121a232e 18894 term = particle->children;
pcercuei 0:03b5121a232e 18895 if (term == NULL)
pcercuei 0:03b5121a232e 18896 continue;
pcercuei 0:03b5121a232e 18897 switch (term->type) {
pcercuei 0:03b5121a232e 18898 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 18899 gdef = (xmlSchemaModelGroupDefPtr) term;
pcercuei 0:03b5121a232e 18900 if (gdef == groupDef)
pcercuei 0:03b5121a232e 18901 return (particle);
pcercuei 0:03b5121a232e 18902 /*
pcercuei 0:03b5121a232e 18903 * Mark this model group definition to avoid infinite
pcercuei 0:03b5121a232e 18904 * recursion on circular references not yet examined.
pcercuei 0:03b5121a232e 18905 */
pcercuei 0:03b5121a232e 18906 if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
pcercuei 0:03b5121a232e 18907 continue;
pcercuei 0:03b5121a232e 18908 if (gdef->children != NULL) {
pcercuei 0:03b5121a232e 18909 gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
pcercuei 0:03b5121a232e 18910 circ = xmlSchemaGetCircModelGrDefRef(groupDef,
pcercuei 0:03b5121a232e 18911 gdef->children->children);
pcercuei 0:03b5121a232e 18912 gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
pcercuei 0:03b5121a232e 18913 if (circ != NULL)
pcercuei 0:03b5121a232e 18914 return (circ);
pcercuei 0:03b5121a232e 18915 }
pcercuei 0:03b5121a232e 18916 break;
pcercuei 0:03b5121a232e 18917 case XML_SCHEMA_TYPE_SEQUENCE:
pcercuei 0:03b5121a232e 18918 case XML_SCHEMA_TYPE_CHOICE:
pcercuei 0:03b5121a232e 18919 case XML_SCHEMA_TYPE_ALL:
pcercuei 0:03b5121a232e 18920 circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
pcercuei 0:03b5121a232e 18921 if (circ != NULL)
pcercuei 0:03b5121a232e 18922 return (circ);
pcercuei 0:03b5121a232e 18923 break;
pcercuei 0:03b5121a232e 18924 default:
pcercuei 0:03b5121a232e 18925 break;
pcercuei 0:03b5121a232e 18926 }
pcercuei 0:03b5121a232e 18927 }
pcercuei 0:03b5121a232e 18928 return (NULL);
pcercuei 0:03b5121a232e 18929 }
pcercuei 0:03b5121a232e 18930
pcercuei 0:03b5121a232e 18931 /**
pcercuei 0:03b5121a232e 18932 * xmlSchemaCheckGroupDefCircular:
pcercuei 0:03b5121a232e 18933 * @item: the model group definition
pcercuei 0:03b5121a232e 18934 * @ctxt: the parser context
pcercuei 0:03b5121a232e 18935 * @name: the name
pcercuei 0:03b5121a232e 18936 *
pcercuei 0:03b5121a232e 18937 * Checks for circular references to model group definitions.
pcercuei 0:03b5121a232e 18938 */
pcercuei 0:03b5121a232e 18939 static void
pcercuei 0:03b5121a232e 18940 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
pcercuei 0:03b5121a232e 18941 xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 18942 {
pcercuei 0:03b5121a232e 18943 /*
pcercuei 0:03b5121a232e 18944 * Schema Component Constraint: Model Group Correct
pcercuei 0:03b5121a232e 18945 * 2 Circular groups are disallowed. That is, within the {particles}
pcercuei 0:03b5121a232e 18946 * of a group there must not be at any depth a particle whose {term}
pcercuei 0:03b5121a232e 18947 * is the group itself.
pcercuei 0:03b5121a232e 18948 */
pcercuei 0:03b5121a232e 18949 if ((item == NULL) ||
pcercuei 0:03b5121a232e 18950 (item->type != XML_SCHEMA_TYPE_GROUP) ||
pcercuei 0:03b5121a232e 18951 (item->children == NULL))
pcercuei 0:03b5121a232e 18952 return;
pcercuei 0:03b5121a232e 18953 {
pcercuei 0:03b5121a232e 18954 xmlSchemaTreeItemPtr circ;
pcercuei 0:03b5121a232e 18955
pcercuei 0:03b5121a232e 18956 circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
pcercuei 0:03b5121a232e 18957 if (circ != NULL) {
pcercuei 0:03b5121a232e 18958 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 18959 /*
pcercuei 0:03b5121a232e 18960 * TODO: The error report is not adequate: this constraint
pcercuei 0:03b5121a232e 18961 * is defined for model groups but not definitions, but since
pcercuei 0:03b5121a232e 18962 * there cannot be any circular model groups without a model group
pcercuei 0:03b5121a232e 18963 * definition (if not using a construction API), we check those
pcercuei 0:03b5121a232e 18964 * defintions only.
pcercuei 0:03b5121a232e 18965 */
pcercuei 0:03b5121a232e 18966 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 18967 XML_SCHEMAP_MG_PROPS_CORRECT_2,
pcercuei 0:03b5121a232e 18968 NULL, WXS_ITEM_NODE(circ),
pcercuei 0:03b5121a232e 18969 "Circular reference to the model group definition '%s' "
pcercuei 0:03b5121a232e 18970 "defined", xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 18971 item->targetNamespace, item->name));
pcercuei 0:03b5121a232e 18972 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 18973 /*
pcercuei 0:03b5121a232e 18974 * NOTE: We will cut the reference to avoid further
pcercuei 0:03b5121a232e 18975 * confusion of the processor. This is a fatal error.
pcercuei 0:03b5121a232e 18976 */
pcercuei 0:03b5121a232e 18977 circ->children = NULL;
pcercuei 0:03b5121a232e 18978 }
pcercuei 0:03b5121a232e 18979 }
pcercuei 0:03b5121a232e 18980 }
pcercuei 0:03b5121a232e 18981
pcercuei 0:03b5121a232e 18982 /**
pcercuei 0:03b5121a232e 18983 * xmlSchemaModelGroupToModelGroupDefFixup:
pcercuei 0:03b5121a232e 18984 * @ctxt: the parser context
pcercuei 0:03b5121a232e 18985 * @mg: the model group
pcercuei 0:03b5121a232e 18986 *
pcercuei 0:03b5121a232e 18987 * Assigns the model group of model group definitions to the "term"
pcercuei 0:03b5121a232e 18988 * of the referencing particle.
pcercuei 0:03b5121a232e 18989 * In xmlSchemaResolveModelGroupParticleReferences the model group
pcercuei 0:03b5121a232e 18990 * definitions were assigned to the "term", since needed for the
pcercuei 0:03b5121a232e 18991 * circularity check.
pcercuei 0:03b5121a232e 18992 *
pcercuei 0:03b5121a232e 18993 * Schema Component Constraint:
pcercuei 0:03b5121a232e 18994 * All Group Limited (cos-all-limited) (1.2)
pcercuei 0:03b5121a232e 18995 */
pcercuei 0:03b5121a232e 18996 static void
pcercuei 0:03b5121a232e 18997 xmlSchemaModelGroupToModelGroupDefFixup(
pcercuei 0:03b5121a232e 18998 xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 18999 xmlSchemaModelGroupPtr mg)
pcercuei 0:03b5121a232e 19000 {
pcercuei 0:03b5121a232e 19001 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
pcercuei 0:03b5121a232e 19002
pcercuei 0:03b5121a232e 19003 while (particle != NULL) {
pcercuei 0:03b5121a232e 19004 if ((WXS_PARTICLE_TERM(particle) == NULL) ||
pcercuei 0:03b5121a232e 19005 ((WXS_PARTICLE_TERM(particle))->type !=
pcercuei 0:03b5121a232e 19006 XML_SCHEMA_TYPE_GROUP))
pcercuei 0:03b5121a232e 19007 {
pcercuei 0:03b5121a232e 19008 particle = WXS_PTC_CAST particle->next;
pcercuei 0:03b5121a232e 19009 continue;
pcercuei 0:03b5121a232e 19010 }
pcercuei 0:03b5121a232e 19011 if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
pcercuei 0:03b5121a232e 19012 /*
pcercuei 0:03b5121a232e 19013 * TODO: Remove the particle.
pcercuei 0:03b5121a232e 19014 */
pcercuei 0:03b5121a232e 19015 WXS_PARTICLE_TERM(particle) = NULL;
pcercuei 0:03b5121a232e 19016 particle = WXS_PTC_CAST particle->next;
pcercuei 0:03b5121a232e 19017 continue;
pcercuei 0:03b5121a232e 19018 }
pcercuei 0:03b5121a232e 19019 /*
pcercuei 0:03b5121a232e 19020 * Assign the model group to the {term} of the particle.
pcercuei 0:03b5121a232e 19021 */
pcercuei 0:03b5121a232e 19022 WXS_PARTICLE_TERM(particle) =
pcercuei 0:03b5121a232e 19023 WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
pcercuei 0:03b5121a232e 19024
pcercuei 0:03b5121a232e 19025 particle = WXS_PTC_CAST particle->next;
pcercuei 0:03b5121a232e 19026 }
pcercuei 0:03b5121a232e 19027 }
pcercuei 0:03b5121a232e 19028
pcercuei 0:03b5121a232e 19029 /**
pcercuei 0:03b5121a232e 19030 * xmlSchemaCheckAttrGroupCircularRecur:
pcercuei 0:03b5121a232e 19031 * @ctxtGr: the searched attribute group
pcercuei 0:03b5121a232e 19032 * @attr: the current attribute list to be processed
pcercuei 0:03b5121a232e 19033 *
pcercuei 0:03b5121a232e 19034 * This one is intended to be used by
pcercuei 0:03b5121a232e 19035 * xmlSchemaCheckAttrGroupCircular only.
pcercuei 0:03b5121a232e 19036 *
pcercuei 0:03b5121a232e 19037 * Returns the circular attribute grou reference, otherwise NULL.
pcercuei 0:03b5121a232e 19038 */
pcercuei 0:03b5121a232e 19039 static xmlSchemaQNameRefPtr
pcercuei 0:03b5121a232e 19040 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
pcercuei 0:03b5121a232e 19041 xmlSchemaItemListPtr list)
pcercuei 0:03b5121a232e 19042 {
pcercuei 0:03b5121a232e 19043 xmlSchemaAttributeGroupPtr gr;
pcercuei 0:03b5121a232e 19044 xmlSchemaQNameRefPtr ref, circ;
pcercuei 0:03b5121a232e 19045 int i;
pcercuei 0:03b5121a232e 19046 /*
pcercuei 0:03b5121a232e 19047 * We will search for an attribute group reference which
pcercuei 0:03b5121a232e 19048 * references the context attribute group.
pcercuei 0:03b5121a232e 19049 */
pcercuei 0:03b5121a232e 19050 for (i = 0; i < list->nbItems; i++) {
pcercuei 0:03b5121a232e 19051 ref = list->items[i];
pcercuei 0:03b5121a232e 19052 if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
pcercuei 0:03b5121a232e 19053 (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
pcercuei 0:03b5121a232e 19054 (ref->item != NULL))
pcercuei 0:03b5121a232e 19055 {
pcercuei 0:03b5121a232e 19056 gr = WXS_ATTR_GROUP_CAST ref->item;
pcercuei 0:03b5121a232e 19057 if (gr == ctxtGr)
pcercuei 0:03b5121a232e 19058 return(ref);
pcercuei 0:03b5121a232e 19059 if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
pcercuei 0:03b5121a232e 19060 continue;
pcercuei 0:03b5121a232e 19061 /*
pcercuei 0:03b5121a232e 19062 * Mark as visited to avoid infinite recursion on
pcercuei 0:03b5121a232e 19063 * circular references not yet examined.
pcercuei 0:03b5121a232e 19064 */
pcercuei 0:03b5121a232e 19065 if ((gr->attrUses) &&
pcercuei 0:03b5121a232e 19066 (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
pcercuei 0:03b5121a232e 19067 {
pcercuei 0:03b5121a232e 19068 gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
pcercuei 0:03b5121a232e 19069 circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
pcercuei 0:03b5121a232e 19070 (xmlSchemaItemListPtr) gr->attrUses);
pcercuei 0:03b5121a232e 19071 gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
pcercuei 0:03b5121a232e 19072 if (circ != NULL)
pcercuei 0:03b5121a232e 19073 return (circ);
pcercuei 0:03b5121a232e 19074 }
pcercuei 0:03b5121a232e 19075
pcercuei 0:03b5121a232e 19076 }
pcercuei 0:03b5121a232e 19077 }
pcercuei 0:03b5121a232e 19078 return (NULL);
pcercuei 0:03b5121a232e 19079 }
pcercuei 0:03b5121a232e 19080
pcercuei 0:03b5121a232e 19081 /**
pcercuei 0:03b5121a232e 19082 * xmlSchemaCheckAttrGroupCircular:
pcercuei 0:03b5121a232e 19083 * attrGr: the attribute group definition
pcercuei 0:03b5121a232e 19084 * @ctxt: the parser context
pcercuei 0:03b5121a232e 19085 * @name: the name
pcercuei 0:03b5121a232e 19086 *
pcercuei 0:03b5121a232e 19087 * Checks for circular references of attribute groups.
pcercuei 0:03b5121a232e 19088 */
pcercuei 0:03b5121a232e 19089 static int
pcercuei 0:03b5121a232e 19090 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
pcercuei 0:03b5121a232e 19091 xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 19092 {
pcercuei 0:03b5121a232e 19093 /*
pcercuei 0:03b5121a232e 19094 * Schema Representation Constraint:
pcercuei 0:03b5121a232e 19095 * Attribute Group Definition Representation OK
pcercuei 0:03b5121a232e 19096 * 3 Circular group reference is disallowed outside <redefine>.
pcercuei 0:03b5121a232e 19097 * That is, unless this element information item's parent is
pcercuei 0:03b5121a232e 19098 * <redefine>, then among the [children], if any, there must
pcercuei 0:03b5121a232e 19099 * not be an <attributeGroup> with ref [attribute] which resolves
pcercuei 0:03b5121a232e 19100 * to the component corresponding to this <attributeGroup>. Indirect
pcercuei 0:03b5121a232e 19101 * circularity is also ruled out. That is, when QName resolution
pcercuei 0:03b5121a232e 19102 * (Schema Document) ($3.15.3) is applied to a `QName` arising from
pcercuei 0:03b5121a232e 19103 * any <attributeGroup>s with a ref [attribute] among the [children],
pcercuei 0:03b5121a232e 19104 * it must not be the case that a `QName` is encountered at any depth
pcercuei 0:03b5121a232e 19105 * which resolves to the component corresponding to this <attributeGroup>.
pcercuei 0:03b5121a232e 19106 */
pcercuei 0:03b5121a232e 19107 if (attrGr->attrUses == NULL)
pcercuei 0:03b5121a232e 19108 return(0);
pcercuei 0:03b5121a232e 19109 else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
pcercuei 0:03b5121a232e 19110 return(0);
pcercuei 0:03b5121a232e 19111 else {
pcercuei 0:03b5121a232e 19112 xmlSchemaQNameRefPtr circ;
pcercuei 0:03b5121a232e 19113
pcercuei 0:03b5121a232e 19114 circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
pcercuei 0:03b5121a232e 19115 (xmlSchemaItemListPtr) attrGr->attrUses);
pcercuei 0:03b5121a232e 19116 if (circ != NULL) {
pcercuei 0:03b5121a232e 19117 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 19118 /*
pcercuei 0:03b5121a232e 19119 * TODO: Report the referenced attr group as QName.
pcercuei 0:03b5121a232e 19120 */
pcercuei 0:03b5121a232e 19121 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 19122 XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
pcercuei 0:03b5121a232e 19123 NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
pcercuei 0:03b5121a232e 19124 "Circular reference to the attribute group '%s' "
pcercuei 0:03b5121a232e 19125 "defined", xmlSchemaGetComponentQName(&str, attrGr));
pcercuei 0:03b5121a232e 19126 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 19127 /*
pcercuei 0:03b5121a232e 19128 * NOTE: We will cut the reference to avoid further
pcercuei 0:03b5121a232e 19129 * confusion of the processor.
pcercuei 0:03b5121a232e 19130 * BADSPEC TODO: The spec should define how to process in this case.
pcercuei 0:03b5121a232e 19131 */
pcercuei 0:03b5121a232e 19132 circ->item = NULL;
pcercuei 0:03b5121a232e 19133 return(ctxt->err);
pcercuei 0:03b5121a232e 19134 }
pcercuei 0:03b5121a232e 19135 }
pcercuei 0:03b5121a232e 19136 return(0);
pcercuei 0:03b5121a232e 19137 }
pcercuei 0:03b5121a232e 19138
pcercuei 0:03b5121a232e 19139 static int
pcercuei 0:03b5121a232e 19140 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 19141 xmlSchemaAttributeGroupPtr attrGr);
pcercuei 0:03b5121a232e 19142
pcercuei 0:03b5121a232e 19143 /**
pcercuei 0:03b5121a232e 19144 * xmlSchemaExpandAttributeGroupRefs:
pcercuei 0:03b5121a232e 19145 * @pctxt: the parser context
pcercuei 0:03b5121a232e 19146 * @node: the node of the component holding the attribute uses
pcercuei 0:03b5121a232e 19147 * @completeWild: the intersected wildcard to be returned
pcercuei 0:03b5121a232e 19148 * @list: the attribute uses
pcercuei 0:03b5121a232e 19149 *
pcercuei 0:03b5121a232e 19150 * Substitutes contained attribute group references
pcercuei 0:03b5121a232e 19151 * for their attribute uses. Wilcards are intersected.
pcercuei 0:03b5121a232e 19152 * Attribute use prohibitions are removed from the list
pcercuei 0:03b5121a232e 19153 * and returned via the @prohibs list.
pcercuei 0:03b5121a232e 19154 * Pointlessness of attr. prohibs, if a matching attr. decl
pcercuei 0:03b5121a232e 19155 * is existent a well, are checked.
pcercuei 0:03b5121a232e 19156 */
pcercuei 0:03b5121a232e 19157 static int
pcercuei 0:03b5121a232e 19158 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 19159 xmlSchemaBasicItemPtr item,
pcercuei 0:03b5121a232e 19160 xmlSchemaWildcardPtr *completeWild,
pcercuei 0:03b5121a232e 19161 xmlSchemaItemListPtr list,
pcercuei 0:03b5121a232e 19162 xmlSchemaItemListPtr prohibs)
pcercuei 0:03b5121a232e 19163 {
pcercuei 0:03b5121a232e 19164 xmlSchemaAttributeGroupPtr gr;
pcercuei 0:03b5121a232e 19165 xmlSchemaAttributeUsePtr use;
pcercuei 0:03b5121a232e 19166 xmlSchemaItemListPtr sublist;
pcercuei 0:03b5121a232e 19167 int i, j;
pcercuei 0:03b5121a232e 19168 int created = (*completeWild == NULL) ? 0 : 1;
pcercuei 0:03b5121a232e 19169
pcercuei 0:03b5121a232e 19170 if (prohibs)
pcercuei 0:03b5121a232e 19171 prohibs->nbItems = 0;
pcercuei 0:03b5121a232e 19172
pcercuei 0:03b5121a232e 19173 for (i = 0; i < list->nbItems; i++) {
pcercuei 0:03b5121a232e 19174 use = list->items[i];
pcercuei 0:03b5121a232e 19175
pcercuei 0:03b5121a232e 19176 if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
pcercuei 0:03b5121a232e 19177 if (prohibs == NULL) {
pcercuei 0:03b5121a232e 19178 PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
pcercuei 0:03b5121a232e 19179 "unexpected attr prohibition found");
pcercuei 0:03b5121a232e 19180 return(-1);
pcercuei 0:03b5121a232e 19181 }
pcercuei 0:03b5121a232e 19182 /*
pcercuei 0:03b5121a232e 19183 * Remove from attribute uses.
pcercuei 0:03b5121a232e 19184 */
pcercuei 0:03b5121a232e 19185 if (xmlSchemaItemListRemove(list, i) == -1)
pcercuei 0:03b5121a232e 19186 return(-1);
pcercuei 0:03b5121a232e 19187 i--;
pcercuei 0:03b5121a232e 19188 /*
pcercuei 0:03b5121a232e 19189 * Note that duplicate prohibitions were already
pcercuei 0:03b5121a232e 19190 * handled at parsing time.
pcercuei 0:03b5121a232e 19191 */
pcercuei 0:03b5121a232e 19192 /*
pcercuei 0:03b5121a232e 19193 * Add to list of prohibitions.
pcercuei 0:03b5121a232e 19194 */
pcercuei 0:03b5121a232e 19195 xmlSchemaItemListAddSize(prohibs, 2, use);
pcercuei 0:03b5121a232e 19196 continue;
pcercuei 0:03b5121a232e 19197 }
pcercuei 0:03b5121a232e 19198 if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
pcercuei 0:03b5121a232e 19199 ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
pcercuei 0:03b5121a232e 19200 {
pcercuei 0:03b5121a232e 19201 if ((WXS_QNAME_CAST use)->item == NULL)
pcercuei 0:03b5121a232e 19202 return(-1);
pcercuei 0:03b5121a232e 19203 gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
pcercuei 0:03b5121a232e 19204 /*
pcercuei 0:03b5121a232e 19205 * Expand the referenced attr. group.
pcercuei 0:03b5121a232e 19206 * TODO: remove this, this is done in a previous step, so
pcercuei 0:03b5121a232e 19207 * already done here.
pcercuei 0:03b5121a232e 19208 */
pcercuei 0:03b5121a232e 19209 if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
pcercuei 0:03b5121a232e 19210 if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
pcercuei 0:03b5121a232e 19211 return(-1);
pcercuei 0:03b5121a232e 19212 }
pcercuei 0:03b5121a232e 19213 /*
pcercuei 0:03b5121a232e 19214 * Build the 'complete' wildcard; i.e. intersect multiple
pcercuei 0:03b5121a232e 19215 * wildcards.
pcercuei 0:03b5121a232e 19216 */
pcercuei 0:03b5121a232e 19217 if (gr->attributeWildcard != NULL) {
pcercuei 0:03b5121a232e 19218 if (*completeWild == NULL) {
pcercuei 0:03b5121a232e 19219 *completeWild = gr->attributeWildcard;
pcercuei 0:03b5121a232e 19220 } else {
pcercuei 0:03b5121a232e 19221 if (! created) {
pcercuei 0:03b5121a232e 19222 xmlSchemaWildcardPtr tmpWild;
pcercuei 0:03b5121a232e 19223
pcercuei 0:03b5121a232e 19224 /*
pcercuei 0:03b5121a232e 19225 * Copy the first encountered wildcard as context,
pcercuei 0:03b5121a232e 19226 * except for the annotation.
pcercuei 0:03b5121a232e 19227 *
pcercuei 0:03b5121a232e 19228 * Although the complete wildcard might not correspond
pcercuei 0:03b5121a232e 19229 * to any node in the schema, we will anchor it on
pcercuei 0:03b5121a232e 19230 * the node of the owner component.
pcercuei 0:03b5121a232e 19231 */
pcercuei 0:03b5121a232e 19232 tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema,
pcercuei 0:03b5121a232e 19233 XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
pcercuei 0:03b5121a232e 19234 WXS_ITEM_NODE(item));
pcercuei 0:03b5121a232e 19235 if (tmpWild == NULL)
pcercuei 0:03b5121a232e 19236 return(-1);
pcercuei 0:03b5121a232e 19237 if (xmlSchemaCloneWildcardNsConstraints(pctxt,
pcercuei 0:03b5121a232e 19238 tmpWild, *completeWild) == -1)
pcercuei 0:03b5121a232e 19239 return (-1);
pcercuei 0:03b5121a232e 19240 tmpWild->processContents = (*completeWild)->processContents;
pcercuei 0:03b5121a232e 19241 *completeWild = tmpWild;
pcercuei 0:03b5121a232e 19242 created = 1;
pcercuei 0:03b5121a232e 19243 }
pcercuei 0:03b5121a232e 19244
pcercuei 0:03b5121a232e 19245 if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
pcercuei 0:03b5121a232e 19246 gr->attributeWildcard) == -1)
pcercuei 0:03b5121a232e 19247 return(-1);
pcercuei 0:03b5121a232e 19248 }
pcercuei 0:03b5121a232e 19249 }
pcercuei 0:03b5121a232e 19250 /*
pcercuei 0:03b5121a232e 19251 * Just remove the reference if the referenced group does not
pcercuei 0:03b5121a232e 19252 * contain any attribute uses.
pcercuei 0:03b5121a232e 19253 */
pcercuei 0:03b5121a232e 19254 sublist = ((xmlSchemaItemListPtr) gr->attrUses);
pcercuei 0:03b5121a232e 19255 if ((sublist == NULL) || sublist->nbItems == 0) {
pcercuei 0:03b5121a232e 19256 if (xmlSchemaItemListRemove(list, i) == -1)
pcercuei 0:03b5121a232e 19257 return(-1);
pcercuei 0:03b5121a232e 19258 i--;
pcercuei 0:03b5121a232e 19259 continue;
pcercuei 0:03b5121a232e 19260 }
pcercuei 0:03b5121a232e 19261 /*
pcercuei 0:03b5121a232e 19262 * Add the attribute uses.
pcercuei 0:03b5121a232e 19263 */
pcercuei 0:03b5121a232e 19264 list->items[i] = sublist->items[0];
pcercuei 0:03b5121a232e 19265 if (sublist->nbItems != 1) {
pcercuei 0:03b5121a232e 19266 for (j = 1; j < sublist->nbItems; j++) {
pcercuei 0:03b5121a232e 19267 i++;
pcercuei 0:03b5121a232e 19268 if (xmlSchemaItemListInsert(list,
pcercuei 0:03b5121a232e 19269 sublist->items[j], i) == -1)
pcercuei 0:03b5121a232e 19270 return(-1);
pcercuei 0:03b5121a232e 19271 }
pcercuei 0:03b5121a232e 19272 }
pcercuei 0:03b5121a232e 19273 }
pcercuei 0:03b5121a232e 19274
pcercuei 0:03b5121a232e 19275 }
pcercuei 0:03b5121a232e 19276 /*
pcercuei 0:03b5121a232e 19277 * Handle pointless prohibitions of declared attributes.
pcercuei 0:03b5121a232e 19278 */
pcercuei 0:03b5121a232e 19279 if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
pcercuei 0:03b5121a232e 19280 xmlSchemaAttributeUseProhibPtr prohib;
pcercuei 0:03b5121a232e 19281
pcercuei 0:03b5121a232e 19282 for (i = prohibs->nbItems -1; i >= 0; i--) {
pcercuei 0:03b5121a232e 19283 prohib = prohibs->items[i];
pcercuei 0:03b5121a232e 19284 for (j = 0; j < list->nbItems; j++) {
pcercuei 0:03b5121a232e 19285 use = list->items[j];
pcercuei 0:03b5121a232e 19286
pcercuei 0:03b5121a232e 19287 if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
pcercuei 0:03b5121a232e 19288 (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
pcercuei 0:03b5121a232e 19289 {
pcercuei 0:03b5121a232e 19290 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 19291
pcercuei 0:03b5121a232e 19292 xmlSchemaCustomWarning(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 19293 XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
pcercuei 0:03b5121a232e 19294 prohib->node, NULL,
pcercuei 0:03b5121a232e 19295 "Skipping pointless attribute use prohibition "
pcercuei 0:03b5121a232e 19296 "'%s', since a corresponding attribute use "
pcercuei 0:03b5121a232e 19297 "exists already in the type definition",
pcercuei 0:03b5121a232e 19298 xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 19299 prohib->targetNamespace, prohib->name),
pcercuei 0:03b5121a232e 19300 NULL, NULL);
pcercuei 0:03b5121a232e 19301 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 19302 /*
pcercuei 0:03b5121a232e 19303 * Remove the prohibition.
pcercuei 0:03b5121a232e 19304 */
pcercuei 0:03b5121a232e 19305 if (xmlSchemaItemListRemove(prohibs, i) == -1)
pcercuei 0:03b5121a232e 19306 return(-1);
pcercuei 0:03b5121a232e 19307 break;
pcercuei 0:03b5121a232e 19308 }
pcercuei 0:03b5121a232e 19309 }
pcercuei 0:03b5121a232e 19310 }
pcercuei 0:03b5121a232e 19311 }
pcercuei 0:03b5121a232e 19312 return(0);
pcercuei 0:03b5121a232e 19313 }
pcercuei 0:03b5121a232e 19314
pcercuei 0:03b5121a232e 19315 /**
pcercuei 0:03b5121a232e 19316 * xmlSchemaAttributeGroupExpandRefs:
pcercuei 0:03b5121a232e 19317 * @pctxt: the parser context
pcercuei 0:03b5121a232e 19318 * @attrGr: the attribute group definition
pcercuei 0:03b5121a232e 19319 *
pcercuei 0:03b5121a232e 19320 * Computation of:
pcercuei 0:03b5121a232e 19321 * {attribute uses} property
pcercuei 0:03b5121a232e 19322 * {attribute wildcard} property
pcercuei 0:03b5121a232e 19323 *
pcercuei 0:03b5121a232e 19324 * Substitutes contained attribute group references
pcercuei 0:03b5121a232e 19325 * for their attribute uses. Wilcards are intersected.
pcercuei 0:03b5121a232e 19326 */
pcercuei 0:03b5121a232e 19327 static int
pcercuei 0:03b5121a232e 19328 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 19329 xmlSchemaAttributeGroupPtr attrGr)
pcercuei 0:03b5121a232e 19330 {
pcercuei 0:03b5121a232e 19331 if ((attrGr->attrUses == NULL) ||
pcercuei 0:03b5121a232e 19332 (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
pcercuei 0:03b5121a232e 19333 return(0);
pcercuei 0:03b5121a232e 19334
pcercuei 0:03b5121a232e 19335 attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
pcercuei 0:03b5121a232e 19336 if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
pcercuei 0:03b5121a232e 19337 &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
pcercuei 0:03b5121a232e 19338 return(-1);
pcercuei 0:03b5121a232e 19339 return(0);
pcercuei 0:03b5121a232e 19340 }
pcercuei 0:03b5121a232e 19341
pcercuei 0:03b5121a232e 19342 /**
pcercuei 0:03b5121a232e 19343 * xmlSchemaAttributeGroupExpandRefs:
pcercuei 0:03b5121a232e 19344 * @pctxt: the parser context
pcercuei 0:03b5121a232e 19345 * @attrGr: the attribute group definition
pcercuei 0:03b5121a232e 19346 *
pcercuei 0:03b5121a232e 19347 * Substitutes contained attribute group references
pcercuei 0:03b5121a232e 19348 * for their attribute uses. Wilcards are intersected.
pcercuei 0:03b5121a232e 19349 *
pcercuei 0:03b5121a232e 19350 * Schema Component Constraint:
pcercuei 0:03b5121a232e 19351 * Attribute Group Definition Properties Correct (ag-props-correct)
pcercuei 0:03b5121a232e 19352 */
pcercuei 0:03b5121a232e 19353 static int
pcercuei 0:03b5121a232e 19354 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 19355 xmlSchemaAttributeGroupPtr attrGr)
pcercuei 0:03b5121a232e 19356 {
pcercuei 0:03b5121a232e 19357 /*
pcercuei 0:03b5121a232e 19358 * SPEC ag-props-correct
pcercuei 0:03b5121a232e 19359 * (1) "The values of the properties of an attribute group definition
pcercuei 0:03b5121a232e 19360 * must be as described in the property tableau in The Attribute
pcercuei 0:03b5121a232e 19361 * Group Definition Schema Component ($3.6.1), modulo the impact of
pcercuei 0:03b5121a232e 19362 * Missing Sub-components ($5.3);"
pcercuei 0:03b5121a232e 19363 */
pcercuei 0:03b5121a232e 19364
pcercuei 0:03b5121a232e 19365 if ((attrGr->attrUses != NULL) &&
pcercuei 0:03b5121a232e 19366 (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
pcercuei 0:03b5121a232e 19367 {
pcercuei 0:03b5121a232e 19368 xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
pcercuei 0:03b5121a232e 19369 xmlSchemaAttributeUsePtr use, tmp;
pcercuei 0:03b5121a232e 19370 int i, j, hasId = 0;
pcercuei 0:03b5121a232e 19371
pcercuei 0:03b5121a232e 19372 for (i = uses->nbItems -1; i >= 0; i--) {
pcercuei 0:03b5121a232e 19373 use = uses->items[i];
pcercuei 0:03b5121a232e 19374 /*
pcercuei 0:03b5121a232e 19375 * SPEC ag-props-correct
pcercuei 0:03b5121a232e 19376 * (2) "Two distinct members of the {attribute uses} must not have
pcercuei 0:03b5121a232e 19377 * {attribute declaration}s both of whose {name}s match and whose
pcercuei 0:03b5121a232e 19378 * {target namespace}s are identical."
pcercuei 0:03b5121a232e 19379 */
pcercuei 0:03b5121a232e 19380 if (i > 0) {
pcercuei 0:03b5121a232e 19381 for (j = i -1; j >= 0; j--) {
pcercuei 0:03b5121a232e 19382 tmp = uses->items[j];
pcercuei 0:03b5121a232e 19383 if ((WXS_ATTRUSE_DECL_NAME(use) ==
pcercuei 0:03b5121a232e 19384 WXS_ATTRUSE_DECL_NAME(tmp)) &&
pcercuei 0:03b5121a232e 19385 (WXS_ATTRUSE_DECL_TNS(use) ==
pcercuei 0:03b5121a232e 19386 WXS_ATTRUSE_DECL_TNS(tmp)))
pcercuei 0:03b5121a232e 19387 {
pcercuei 0:03b5121a232e 19388 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 19389
pcercuei 0:03b5121a232e 19390 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 19391 XML_SCHEMAP_AG_PROPS_CORRECT,
pcercuei 0:03b5121a232e 19392 attrGr->node, WXS_BASIC_CAST attrGr,
pcercuei 0:03b5121a232e 19393 "Duplicate %s",
pcercuei 0:03b5121a232e 19394 xmlSchemaGetComponentDesignation(&str, use),
pcercuei 0:03b5121a232e 19395 NULL);
pcercuei 0:03b5121a232e 19396 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 19397 /*
pcercuei 0:03b5121a232e 19398 * Remove the duplicate.
pcercuei 0:03b5121a232e 19399 */
pcercuei 0:03b5121a232e 19400 if (xmlSchemaItemListRemove(uses, i) == -1)
pcercuei 0:03b5121a232e 19401 return(-1);
pcercuei 0:03b5121a232e 19402 goto next_use;
pcercuei 0:03b5121a232e 19403 }
pcercuei 0:03b5121a232e 19404 }
pcercuei 0:03b5121a232e 19405 }
pcercuei 0:03b5121a232e 19406 /*
pcercuei 0:03b5121a232e 19407 * SPEC ag-props-correct
pcercuei 0:03b5121a232e 19408 * (3) "Two distinct members of the {attribute uses} must not have
pcercuei 0:03b5121a232e 19409 * {attribute declaration}s both of whose {type definition}s are or
pcercuei 0:03b5121a232e 19410 * are derived from ID."
pcercuei 0:03b5121a232e 19411 * TODO: Does 'derived' include member-types of unions?
pcercuei 0:03b5121a232e 19412 */
pcercuei 0:03b5121a232e 19413 if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
pcercuei 0:03b5121a232e 19414 if (xmlSchemaIsDerivedFromBuiltInType(
pcercuei 0:03b5121a232e 19415 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
pcercuei 0:03b5121a232e 19416 {
pcercuei 0:03b5121a232e 19417 if (hasId) {
pcercuei 0:03b5121a232e 19418 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 19419
pcercuei 0:03b5121a232e 19420 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 19421 XML_SCHEMAP_AG_PROPS_CORRECT,
pcercuei 0:03b5121a232e 19422 attrGr->node, WXS_BASIC_CAST attrGr,
pcercuei 0:03b5121a232e 19423 "There must not exist more than one attribute "
pcercuei 0:03b5121a232e 19424 "declaration of type 'xs:ID' "
pcercuei 0:03b5121a232e 19425 "(or derived from 'xs:ID'). The %s violates this "
pcercuei 0:03b5121a232e 19426 "constraint",
pcercuei 0:03b5121a232e 19427 xmlSchemaGetComponentDesignation(&str, use),
pcercuei 0:03b5121a232e 19428 NULL);
pcercuei 0:03b5121a232e 19429 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 19430 if (xmlSchemaItemListRemove(uses, i) == -1)
pcercuei 0:03b5121a232e 19431 return(-1);
pcercuei 0:03b5121a232e 19432 }
pcercuei 0:03b5121a232e 19433 hasId = 1;
pcercuei 0:03b5121a232e 19434 }
pcercuei 0:03b5121a232e 19435 }
pcercuei 0:03b5121a232e 19436 next_use: {}
pcercuei 0:03b5121a232e 19437 }
pcercuei 0:03b5121a232e 19438 }
pcercuei 0:03b5121a232e 19439 return(0);
pcercuei 0:03b5121a232e 19440 }
pcercuei 0:03b5121a232e 19441
pcercuei 0:03b5121a232e 19442 /**
pcercuei 0:03b5121a232e 19443 * xmlSchemaResolveAttrGroupReferences:
pcercuei 0:03b5121a232e 19444 * @attrgrpDecl: the schema attribute definition
pcercuei 0:03b5121a232e 19445 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 19446 * @name: the attribute name
pcercuei 0:03b5121a232e 19447 *
pcercuei 0:03b5121a232e 19448 * Resolves references to attribute group definitions.
pcercuei 0:03b5121a232e 19449 */
pcercuei 0:03b5121a232e 19450 static int
pcercuei 0:03b5121a232e 19451 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
pcercuei 0:03b5121a232e 19452 xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 19453 {
pcercuei 0:03b5121a232e 19454 xmlSchemaAttributeGroupPtr group;
pcercuei 0:03b5121a232e 19455
pcercuei 0:03b5121a232e 19456 if (ref->item != NULL)
pcercuei 0:03b5121a232e 19457 return(0);
pcercuei 0:03b5121a232e 19458 group = xmlSchemaGetAttributeGroup(ctxt->schema,
pcercuei 0:03b5121a232e 19459 ref->name,
pcercuei 0:03b5121a232e 19460 ref->targetNamespace);
pcercuei 0:03b5121a232e 19461 if (group == NULL) {
pcercuei 0:03b5121a232e 19462 xmlSchemaPResCompAttrErr(ctxt,
pcercuei 0:03b5121a232e 19463 XML_SCHEMAP_SRC_RESOLVE,
pcercuei 0:03b5121a232e 19464 NULL, ref->node,
pcercuei 0:03b5121a232e 19465 "ref", ref->name, ref->targetNamespace,
pcercuei 0:03b5121a232e 19466 ref->itemType, NULL);
pcercuei 0:03b5121a232e 19467 return(ctxt->err);
pcercuei 0:03b5121a232e 19468 }
pcercuei 0:03b5121a232e 19469 ref->item = WXS_BASIC_CAST group;
pcercuei 0:03b5121a232e 19470 return(0);
pcercuei 0:03b5121a232e 19471 }
pcercuei 0:03b5121a232e 19472
pcercuei 0:03b5121a232e 19473 /**
pcercuei 0:03b5121a232e 19474 * xmlSchemaCheckAttrPropsCorrect:
pcercuei 0:03b5121a232e 19475 * @item: an schema attribute declaration/use
pcercuei 0:03b5121a232e 19476 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 19477 * @name: the name of the attribute
pcercuei 0:03b5121a232e 19478 *
pcercuei 0:03b5121a232e 19479 *
pcercuei 0:03b5121a232e 19480 * Schema Component Constraint:
pcercuei 0:03b5121a232e 19481 * Attribute Declaration Properties Correct (a-props-correct)
pcercuei 0:03b5121a232e 19482 *
pcercuei 0:03b5121a232e 19483 * Validates the value constraints of an attribute declaration/use.
pcercuei 0:03b5121a232e 19484 * NOTE that this needs the simle type definitions to be already
pcercuei 0:03b5121a232e 19485 * builded and checked.
pcercuei 0:03b5121a232e 19486 */
pcercuei 0:03b5121a232e 19487 static int
pcercuei 0:03b5121a232e 19488 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 19489 xmlSchemaAttributePtr attr)
pcercuei 0:03b5121a232e 19490 {
pcercuei 0:03b5121a232e 19491
pcercuei 0:03b5121a232e 19492 /*
pcercuei 0:03b5121a232e 19493 * SPEC a-props-correct (1)
pcercuei 0:03b5121a232e 19494 * "The values of the properties of an attribute declaration must
pcercuei 0:03b5121a232e 19495 * be as described in the property tableau in The Attribute
pcercuei 0:03b5121a232e 19496 * Declaration Schema Component ($3.2.1), modulo the impact of
pcercuei 0:03b5121a232e 19497 * Missing Sub-components ($5.3)."
pcercuei 0:03b5121a232e 19498 */
pcercuei 0:03b5121a232e 19499
pcercuei 0:03b5121a232e 19500 if (WXS_ATTR_TYPEDEF(attr) == NULL)
pcercuei 0:03b5121a232e 19501 return(0);
pcercuei 0:03b5121a232e 19502
pcercuei 0:03b5121a232e 19503 if (attr->defValue != NULL) {
pcercuei 0:03b5121a232e 19504 int ret;
pcercuei 0:03b5121a232e 19505
pcercuei 0:03b5121a232e 19506 /*
pcercuei 0:03b5121a232e 19507 * SPEC a-props-correct (3)
pcercuei 0:03b5121a232e 19508 * "If the {type definition} is or is derived from ID then there
pcercuei 0:03b5121a232e 19509 * must not be a {value constraint}."
pcercuei 0:03b5121a232e 19510 */
pcercuei 0:03b5121a232e 19511 if (xmlSchemaIsDerivedFromBuiltInType(
pcercuei 0:03b5121a232e 19512 WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
pcercuei 0:03b5121a232e 19513 {
pcercuei 0:03b5121a232e 19514 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 19515 XML_SCHEMAP_A_PROPS_CORRECT_3,
pcercuei 0:03b5121a232e 19516 NULL, WXS_BASIC_CAST attr,
pcercuei 0:03b5121a232e 19517 "Value constraints are not allowed if the type definition "
pcercuei 0:03b5121a232e 19518 "is or is derived from xs:ID",
pcercuei 0:03b5121a232e 19519 NULL, NULL);
pcercuei 0:03b5121a232e 19520 return(pctxt->err);
pcercuei 0:03b5121a232e 19521 }
pcercuei 0:03b5121a232e 19522 /*
pcercuei 0:03b5121a232e 19523 * SPEC a-props-correct (2)
pcercuei 0:03b5121a232e 19524 * "if there is a {value constraint}, the canonical lexical
pcercuei 0:03b5121a232e 19525 * representation of its value must be `valid` with respect
pcercuei 0:03b5121a232e 19526 * to the {type definition} as defined in String Valid ($3.14.4)."
pcercuei 0:03b5121a232e 19527 * TODO: Don't care about the *canonical* stuff here, this requirement
pcercuei 0:03b5121a232e 19528 * will be removed in WXS 1.1 anyway.
pcercuei 0:03b5121a232e 19529 */
pcercuei 0:03b5121a232e 19530 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 19531 attr->node, WXS_ATTR_TYPEDEF(attr),
pcercuei 0:03b5121a232e 19532 attr->defValue, &(attr->defVal),
pcercuei 0:03b5121a232e 19533 1, 1, 0);
pcercuei 0:03b5121a232e 19534 if (ret != 0) {
pcercuei 0:03b5121a232e 19535 if (ret < 0) {
pcercuei 0:03b5121a232e 19536 PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
pcercuei 0:03b5121a232e 19537 "calling xmlSchemaVCheckCVCSimpleType()");
pcercuei 0:03b5121a232e 19538 return(-1);
pcercuei 0:03b5121a232e 19539 }
pcercuei 0:03b5121a232e 19540 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 19541 XML_SCHEMAP_A_PROPS_CORRECT_2,
pcercuei 0:03b5121a232e 19542 NULL, WXS_BASIC_CAST attr,
pcercuei 0:03b5121a232e 19543 "The value of the value constraint is not valid",
pcercuei 0:03b5121a232e 19544 NULL, NULL);
pcercuei 0:03b5121a232e 19545 return(pctxt->err);
pcercuei 0:03b5121a232e 19546 }
pcercuei 0:03b5121a232e 19547 }
pcercuei 0:03b5121a232e 19548
pcercuei 0:03b5121a232e 19549 return(0);
pcercuei 0:03b5121a232e 19550 }
pcercuei 0:03b5121a232e 19551
pcercuei 0:03b5121a232e 19552 static xmlSchemaElementPtr
pcercuei 0:03b5121a232e 19553 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
pcercuei 0:03b5121a232e 19554 xmlSchemaElementPtr ancestor)
pcercuei 0:03b5121a232e 19555 {
pcercuei 0:03b5121a232e 19556 xmlSchemaElementPtr ret;
pcercuei 0:03b5121a232e 19557
pcercuei 0:03b5121a232e 19558 if (WXS_SUBST_HEAD(ancestor) == NULL)
pcercuei 0:03b5121a232e 19559 return (NULL);
pcercuei 0:03b5121a232e 19560 if (WXS_SUBST_HEAD(ancestor) == elemDecl)
pcercuei 0:03b5121a232e 19561 return (ancestor);
pcercuei 0:03b5121a232e 19562
pcercuei 0:03b5121a232e 19563 if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
pcercuei 0:03b5121a232e 19564 return (NULL);
pcercuei 0:03b5121a232e 19565 WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
pcercuei 0:03b5121a232e 19566 ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
pcercuei 0:03b5121a232e 19567 WXS_SUBST_HEAD(ancestor));
pcercuei 0:03b5121a232e 19568 WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
pcercuei 0:03b5121a232e 19569
pcercuei 0:03b5121a232e 19570 return (ret);
pcercuei 0:03b5121a232e 19571 }
pcercuei 0:03b5121a232e 19572
pcercuei 0:03b5121a232e 19573 /**
pcercuei 0:03b5121a232e 19574 * xmlSchemaCheckElemPropsCorrect:
pcercuei 0:03b5121a232e 19575 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 19576 * @decl: the element declaration
pcercuei 0:03b5121a232e 19577 * @name: the name of the attribute
pcercuei 0:03b5121a232e 19578 *
pcercuei 0:03b5121a232e 19579 * Schema Component Constraint:
pcercuei 0:03b5121a232e 19580 * Element Declaration Properties Correct (e-props-correct)
pcercuei 0:03b5121a232e 19581 *
pcercuei 0:03b5121a232e 19582 * STATUS:
pcercuei 0:03b5121a232e 19583 * missing: (6)
pcercuei 0:03b5121a232e 19584 */
pcercuei 0:03b5121a232e 19585 static int
pcercuei 0:03b5121a232e 19586 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 19587 xmlSchemaElementPtr elemDecl)
pcercuei 0:03b5121a232e 19588 {
pcercuei 0:03b5121a232e 19589 int ret = 0;
pcercuei 0:03b5121a232e 19590 xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
pcercuei 0:03b5121a232e 19591 /*
pcercuei 0:03b5121a232e 19592 * SPEC (1) "The values of the properties of an element declaration
pcercuei 0:03b5121a232e 19593 * must be as described in the property tableau in The Element
pcercuei 0:03b5121a232e 19594 * Declaration Schema Component ($3.3.1), modulo the impact of Missing
pcercuei 0:03b5121a232e 19595 * Sub-components ($5.3)."
pcercuei 0:03b5121a232e 19596 */
pcercuei 0:03b5121a232e 19597 if (WXS_SUBST_HEAD(elemDecl) != NULL) {
pcercuei 0:03b5121a232e 19598 xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
pcercuei 0:03b5121a232e 19599
pcercuei 0:03b5121a232e 19600 xmlSchemaCheckElementDeclComponent(head, pctxt);
pcercuei 0:03b5121a232e 19601 /*
pcercuei 0:03b5121a232e 19602 * SPEC (3) "If there is a non-`absent` {substitution group
pcercuei 0:03b5121a232e 19603 * affiliation}, then {scope} must be global."
pcercuei 0:03b5121a232e 19604 */
pcercuei 0:03b5121a232e 19605 if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
pcercuei 0:03b5121a232e 19606 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 19607 XML_SCHEMAP_E_PROPS_CORRECT_3,
pcercuei 0:03b5121a232e 19608 WXS_BASIC_CAST elemDecl, NULL,
pcercuei 0:03b5121a232e 19609 "Only global element declarations can have a "
pcercuei 0:03b5121a232e 19610 "substitution group affiliation", NULL);
pcercuei 0:03b5121a232e 19611 ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
pcercuei 0:03b5121a232e 19612 }
pcercuei 0:03b5121a232e 19613 /*
pcercuei 0:03b5121a232e 19614 * TODO: SPEC (6) "Circular substitution groups are disallowed.
pcercuei 0:03b5121a232e 19615 * That is, it must not be possible to return to an element declaration
pcercuei 0:03b5121a232e 19616 * by repeatedly following the {substitution group affiliation}
pcercuei 0:03b5121a232e 19617 * property."
pcercuei 0:03b5121a232e 19618 */
pcercuei 0:03b5121a232e 19619 if (head == elemDecl)
pcercuei 0:03b5121a232e 19620 circ = head;
pcercuei 0:03b5121a232e 19621 else if (WXS_SUBST_HEAD(head) != NULL)
pcercuei 0:03b5121a232e 19622 circ = xmlSchemaCheckSubstGroupCircular(head, head);
pcercuei 0:03b5121a232e 19623 else
pcercuei 0:03b5121a232e 19624 circ = NULL;
pcercuei 0:03b5121a232e 19625 if (circ != NULL) {
pcercuei 0:03b5121a232e 19626 xmlChar *strA = NULL, *strB = NULL;
pcercuei 0:03b5121a232e 19627
pcercuei 0:03b5121a232e 19628 xmlSchemaPCustomErrExt(pctxt,
pcercuei 0:03b5121a232e 19629 XML_SCHEMAP_E_PROPS_CORRECT_6,
pcercuei 0:03b5121a232e 19630 WXS_BASIC_CAST circ, NULL,
pcercuei 0:03b5121a232e 19631 "The element declaration '%s' defines a circular "
pcercuei 0:03b5121a232e 19632 "substitution group to element declaration '%s'",
pcercuei 0:03b5121a232e 19633 xmlSchemaGetComponentQName(&strA, circ),
pcercuei 0:03b5121a232e 19634 xmlSchemaGetComponentQName(&strB, head),
pcercuei 0:03b5121a232e 19635 NULL);
pcercuei 0:03b5121a232e 19636 FREE_AND_NULL(strA)
pcercuei 0:03b5121a232e 19637 FREE_AND_NULL(strB)
pcercuei 0:03b5121a232e 19638 ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
pcercuei 0:03b5121a232e 19639 }
pcercuei 0:03b5121a232e 19640 /*
pcercuei 0:03b5121a232e 19641 * SPEC (4) "If there is a {substitution group affiliation},
pcercuei 0:03b5121a232e 19642 * the {type definition}
pcercuei 0:03b5121a232e 19643 * of the element declaration must be validly derived from the {type
pcercuei 0:03b5121a232e 19644 * definition} of the {substitution group affiliation}, given the value
pcercuei 0:03b5121a232e 19645 * of the {substitution group exclusions} of the {substitution group
pcercuei 0:03b5121a232e 19646 * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
pcercuei 0:03b5121a232e 19647 * (if the {type definition} is complex) or as defined in
pcercuei 0:03b5121a232e 19648 * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
pcercuei 0:03b5121a232e 19649 * simple)."
pcercuei 0:03b5121a232e 19650 *
pcercuei 0:03b5121a232e 19651 * NOTE: {substitution group exclusions} means the values of the
pcercuei 0:03b5121a232e 19652 * attribute "final".
pcercuei 0:03b5121a232e 19653 */
pcercuei 0:03b5121a232e 19654
pcercuei 0:03b5121a232e 19655 if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
pcercuei 0:03b5121a232e 19656 int set = 0;
pcercuei 0:03b5121a232e 19657
pcercuei 0:03b5121a232e 19658 if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
pcercuei 0:03b5121a232e 19659 set |= SUBSET_EXTENSION;
pcercuei 0:03b5121a232e 19660 if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
pcercuei 0:03b5121a232e 19661 set |= SUBSET_RESTRICTION;
pcercuei 0:03b5121a232e 19662
pcercuei 0:03b5121a232e 19663 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
pcercuei 0:03b5121a232e 19664 WXS_ELEM_TYPEDEF(head), set) != 0) {
pcercuei 0:03b5121a232e 19665 xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
pcercuei 0:03b5121a232e 19666
pcercuei 0:03b5121a232e 19667 ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
pcercuei 0:03b5121a232e 19668 xmlSchemaPCustomErrExt(pctxt,
pcercuei 0:03b5121a232e 19669 XML_SCHEMAP_E_PROPS_CORRECT_4,
pcercuei 0:03b5121a232e 19670 WXS_BASIC_CAST elemDecl, NULL,
pcercuei 0:03b5121a232e 19671 "The type definition '%s' was "
pcercuei 0:03b5121a232e 19672 "either rejected by the substitution group "
pcercuei 0:03b5121a232e 19673 "affiliation '%s', or not validly derived from its type "
pcercuei 0:03b5121a232e 19674 "definition '%s'",
pcercuei 0:03b5121a232e 19675 xmlSchemaGetComponentQName(&strA, typeDef),
pcercuei 0:03b5121a232e 19676 xmlSchemaGetComponentQName(&strB, head),
pcercuei 0:03b5121a232e 19677 xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
pcercuei 0:03b5121a232e 19678 FREE_AND_NULL(strA)
pcercuei 0:03b5121a232e 19679 FREE_AND_NULL(strB)
pcercuei 0:03b5121a232e 19680 FREE_AND_NULL(strC)
pcercuei 0:03b5121a232e 19681 }
pcercuei 0:03b5121a232e 19682 }
pcercuei 0:03b5121a232e 19683 }
pcercuei 0:03b5121a232e 19684 /*
pcercuei 0:03b5121a232e 19685 * SPEC (5) "If the {type definition} or {type definition}'s
pcercuei 0:03b5121a232e 19686 * {content type}
pcercuei 0:03b5121a232e 19687 * is or is derived from ID then there must not be a {value constraint}.
pcercuei 0:03b5121a232e 19688 * Note: The use of ID as a type definition for elements goes beyond
pcercuei 0:03b5121a232e 19689 * XML 1.0, and should be avoided if backwards compatibility is desired"
pcercuei 0:03b5121a232e 19690 */
pcercuei 0:03b5121a232e 19691 if ((elemDecl->value != NULL) &&
pcercuei 0:03b5121a232e 19692 ((WXS_IS_SIMPLE(typeDef) &&
pcercuei 0:03b5121a232e 19693 xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
pcercuei 0:03b5121a232e 19694 (WXS_IS_COMPLEX(typeDef) &&
pcercuei 0:03b5121a232e 19695 WXS_HAS_SIMPLE_CONTENT(typeDef) &&
pcercuei 0:03b5121a232e 19696 xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
pcercuei 0:03b5121a232e 19697 XML_SCHEMAS_ID)))) {
pcercuei 0:03b5121a232e 19698
pcercuei 0:03b5121a232e 19699 ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
pcercuei 0:03b5121a232e 19700 xmlSchemaPCustomErr(pctxt,
pcercuei 0:03b5121a232e 19701 XML_SCHEMAP_E_PROPS_CORRECT_5,
pcercuei 0:03b5121a232e 19702 WXS_BASIC_CAST elemDecl, NULL,
pcercuei 0:03b5121a232e 19703 "The type definition (or type definition's content type) is or "
pcercuei 0:03b5121a232e 19704 "is derived from ID; value constraints are not allowed in "
pcercuei 0:03b5121a232e 19705 "conjunction with such a type definition", NULL);
pcercuei 0:03b5121a232e 19706 } else if (elemDecl->value != NULL) {
pcercuei 0:03b5121a232e 19707 int vcret;
pcercuei 0:03b5121a232e 19708 xmlNodePtr node = NULL;
pcercuei 0:03b5121a232e 19709
pcercuei 0:03b5121a232e 19710 /*
pcercuei 0:03b5121a232e 19711 * SPEC (2) "If there is a {value constraint}, the canonical lexical
pcercuei 0:03b5121a232e 19712 * representation of its value must be `valid` with respect to the
pcercuei 0:03b5121a232e 19713 * {type definition} as defined in Element Default Valid (Immediate)
pcercuei 0:03b5121a232e 19714 * ($3.3.6)."
pcercuei 0:03b5121a232e 19715 */
pcercuei 0:03b5121a232e 19716 if (typeDef == NULL) {
pcercuei 0:03b5121a232e 19717 xmlSchemaPErr(pctxt, elemDecl->node,
pcercuei 0:03b5121a232e 19718 XML_SCHEMAP_INTERNAL,
pcercuei 0:03b5121a232e 19719 "Internal error: xmlSchemaCheckElemPropsCorrect, "
pcercuei 0:03b5121a232e 19720 "type is missing... skipping validation of "
pcercuei 0:03b5121a232e 19721 "the value constraint", NULL, NULL);
pcercuei 0:03b5121a232e 19722 return (-1);
pcercuei 0:03b5121a232e 19723 }
pcercuei 0:03b5121a232e 19724 if (elemDecl->node != NULL) {
pcercuei 0:03b5121a232e 19725 if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
pcercuei 0:03b5121a232e 19726 node = (xmlNodePtr) xmlHasProp(elemDecl->node,
pcercuei 0:03b5121a232e 19727 BAD_CAST "fixed");
pcercuei 0:03b5121a232e 19728 else
pcercuei 0:03b5121a232e 19729 node = (xmlNodePtr) xmlHasProp(elemDecl->node,
pcercuei 0:03b5121a232e 19730 BAD_CAST "default");
pcercuei 0:03b5121a232e 19731 }
pcercuei 0:03b5121a232e 19732 vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
pcercuei 0:03b5121a232e 19733 typeDef, elemDecl->value, &(elemDecl->defVal));
pcercuei 0:03b5121a232e 19734 if (vcret != 0) {
pcercuei 0:03b5121a232e 19735 if (vcret < 0) {
pcercuei 0:03b5121a232e 19736 PERROR_INT("xmlSchemaElemCheckValConstr",
pcercuei 0:03b5121a232e 19737 "failed to validate the value constraint of an "
pcercuei 0:03b5121a232e 19738 "element declaration");
pcercuei 0:03b5121a232e 19739 return (-1);
pcercuei 0:03b5121a232e 19740 }
pcercuei 0:03b5121a232e 19741 return (vcret);
pcercuei 0:03b5121a232e 19742 }
pcercuei 0:03b5121a232e 19743 }
pcercuei 0:03b5121a232e 19744
pcercuei 0:03b5121a232e 19745 return (ret);
pcercuei 0:03b5121a232e 19746 }
pcercuei 0:03b5121a232e 19747
pcercuei 0:03b5121a232e 19748 /**
pcercuei 0:03b5121a232e 19749 * xmlSchemaCheckElemSubstGroup:
pcercuei 0:03b5121a232e 19750 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 19751 * @decl: the element declaration
pcercuei 0:03b5121a232e 19752 * @name: the name of the attribute
pcercuei 0:03b5121a232e 19753 *
pcercuei 0:03b5121a232e 19754 * Schema Component Constraint:
pcercuei 0:03b5121a232e 19755 * Substitution Group (cos-equiv-class)
pcercuei 0:03b5121a232e 19756 *
pcercuei 0:03b5121a232e 19757 * In Libxml2 the subst. groups will be precomputed, in terms of that
pcercuei 0:03b5121a232e 19758 * a list will be built for each subst. group head, holding all direct
pcercuei 0:03b5121a232e 19759 * referents to this head.
pcercuei 0:03b5121a232e 19760 * NOTE that this function needs:
pcercuei 0:03b5121a232e 19761 * 1. circular subst. groups to be checked beforehand
pcercuei 0:03b5121a232e 19762 * 2. the declaration's type to be derived from the head's type
pcercuei 0:03b5121a232e 19763 *
pcercuei 0:03b5121a232e 19764 * STATUS:
pcercuei 0:03b5121a232e 19765 *
pcercuei 0:03b5121a232e 19766 */
pcercuei 0:03b5121a232e 19767 static void
pcercuei 0:03b5121a232e 19768 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 19769 xmlSchemaElementPtr elemDecl)
pcercuei 0:03b5121a232e 19770 {
pcercuei 0:03b5121a232e 19771 if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
pcercuei 0:03b5121a232e 19772 /* SPEC (1) "Its {abstract} is false." */
pcercuei 0:03b5121a232e 19773 (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
pcercuei 0:03b5121a232e 19774 return;
pcercuei 0:03b5121a232e 19775 {
pcercuei 0:03b5121a232e 19776 xmlSchemaElementPtr head;
pcercuei 0:03b5121a232e 19777 xmlSchemaTypePtr headType, type;
pcercuei 0:03b5121a232e 19778 int set, methSet;
pcercuei 0:03b5121a232e 19779 /*
pcercuei 0:03b5121a232e 19780 * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
pcercuei 0:03b5121a232e 19781 * {disallowed substitutions} as the blocking constraint, as defined in
pcercuei 0:03b5121a232e 19782 * Substitution Group OK (Transitive) ($3.3.6)."
pcercuei 0:03b5121a232e 19783 */
pcercuei 0:03b5121a232e 19784 for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
pcercuei 0:03b5121a232e 19785 head = WXS_SUBST_HEAD(head)) {
pcercuei 0:03b5121a232e 19786 set = 0;
pcercuei 0:03b5121a232e 19787 methSet = 0;
pcercuei 0:03b5121a232e 19788 /*
pcercuei 0:03b5121a232e 19789 * The blocking constraints.
pcercuei 0:03b5121a232e 19790 */
pcercuei 0:03b5121a232e 19791 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
pcercuei 0:03b5121a232e 19792 continue;
pcercuei 0:03b5121a232e 19793 headType = head->subtypes;
pcercuei 0:03b5121a232e 19794 type = elemDecl->subtypes;
pcercuei 0:03b5121a232e 19795 if (headType == type)
pcercuei 0:03b5121a232e 19796 goto add_member;
pcercuei 0:03b5121a232e 19797 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
pcercuei 0:03b5121a232e 19798 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
pcercuei 0:03b5121a232e 19799 if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
pcercuei 0:03b5121a232e 19800 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
pcercuei 0:03b5121a232e 19801 /*
pcercuei 0:03b5121a232e 19802 * SPEC: Substitution Group OK (Transitive) (2.3)
pcercuei 0:03b5121a232e 19803 * "The set of all {derivation method}s involved in the
pcercuei 0:03b5121a232e 19804 * derivation of D's {type definition} from C's {type definition}
pcercuei 0:03b5121a232e 19805 * does not intersect with the union of the blocking constraint,
pcercuei 0:03b5121a232e 19806 * C's {prohibited substitutions} (if C is complex, otherwise the
pcercuei 0:03b5121a232e 19807 * empty set) and the {prohibited substitutions} (respectively the
pcercuei 0:03b5121a232e 19808 * empty set) of any intermediate {type definition}s in the
pcercuei 0:03b5121a232e 19809 * derivation of D's {type definition} from C's {type definition}."
pcercuei 0:03b5121a232e 19810 */
pcercuei 0:03b5121a232e 19811 /*
pcercuei 0:03b5121a232e 19812 * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
pcercuei 0:03b5121a232e 19813 * subst.head axis, the methSet does not need to be computed for
pcercuei 0:03b5121a232e 19814 * the full depth over and over.
pcercuei 0:03b5121a232e 19815 */
pcercuei 0:03b5121a232e 19816 /*
pcercuei 0:03b5121a232e 19817 * The set of all {derivation method}s involved in the derivation
pcercuei 0:03b5121a232e 19818 */
pcercuei 0:03b5121a232e 19819 while ((type != NULL) && (type != headType)) {
pcercuei 0:03b5121a232e 19820 if ((WXS_IS_EXTENSION(type)) &&
pcercuei 0:03b5121a232e 19821 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
pcercuei 0:03b5121a232e 19822 methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
pcercuei 0:03b5121a232e 19823
pcercuei 0:03b5121a232e 19824 if (WXS_IS_RESTRICTION(type) &&
pcercuei 0:03b5121a232e 19825 ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
pcercuei 0:03b5121a232e 19826 methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
pcercuei 0:03b5121a232e 19827
pcercuei 0:03b5121a232e 19828 type = type->baseType;
pcercuei 0:03b5121a232e 19829 }
pcercuei 0:03b5121a232e 19830 /*
pcercuei 0:03b5121a232e 19831 * The {prohibited substitutions} of all intermediate types +
pcercuei 0:03b5121a232e 19832 * the head's type.
pcercuei 0:03b5121a232e 19833 */
pcercuei 0:03b5121a232e 19834 type = elemDecl->subtypes->baseType;
pcercuei 0:03b5121a232e 19835 while (type != NULL) {
pcercuei 0:03b5121a232e 19836 if (WXS_IS_COMPLEX(type)) {
pcercuei 0:03b5121a232e 19837 if ((type->flags &
pcercuei 0:03b5121a232e 19838 XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
pcercuei 0:03b5121a232e 19839 ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
pcercuei 0:03b5121a232e 19840 set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
pcercuei 0:03b5121a232e 19841 if ((type->flags &
pcercuei 0:03b5121a232e 19842 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
pcercuei 0:03b5121a232e 19843 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
pcercuei 0:03b5121a232e 19844 set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
pcercuei 0:03b5121a232e 19845 } else
pcercuei 0:03b5121a232e 19846 break;
pcercuei 0:03b5121a232e 19847 if (type == headType)
pcercuei 0:03b5121a232e 19848 break;
pcercuei 0:03b5121a232e 19849 type = type->baseType;
pcercuei 0:03b5121a232e 19850 }
pcercuei 0:03b5121a232e 19851 if ((set != 0) &&
pcercuei 0:03b5121a232e 19852 (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
pcercuei 0:03b5121a232e 19853 (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
pcercuei 0:03b5121a232e 19854 ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
pcercuei 0:03b5121a232e 19855 (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
pcercuei 0:03b5121a232e 19856 continue;
pcercuei 0:03b5121a232e 19857 }
pcercuei 0:03b5121a232e 19858 add_member:
pcercuei 0:03b5121a232e 19859 xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
pcercuei 0:03b5121a232e 19860 if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
pcercuei 0:03b5121a232e 19861 head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
pcercuei 0:03b5121a232e 19862 }
pcercuei 0:03b5121a232e 19863 }
pcercuei 0:03b5121a232e 19864 }
pcercuei 0:03b5121a232e 19865
pcercuei 0:03b5121a232e 19866 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
pcercuei 0:03b5121a232e 19867 /**
pcercuei 0:03b5121a232e 19868 * xmlSchemaCheckElementDeclComponent
pcercuei 0:03b5121a232e 19869 * @pctxt: the schema parser context
pcercuei 0:03b5121a232e 19870 * @ctxtComponent: the context component (an element declaration)
pcercuei 0:03b5121a232e 19871 * @ctxtParticle: the first particle of the context component
pcercuei 0:03b5121a232e 19872 * @searchParticle: the element declaration particle to be analysed
pcercuei 0:03b5121a232e 19873 *
pcercuei 0:03b5121a232e 19874 * Schema Component Constraint: Element Declarations Consistent
pcercuei 0:03b5121a232e 19875 */
pcercuei 0:03b5121a232e 19876 static int
pcercuei 0:03b5121a232e 19877 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 19878 xmlSchemaBasicItemPtr ctxtComponent,
pcercuei 0:03b5121a232e 19879 xmlSchemaParticlePtr ctxtParticle,
pcercuei 0:03b5121a232e 19880 xmlSchemaParticlePtr searchParticle,
pcercuei 0:03b5121a232e 19881 xmlSchemaParticlePtr curParticle,
pcercuei 0:03b5121a232e 19882 int search)
pcercuei 0:03b5121a232e 19883 {
pcercuei 0:03b5121a232e 19884 return(0);
pcercuei 0:03b5121a232e 19885
pcercuei 0:03b5121a232e 19886 int ret = 0;
pcercuei 0:03b5121a232e 19887 xmlSchemaParticlePtr cur = curParticle;
pcercuei 0:03b5121a232e 19888 if (curParticle == NULL) {
pcercuei 0:03b5121a232e 19889 return(0);
pcercuei 0:03b5121a232e 19890 }
pcercuei 0:03b5121a232e 19891 if (WXS_PARTICLE_TERM(curParticle) == NULL) {
pcercuei 0:03b5121a232e 19892 /*
pcercuei 0:03b5121a232e 19893 * Just return in this case. A missing "term" of the particle
pcercuei 0:03b5121a232e 19894 * might arise due to an invalid "term" component.
pcercuei 0:03b5121a232e 19895 */
pcercuei 0:03b5121a232e 19896 return(0);
pcercuei 0:03b5121a232e 19897 }
pcercuei 0:03b5121a232e 19898 while (cur != NULL) {
pcercuei 0:03b5121a232e 19899 switch (WXS_PARTICLE_TERM(cur)->type) {
pcercuei 0:03b5121a232e 19900 case XML_SCHEMA_TYPE_ANY:
pcercuei 0:03b5121a232e 19901 break;
pcercuei 0:03b5121a232e 19902 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 19903 if (search == 0) {
pcercuei 0:03b5121a232e 19904 ret = xmlSchemaCheckElementDeclConsistent(pctxt,
pcercuei 0:03b5121a232e 19905 ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
pcercuei 0:03b5121a232e 19906 if (ret != 0)
pcercuei 0:03b5121a232e 19907 return(ret);
pcercuei 0:03b5121a232e 19908 } else {
pcercuei 0:03b5121a232e 19909 xmlSchemaElementPtr elem =
pcercuei 0:03b5121a232e 19910 WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
pcercuei 0:03b5121a232e 19911 /*
pcercuei 0:03b5121a232e 19912 * SPEC Element Declarations Consistent:
pcercuei 0:03b5121a232e 19913 * "If the {particles} contains, either directly,
pcercuei 0:03b5121a232e 19914 * indirectly (that is, within the {particles} of a
pcercuei 0:03b5121a232e 19915 * contained model group, recursively) or `implicitly`
pcercuei 0:03b5121a232e 19916 * two or more element declaration particles with
pcercuei 0:03b5121a232e 19917 * the same {name} and {target namespace}, then
pcercuei 0:03b5121a232e 19918 * all their type definitions must be the same
pcercuei 0:03b5121a232e 19919 * top-level definition [...]"
pcercuei 0:03b5121a232e 19920 */
pcercuei 0:03b5121a232e 19921 if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
pcercuei 0:03b5121a232e 19922 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
pcercuei 0:03b5121a232e 19923 xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
pcercuei 0:03b5121a232e 19924 WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
pcercuei 0:03b5121a232e 19925 {
pcercuei 0:03b5121a232e 19926 xmlChar *strA = NULL, *strB = NULL;
pcercuei 0:03b5121a232e 19927
pcercuei 0:03b5121a232e 19928 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 19929 /* TODO: error code */
pcercuei 0:03b5121a232e 19930 XML_SCHEMAP_COS_NONAMBIG,
pcercuei 0:03b5121a232e 19931 WXS_ITEM_NODE(cur), NULL,
pcercuei 0:03b5121a232e 19932 "In the content model of %s, there are multiple "
pcercuei 0:03b5121a232e 19933 "element declarations for '%s' with different "
pcercuei 0:03b5121a232e 19934 "type definitions",
pcercuei 0:03b5121a232e 19935 xmlSchemaGetComponentDesignation(&strA,
pcercuei 0:03b5121a232e 19936 ctxtComponent),
pcercuei 0:03b5121a232e 19937 xmlSchemaFormatQName(&strB,
pcercuei 0:03b5121a232e 19938 WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
pcercuei 0:03b5121a232e 19939 WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
pcercuei 0:03b5121a232e 19940 FREE_AND_NULL(strA);
pcercuei 0:03b5121a232e 19941 FREE_AND_NULL(strB);
pcercuei 0:03b5121a232e 19942 return(XML_SCHEMAP_COS_NONAMBIG);
pcercuei 0:03b5121a232e 19943 }
pcercuei 0:03b5121a232e 19944 }
pcercuei 0:03b5121a232e 19945 break;
pcercuei 0:03b5121a232e 19946 case XML_SCHEMA_TYPE_SEQUENCE: {
pcercuei 0:03b5121a232e 19947 break;
pcercuei 0:03b5121a232e 19948 }
pcercuei 0:03b5121a232e 19949 case XML_SCHEMA_TYPE_CHOICE:{
pcercuei 0:03b5121a232e 19950 /*
pcercuei 0:03b5121a232e 19951 xmlSchemaTreeItemPtr sub;
pcercuei 0:03b5121a232e 19952
pcercuei 0:03b5121a232e 19953 sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr)
pcercuei 0:03b5121a232e 19954 while (sub != NULL) {
pcercuei 0:03b5121a232e 19955 ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
pcercuei 0:03b5121a232e 19956 ctxtParticle, ctxtElem);
pcercuei 0:03b5121a232e 19957 if (ret != 0)
pcercuei 0:03b5121a232e 19958 return(ret);
pcercuei 0:03b5121a232e 19959 sub = sub->next;
pcercuei 0:03b5121a232e 19960 }
pcercuei 0:03b5121a232e 19961 */
pcercuei 0:03b5121a232e 19962 break;
pcercuei 0:03b5121a232e 19963 }
pcercuei 0:03b5121a232e 19964 case XML_SCHEMA_TYPE_ALL:
pcercuei 0:03b5121a232e 19965 break;
pcercuei 0:03b5121a232e 19966 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 19967 break;
pcercuei 0:03b5121a232e 19968 default:
pcercuei 0:03b5121a232e 19969 xmlSchemaInternalErr2(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 19970 "xmlSchemaCheckElementDeclConsistent",
pcercuei 0:03b5121a232e 19971 "found unexpected term of type '%s' in content model",
pcercuei 0:03b5121a232e 19972 WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
pcercuei 0:03b5121a232e 19973 return(-1);
pcercuei 0:03b5121a232e 19974 }
pcercuei 0:03b5121a232e 19975 cur = (xmlSchemaParticlePtr) cur->next;
pcercuei 0:03b5121a232e 19976 }
pcercuei 0:03b5121a232e 19977
pcercuei 0:03b5121a232e 19978 exit:
pcercuei 0:03b5121a232e 19979 return(ret);
pcercuei 0:03b5121a232e 19980 }
pcercuei 0:03b5121a232e 19981 #endif
pcercuei 0:03b5121a232e 19982
pcercuei 0:03b5121a232e 19983 /**
pcercuei 0:03b5121a232e 19984 * xmlSchemaCheckElementDeclComponent
pcercuei 0:03b5121a232e 19985 * @item: an schema element declaration/particle
pcercuei 0:03b5121a232e 19986 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 19987 * @name: the name of the attribute
pcercuei 0:03b5121a232e 19988 *
pcercuei 0:03b5121a232e 19989 * Validates the value constraints of an element declaration.
pcercuei 0:03b5121a232e 19990 * Adds substitution group members.
pcercuei 0:03b5121a232e 19991 */
pcercuei 0:03b5121a232e 19992 static void
pcercuei 0:03b5121a232e 19993 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
pcercuei 0:03b5121a232e 19994 xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 19995 {
pcercuei 0:03b5121a232e 19996 if (elemDecl == NULL)
pcercuei 0:03b5121a232e 19997 return;
pcercuei 0:03b5121a232e 19998 if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
pcercuei 0:03b5121a232e 19999 return;
pcercuei 0:03b5121a232e 20000 elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
pcercuei 0:03b5121a232e 20001 if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
pcercuei 0:03b5121a232e 20002 /*
pcercuei 0:03b5121a232e 20003 * Adds substitution group members.
pcercuei 0:03b5121a232e 20004 */
pcercuei 0:03b5121a232e 20005 xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
pcercuei 0:03b5121a232e 20006 }
pcercuei 0:03b5121a232e 20007 }
pcercuei 0:03b5121a232e 20008
pcercuei 0:03b5121a232e 20009 /**
pcercuei 0:03b5121a232e 20010 * xmlSchemaResolveModelGroupParticleReferences:
pcercuei 0:03b5121a232e 20011 * @particle: a particle component
pcercuei 0:03b5121a232e 20012 * @ctxt: a parser context
pcercuei 0:03b5121a232e 20013 *
pcercuei 0:03b5121a232e 20014 * Resolves references of a model group's {particles} to
pcercuei 0:03b5121a232e 20015 * model group definitions and to element declarations.
pcercuei 0:03b5121a232e 20016 */
pcercuei 0:03b5121a232e 20017 static void
pcercuei 0:03b5121a232e 20018 xmlSchemaResolveModelGroupParticleReferences(
pcercuei 0:03b5121a232e 20019 xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 20020 xmlSchemaModelGroupPtr mg)
pcercuei 0:03b5121a232e 20021 {
pcercuei 0:03b5121a232e 20022 xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
pcercuei 0:03b5121a232e 20023 xmlSchemaQNameRefPtr ref;
pcercuei 0:03b5121a232e 20024 xmlSchemaBasicItemPtr refItem;
pcercuei 0:03b5121a232e 20025
pcercuei 0:03b5121a232e 20026 /*
pcercuei 0:03b5121a232e 20027 * URGENT TODO: Test this.
pcercuei 0:03b5121a232e 20028 */
pcercuei 0:03b5121a232e 20029 while (particle != NULL) {
pcercuei 0:03b5121a232e 20030 if ((WXS_PARTICLE_TERM(particle) == NULL) ||
pcercuei 0:03b5121a232e 20031 ((WXS_PARTICLE_TERM(particle))->type !=
pcercuei 0:03b5121a232e 20032 XML_SCHEMA_EXTRA_QNAMEREF))
pcercuei 0:03b5121a232e 20033 {
pcercuei 0:03b5121a232e 20034 goto next_particle;
pcercuei 0:03b5121a232e 20035 }
pcercuei 0:03b5121a232e 20036 ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
pcercuei 0:03b5121a232e 20037 /*
pcercuei 0:03b5121a232e 20038 * Resolve the reference.
pcercuei 0:03b5121a232e 20039 * NULL the {term} by default.
pcercuei 0:03b5121a232e 20040 */
pcercuei 0:03b5121a232e 20041 particle->children = NULL;
pcercuei 0:03b5121a232e 20042
pcercuei 0:03b5121a232e 20043 refItem = xmlSchemaGetNamedComponent(ctxt->schema,
pcercuei 0:03b5121a232e 20044 ref->itemType, ref->name, ref->targetNamespace);
pcercuei 0:03b5121a232e 20045 if (refItem == NULL) {
pcercuei 0:03b5121a232e 20046 xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
pcercuei 0:03b5121a232e 20047 NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
pcercuei 0:03b5121a232e 20048 ref->targetNamespace, ref->itemType, NULL);
pcercuei 0:03b5121a232e 20049 /* TODO: remove the particle. */
pcercuei 0:03b5121a232e 20050 goto next_particle;
pcercuei 0:03b5121a232e 20051 }
pcercuei 0:03b5121a232e 20052 if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
pcercuei 0:03b5121a232e 20053 if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
pcercuei 0:03b5121a232e 20054 /* TODO: remove the particle. */
pcercuei 0:03b5121a232e 20055 goto next_particle;
pcercuei 0:03b5121a232e 20056 /*
pcercuei 0:03b5121a232e 20057 * NOTE that we will assign the model group definition
pcercuei 0:03b5121a232e 20058 * itself to the "term" of the particle. This will ease
pcercuei 0:03b5121a232e 20059 * the check for circular model group definitions. After
pcercuei 0:03b5121a232e 20060 * that the "term" will be assigned the model group of the
pcercuei 0:03b5121a232e 20061 * model group definition.
pcercuei 0:03b5121a232e 20062 */
pcercuei 0:03b5121a232e 20063 if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
pcercuei 0:03b5121a232e 20064 XML_SCHEMA_TYPE_ALL) {
pcercuei 0:03b5121a232e 20065 /*
pcercuei 0:03b5121a232e 20066 * SPEC cos-all-limited (1)
pcercuei 0:03b5121a232e 20067 * SPEC cos-all-limited (1.2)
pcercuei 0:03b5121a232e 20068 * "It appears only as the value of one or both of the
pcercuei 0:03b5121a232e 20069 * following properties:"
pcercuei 0:03b5121a232e 20070 * (1.1) "the {model group} property of a model group
pcercuei 0:03b5121a232e 20071 * definition."
pcercuei 0:03b5121a232e 20072 * (1.2) "the {term} property of a particle [... of] the "
pcercuei 0:03b5121a232e 20073 * {content type} of a complex type definition."
pcercuei 0:03b5121a232e 20074 */
pcercuei 0:03b5121a232e 20075 xmlSchemaCustomErr(ACTXT_CAST ctxt,
pcercuei 0:03b5121a232e 20076 /* TODO: error code */
pcercuei 0:03b5121a232e 20077 XML_SCHEMAP_COS_ALL_LIMITED,
pcercuei 0:03b5121a232e 20078 WXS_ITEM_NODE(particle), NULL,
pcercuei 0:03b5121a232e 20079 "A model group definition is referenced, but "
pcercuei 0:03b5121a232e 20080 "it contains an 'all' model group, which "
pcercuei 0:03b5121a232e 20081 "cannot be contained by model groups",
pcercuei 0:03b5121a232e 20082 NULL, NULL);
pcercuei 0:03b5121a232e 20083 /* TODO: remove the particle. */
pcercuei 0:03b5121a232e 20084 goto next_particle;
pcercuei 0:03b5121a232e 20085 }
pcercuei 0:03b5121a232e 20086 particle->children = (xmlSchemaTreeItemPtr) refItem;
pcercuei 0:03b5121a232e 20087 } else {
pcercuei 0:03b5121a232e 20088 /*
pcercuei 0:03b5121a232e 20089 * TODO: Are referenced element declarations the only
pcercuei 0:03b5121a232e 20090 * other components we expect here?
pcercuei 0:03b5121a232e 20091 */
pcercuei 0:03b5121a232e 20092 particle->children = (xmlSchemaTreeItemPtr) refItem;
pcercuei 0:03b5121a232e 20093 }
pcercuei 0:03b5121a232e 20094 next_particle:
pcercuei 0:03b5121a232e 20095 particle = WXS_PTC_CAST particle->next;
pcercuei 0:03b5121a232e 20096 }
pcercuei 0:03b5121a232e 20097 }
pcercuei 0:03b5121a232e 20098
pcercuei 0:03b5121a232e 20099 static int
pcercuei 0:03b5121a232e 20100 xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
pcercuei 0:03b5121a232e 20101 xmlSchemaValPtr y)
pcercuei 0:03b5121a232e 20102 {
pcercuei 0:03b5121a232e 20103 xmlSchemaTypePtr tx, ty, ptx, pty;
pcercuei 0:03b5121a232e 20104 int ret;
pcercuei 0:03b5121a232e 20105
pcercuei 0:03b5121a232e 20106 while (x != NULL) {
pcercuei 0:03b5121a232e 20107 /* Same types. */
pcercuei 0:03b5121a232e 20108 tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
pcercuei 0:03b5121a232e 20109 ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
pcercuei 0:03b5121a232e 20110 ptx = xmlSchemaGetPrimitiveType(tx);
pcercuei 0:03b5121a232e 20111 pty = xmlSchemaGetPrimitiveType(ty);
pcercuei 0:03b5121a232e 20112 /*
pcercuei 0:03b5121a232e 20113 * (1) if a datatype T' is `derived` by `restriction` from an
pcercuei 0:03b5121a232e 20114 * atomic datatype T then the `value space` of T' is a subset of
pcercuei 0:03b5121a232e 20115 * the `value space` of T. */
pcercuei 0:03b5121a232e 20116 /*
pcercuei 0:03b5121a232e 20117 * (2) if datatypes T' and T'' are `derived` by `restriction`
pcercuei 0:03b5121a232e 20118 * from a common atomic ancestor T then the `value space`s of T'
pcercuei 0:03b5121a232e 20119 * and T'' may overlap.
pcercuei 0:03b5121a232e 20120 */
pcercuei 0:03b5121a232e 20121 if (ptx != pty)
pcercuei 0:03b5121a232e 20122 return(0);
pcercuei 0:03b5121a232e 20123 /*
pcercuei 0:03b5121a232e 20124 * We assume computed values to be normalized, so do a fast
pcercuei 0:03b5121a232e 20125 * string comparison for string based types.
pcercuei 0:03b5121a232e 20126 */
pcercuei 0:03b5121a232e 20127 if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
pcercuei 0:03b5121a232e 20128 WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
pcercuei 0:03b5121a232e 20129 if (! xmlStrEqual(
pcercuei 0:03b5121a232e 20130 xmlSchemaValueGetAsString(x),
pcercuei 0:03b5121a232e 20131 xmlSchemaValueGetAsString(y)))
pcercuei 0:03b5121a232e 20132 return (0);
pcercuei 0:03b5121a232e 20133 } else {
pcercuei 0:03b5121a232e 20134 ret = xmlSchemaCompareValuesWhtsp(
pcercuei 0:03b5121a232e 20135 x, XML_SCHEMA_WHITESPACE_PRESERVE,
pcercuei 0:03b5121a232e 20136 y, XML_SCHEMA_WHITESPACE_PRESERVE);
pcercuei 0:03b5121a232e 20137 if (ret == -2)
pcercuei 0:03b5121a232e 20138 return(-1);
pcercuei 0:03b5121a232e 20139 if (ret != 0)
pcercuei 0:03b5121a232e 20140 return(0);
pcercuei 0:03b5121a232e 20141 }
pcercuei 0:03b5121a232e 20142 /*
pcercuei 0:03b5121a232e 20143 * Lists.
pcercuei 0:03b5121a232e 20144 */
pcercuei 0:03b5121a232e 20145 x = xmlSchemaValueGetNext(x);
pcercuei 0:03b5121a232e 20146 if (x != NULL) {
pcercuei 0:03b5121a232e 20147 y = xmlSchemaValueGetNext(y);
pcercuei 0:03b5121a232e 20148 if (y == NULL)
pcercuei 0:03b5121a232e 20149 return (0);
pcercuei 0:03b5121a232e 20150 } else if (xmlSchemaValueGetNext(y) != NULL)
pcercuei 0:03b5121a232e 20151 return (0);
pcercuei 0:03b5121a232e 20152 else
pcercuei 0:03b5121a232e 20153 return (1);
pcercuei 0:03b5121a232e 20154 }
pcercuei 0:03b5121a232e 20155 return (0);
pcercuei 0:03b5121a232e 20156 }
pcercuei 0:03b5121a232e 20157
pcercuei 0:03b5121a232e 20158 /**
pcercuei 0:03b5121a232e 20159 * xmlSchemaResolveAttrUseReferences:
pcercuei 0:03b5121a232e 20160 * @item: an attribute use
pcercuei 0:03b5121a232e 20161 * @ctxt: a parser context
pcercuei 0:03b5121a232e 20162 *
pcercuei 0:03b5121a232e 20163 * Resolves the referenced attribute declaration.
pcercuei 0:03b5121a232e 20164 */
pcercuei 0:03b5121a232e 20165 static int
pcercuei 0:03b5121a232e 20166 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
pcercuei 0:03b5121a232e 20167 xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 20168 {
pcercuei 0:03b5121a232e 20169 if ((ctxt == NULL) || (ause == NULL))
pcercuei 0:03b5121a232e 20170 return(-1);
pcercuei 0:03b5121a232e 20171 if ((ause->attrDecl == NULL) ||
pcercuei 0:03b5121a232e 20172 (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
pcercuei 0:03b5121a232e 20173 return(0);
pcercuei 0:03b5121a232e 20174
pcercuei 0:03b5121a232e 20175 {
pcercuei 0:03b5121a232e 20176 xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
pcercuei 0:03b5121a232e 20177
pcercuei 0:03b5121a232e 20178 /*
pcercuei 0:03b5121a232e 20179 * TODO: Evaluate, what errors could occur if the declaration is not
pcercuei 0:03b5121a232e 20180 * found.
pcercuei 0:03b5121a232e 20181 */
pcercuei 0:03b5121a232e 20182 ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
pcercuei 0:03b5121a232e 20183 ref->name, ref->targetNamespace);
pcercuei 0:03b5121a232e 20184 if (ause->attrDecl == NULL) {
pcercuei 0:03b5121a232e 20185 xmlSchemaPResCompAttrErr(ctxt,
pcercuei 0:03b5121a232e 20186 XML_SCHEMAP_SRC_RESOLVE,
pcercuei 0:03b5121a232e 20187 WXS_BASIC_CAST ause, ause->node,
pcercuei 0:03b5121a232e 20188 "ref", ref->name, ref->targetNamespace,
pcercuei 0:03b5121a232e 20189 XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
pcercuei 0:03b5121a232e 20190 return(ctxt->err);;
pcercuei 0:03b5121a232e 20191 }
pcercuei 0:03b5121a232e 20192 }
pcercuei 0:03b5121a232e 20193 return(0);
pcercuei 0:03b5121a232e 20194 }
pcercuei 0:03b5121a232e 20195
pcercuei 0:03b5121a232e 20196 /**
pcercuei 0:03b5121a232e 20197 * xmlSchemaCheckAttrUsePropsCorrect:
pcercuei 0:03b5121a232e 20198 * @ctxt: a parser context
pcercuei 0:03b5121a232e 20199 * @use: an attribute use
pcercuei 0:03b5121a232e 20200 *
pcercuei 0:03b5121a232e 20201 * Schema Component Constraint:
pcercuei 0:03b5121a232e 20202 * Attribute Use Correct (au-props-correct)
pcercuei 0:03b5121a232e 20203 *
pcercuei 0:03b5121a232e 20204 */
pcercuei 0:03b5121a232e 20205 static int
pcercuei 0:03b5121a232e 20206 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 20207 xmlSchemaAttributeUsePtr use)
pcercuei 0:03b5121a232e 20208 {
pcercuei 0:03b5121a232e 20209 if ((ctxt == NULL) || (use == NULL))
pcercuei 0:03b5121a232e 20210 return(-1);
pcercuei 0:03b5121a232e 20211 if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
pcercuei 0:03b5121a232e 20212 ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
pcercuei 0:03b5121a232e 20213 return(0);
pcercuei 0:03b5121a232e 20214
pcercuei 0:03b5121a232e 20215 /*
pcercuei 0:03b5121a232e 20216 * SPEC au-props-correct (1)
pcercuei 0:03b5121a232e 20217 * "The values of the properties of an attribute use must be as
pcercuei 0:03b5121a232e 20218 * described in the property tableau in The Attribute Use Schema
pcercuei 0:03b5121a232e 20219 * Component ($3.5.1), modulo the impact of Missing
pcercuei 0:03b5121a232e 20220 * Sub-components ($5.3)."
pcercuei 0:03b5121a232e 20221 */
pcercuei 0:03b5121a232e 20222
pcercuei 0:03b5121a232e 20223 if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
pcercuei 0:03b5121a232e 20224 ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
pcercuei 0:03b5121a232e 20225 ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
pcercuei 0:03b5121a232e 20226 {
pcercuei 0:03b5121a232e 20227 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 20228 XML_SCHEMAP_AU_PROPS_CORRECT_2,
pcercuei 0:03b5121a232e 20229 WXS_BASIC_CAST use, NULL,
pcercuei 0:03b5121a232e 20230 "The attribute declaration has a 'fixed' value constraint "
pcercuei 0:03b5121a232e 20231 ", thus the attribute use must also have a 'fixed' value "
pcercuei 0:03b5121a232e 20232 "constraint",
pcercuei 0:03b5121a232e 20233 NULL);
pcercuei 0:03b5121a232e 20234 return(ctxt->err);
pcercuei 0:03b5121a232e 20235 }
pcercuei 0:03b5121a232e 20236 /*
pcercuei 0:03b5121a232e 20237 * Compute and check the value constraint's value.
pcercuei 0:03b5121a232e 20238 */
pcercuei 0:03b5121a232e 20239 if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
pcercuei 0:03b5121a232e 20240 int ret;
pcercuei 0:03b5121a232e 20241 /*
pcercuei 0:03b5121a232e 20242 * TODO: The spec seems to be missing a check of the
pcercuei 0:03b5121a232e 20243 * value constraint of the attribute use. We will do it here.
pcercuei 0:03b5121a232e 20244 */
pcercuei 0:03b5121a232e 20245 /*
pcercuei 0:03b5121a232e 20246 * SPEC a-props-correct (3)
pcercuei 0:03b5121a232e 20247 */
pcercuei 0:03b5121a232e 20248 if (xmlSchemaIsDerivedFromBuiltInType(
pcercuei 0:03b5121a232e 20249 WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
pcercuei 0:03b5121a232e 20250 {
pcercuei 0:03b5121a232e 20251 xmlSchemaCustomErr(ACTXT_CAST ctxt,
pcercuei 0:03b5121a232e 20252 XML_SCHEMAP_AU_PROPS_CORRECT,
pcercuei 0:03b5121a232e 20253 NULL, WXS_BASIC_CAST use,
pcercuei 0:03b5121a232e 20254 "Value constraints are not allowed if the type definition "
pcercuei 0:03b5121a232e 20255 "is or is derived from xs:ID",
pcercuei 0:03b5121a232e 20256 NULL, NULL);
pcercuei 0:03b5121a232e 20257 return(ctxt->err);
pcercuei 0:03b5121a232e 20258 }
pcercuei 0:03b5121a232e 20259
pcercuei 0:03b5121a232e 20260 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
pcercuei 0:03b5121a232e 20261 use->node, WXS_ATTRUSE_TYPEDEF(use),
pcercuei 0:03b5121a232e 20262 use->defValue, &(use->defVal),
pcercuei 0:03b5121a232e 20263 1, 1, 0);
pcercuei 0:03b5121a232e 20264 if (ret != 0) {
pcercuei 0:03b5121a232e 20265 if (ret < 0) {
pcercuei 0:03b5121a232e 20266 PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
pcercuei 0:03b5121a232e 20267 "calling xmlSchemaVCheckCVCSimpleType()");
pcercuei 0:03b5121a232e 20268 return(-1);
pcercuei 0:03b5121a232e 20269 }
pcercuei 0:03b5121a232e 20270 xmlSchemaCustomErr(ACTXT_CAST ctxt,
pcercuei 0:03b5121a232e 20271 XML_SCHEMAP_AU_PROPS_CORRECT,
pcercuei 0:03b5121a232e 20272 NULL, WXS_BASIC_CAST use,
pcercuei 0:03b5121a232e 20273 "The value of the value constraint is not valid",
pcercuei 0:03b5121a232e 20274 NULL, NULL);
pcercuei 0:03b5121a232e 20275 return(ctxt->err);
pcercuei 0:03b5121a232e 20276 }
pcercuei 0:03b5121a232e 20277 }
pcercuei 0:03b5121a232e 20278 /*
pcercuei 0:03b5121a232e 20279 * SPEC au-props-correct (2)
pcercuei 0:03b5121a232e 20280 * "If the {attribute declaration} has a fixed
pcercuei 0:03b5121a232e 20281 * {value constraint}, then if the attribute use itself has a
pcercuei 0:03b5121a232e 20282 * {value constraint}, it must also be fixed and its value must match
pcercuei 0:03b5121a232e 20283 * that of the {attribute declaration}'s {value constraint}."
pcercuei 0:03b5121a232e 20284 */
pcercuei 0:03b5121a232e 20285 if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
pcercuei 0:03b5121a232e 20286 (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
pcercuei 0:03b5121a232e 20287 {
pcercuei 0:03b5121a232e 20288 if (! xmlSchemaAreValuesEqual(use->defVal,
pcercuei 0:03b5121a232e 20289 (WXS_ATTRUSE_DECL(use))->defVal))
pcercuei 0:03b5121a232e 20290 {
pcercuei 0:03b5121a232e 20291 xmlSchemaPCustomErr(ctxt,
pcercuei 0:03b5121a232e 20292 XML_SCHEMAP_AU_PROPS_CORRECT_2,
pcercuei 0:03b5121a232e 20293 WXS_BASIC_CAST use, NULL,
pcercuei 0:03b5121a232e 20294 "The 'fixed' value constraint of the attribute use "
pcercuei 0:03b5121a232e 20295 "must match the attribute declaration's value "
pcercuei 0:03b5121a232e 20296 "constraint '%s'",
pcercuei 0:03b5121a232e 20297 (WXS_ATTRUSE_DECL(use))->defValue);
pcercuei 0:03b5121a232e 20298 }
pcercuei 0:03b5121a232e 20299 return(ctxt->err);
pcercuei 0:03b5121a232e 20300 }
pcercuei 0:03b5121a232e 20301 return(0);
pcercuei 0:03b5121a232e 20302 }
pcercuei 0:03b5121a232e 20303
pcercuei 0:03b5121a232e 20304
pcercuei 0:03b5121a232e 20305
pcercuei 0:03b5121a232e 20306
pcercuei 0:03b5121a232e 20307 /**
pcercuei 0:03b5121a232e 20308 * xmlSchemaResolveAttrTypeReferences:
pcercuei 0:03b5121a232e 20309 * @item: an attribute declaration
pcercuei 0:03b5121a232e 20310 * @ctxt: a parser context
pcercuei 0:03b5121a232e 20311 *
pcercuei 0:03b5121a232e 20312 * Resolves the referenced type definition component.
pcercuei 0:03b5121a232e 20313 */
pcercuei 0:03b5121a232e 20314 static int
pcercuei 0:03b5121a232e 20315 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
pcercuei 0:03b5121a232e 20316 xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 20317 {
pcercuei 0:03b5121a232e 20318 /*
pcercuei 0:03b5121a232e 20319 * The simple type definition corresponding to the <simpleType> element
pcercuei 0:03b5121a232e 20320 * information item in the [children], if present, otherwise the simple
pcercuei 0:03b5121a232e 20321 * type definition `resolved` to by the `actual value` of the type
pcercuei 0:03b5121a232e 20322 * [attribute], if present, otherwise the `simple ur-type definition`.
pcercuei 0:03b5121a232e 20323 */
pcercuei 0:03b5121a232e 20324 if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
pcercuei 0:03b5121a232e 20325 return(0);
pcercuei 0:03b5121a232e 20326 item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
pcercuei 0:03b5121a232e 20327 if (item->subtypes != NULL)
pcercuei 0:03b5121a232e 20328 return(0);
pcercuei 0:03b5121a232e 20329 if (item->typeName != NULL) {
pcercuei 0:03b5121a232e 20330 xmlSchemaTypePtr type;
pcercuei 0:03b5121a232e 20331
pcercuei 0:03b5121a232e 20332 type = xmlSchemaGetType(ctxt->schema, item->typeName,
pcercuei 0:03b5121a232e 20333 item->typeNs);
pcercuei 0:03b5121a232e 20334 if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
pcercuei 0:03b5121a232e 20335 xmlSchemaPResCompAttrErr(ctxt,
pcercuei 0:03b5121a232e 20336 XML_SCHEMAP_SRC_RESOLVE,
pcercuei 0:03b5121a232e 20337 WXS_BASIC_CAST item, item->node,
pcercuei 0:03b5121a232e 20338 "type", item->typeName, item->typeNs,
pcercuei 0:03b5121a232e 20339 XML_SCHEMA_TYPE_SIMPLE, NULL);
pcercuei 0:03b5121a232e 20340 return(ctxt->err);
pcercuei 0:03b5121a232e 20341 } else
pcercuei 0:03b5121a232e 20342 item->subtypes = type;
pcercuei 0:03b5121a232e 20343
pcercuei 0:03b5121a232e 20344 } else {
pcercuei 0:03b5121a232e 20345 /*
pcercuei 0:03b5121a232e 20346 * The type defaults to the xs:anySimpleType.
pcercuei 0:03b5121a232e 20347 */
pcercuei 0:03b5121a232e 20348 item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
pcercuei 0:03b5121a232e 20349 }
pcercuei 0:03b5121a232e 20350 return(0);
pcercuei 0:03b5121a232e 20351 }
pcercuei 0:03b5121a232e 20352
pcercuei 0:03b5121a232e 20353 /**
pcercuei 0:03b5121a232e 20354 * xmlSchemaResolveIDCKeyReferences:
pcercuei 0:03b5121a232e 20355 * @idc: the identity-constraint definition
pcercuei 0:03b5121a232e 20356 * @ctxt: the schema parser context
pcercuei 0:03b5121a232e 20357 * @name: the attribute name
pcercuei 0:03b5121a232e 20358 *
pcercuei 0:03b5121a232e 20359 * Resolve keyRef references to key/unique IDCs.
pcercuei 0:03b5121a232e 20360 * Schema Component Constraint:
pcercuei 0:03b5121a232e 20361 * Identity-constraint Definition Properties Correct (c-props-correct)
pcercuei 0:03b5121a232e 20362 */
pcercuei 0:03b5121a232e 20363 static int
pcercuei 0:03b5121a232e 20364 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
pcercuei 0:03b5121a232e 20365 xmlSchemaParserCtxtPtr pctxt)
pcercuei 0:03b5121a232e 20366 {
pcercuei 0:03b5121a232e 20367 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
pcercuei 0:03b5121a232e 20368 return(0);
pcercuei 0:03b5121a232e 20369 if (idc->ref->name != NULL) {
pcercuei 0:03b5121a232e 20370 idc->ref->item = (xmlSchemaBasicItemPtr)
pcercuei 0:03b5121a232e 20371 xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
pcercuei 0:03b5121a232e 20372 idc->ref->targetNamespace);
pcercuei 0:03b5121a232e 20373 if (idc->ref->item == NULL) {
pcercuei 0:03b5121a232e 20374 /*
pcercuei 0:03b5121a232e 20375 * TODO: It is actually not an error to fail to resolve
pcercuei 0:03b5121a232e 20376 * at this stage. BUT we need to be that strict!
pcercuei 0:03b5121a232e 20377 */
pcercuei 0:03b5121a232e 20378 xmlSchemaPResCompAttrErr(pctxt,
pcercuei 0:03b5121a232e 20379 XML_SCHEMAP_SRC_RESOLVE,
pcercuei 0:03b5121a232e 20380 WXS_BASIC_CAST idc, idc->node,
pcercuei 0:03b5121a232e 20381 "refer", idc->ref->name,
pcercuei 0:03b5121a232e 20382 idc->ref->targetNamespace,
pcercuei 0:03b5121a232e 20383 XML_SCHEMA_TYPE_IDC_KEY, NULL);
pcercuei 0:03b5121a232e 20384 return(pctxt->err);
pcercuei 0:03b5121a232e 20385 } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
pcercuei 0:03b5121a232e 20386 /*
pcercuei 0:03b5121a232e 20387 * SPEC c-props-correct (1)
pcercuei 0:03b5121a232e 20388 */
pcercuei 0:03b5121a232e 20389 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 20390 XML_SCHEMAP_C_PROPS_CORRECT,
pcercuei 0:03b5121a232e 20391 NULL, WXS_BASIC_CAST idc,
pcercuei 0:03b5121a232e 20392 "The keyref references a keyref",
pcercuei 0:03b5121a232e 20393 NULL, NULL);
pcercuei 0:03b5121a232e 20394 idc->ref->item = NULL;
pcercuei 0:03b5121a232e 20395 return(pctxt->err);
pcercuei 0:03b5121a232e 20396 } else {
pcercuei 0:03b5121a232e 20397 if (idc->nbFields !=
pcercuei 0:03b5121a232e 20398 ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
pcercuei 0:03b5121a232e 20399 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 20400 xmlSchemaIDCPtr refer;
pcercuei 0:03b5121a232e 20401
pcercuei 0:03b5121a232e 20402 refer = (xmlSchemaIDCPtr) idc->ref->item;
pcercuei 0:03b5121a232e 20403 /*
pcercuei 0:03b5121a232e 20404 * SPEC c-props-correct(2)
pcercuei 0:03b5121a232e 20405 * "If the {identity-constraint category} is keyref,
pcercuei 0:03b5121a232e 20406 * the cardinality of the {fields} must equal that of
pcercuei 0:03b5121a232e 20407 * the {fields} of the {referenced key}.
pcercuei 0:03b5121a232e 20408 */
pcercuei 0:03b5121a232e 20409 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 20410 XML_SCHEMAP_C_PROPS_CORRECT,
pcercuei 0:03b5121a232e 20411 NULL, WXS_BASIC_CAST idc,
pcercuei 0:03b5121a232e 20412 "The cardinality of the keyref differs from the "
pcercuei 0:03b5121a232e 20413 "cardinality of the referenced key/unique '%s'",
pcercuei 0:03b5121a232e 20414 xmlSchemaFormatQName(&str, refer->targetNamespace,
pcercuei 0:03b5121a232e 20415 refer->name),
pcercuei 0:03b5121a232e 20416 NULL);
pcercuei 0:03b5121a232e 20417 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 20418 return(pctxt->err);
pcercuei 0:03b5121a232e 20419 }
pcercuei 0:03b5121a232e 20420 }
pcercuei 0:03b5121a232e 20421 }
pcercuei 0:03b5121a232e 20422 return(0);
pcercuei 0:03b5121a232e 20423 }
pcercuei 0:03b5121a232e 20424
pcercuei 0:03b5121a232e 20425 static int
pcercuei 0:03b5121a232e 20426 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
pcercuei 0:03b5121a232e 20427 xmlSchemaParserCtxtPtr pctxt)
pcercuei 0:03b5121a232e 20428 {
pcercuei 0:03b5121a232e 20429 if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
pcercuei 0:03b5121a232e 20430 prohib->targetNamespace) == NULL) {
pcercuei 0:03b5121a232e 20431
pcercuei 0:03b5121a232e 20432 xmlSchemaPResCompAttrErr(pctxt,
pcercuei 0:03b5121a232e 20433 XML_SCHEMAP_SRC_RESOLVE,
pcercuei 0:03b5121a232e 20434 NULL, prohib->node,
pcercuei 0:03b5121a232e 20435 "ref", prohib->name, prohib->targetNamespace,
pcercuei 0:03b5121a232e 20436 XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
pcercuei 0:03b5121a232e 20437 return(XML_SCHEMAP_SRC_RESOLVE);
pcercuei 0:03b5121a232e 20438 }
pcercuei 0:03b5121a232e 20439 return(0);
pcercuei 0:03b5121a232e 20440 }
pcercuei 0:03b5121a232e 20441
pcercuei 0:03b5121a232e 20442 #define WXS_REDEFINED_TYPE(c) \
pcercuei 0:03b5121a232e 20443 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
pcercuei 0:03b5121a232e 20444
pcercuei 0:03b5121a232e 20445 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
pcercuei 0:03b5121a232e 20446 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
pcercuei 0:03b5121a232e 20447
pcercuei 0:03b5121a232e 20448 #define WXS_REDEFINED_ATTR_GROUP(c) \
pcercuei 0:03b5121a232e 20449 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
pcercuei 0:03b5121a232e 20450
pcercuei 0:03b5121a232e 20451 static int
pcercuei 0:03b5121a232e 20452 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
pcercuei 0:03b5121a232e 20453 {
pcercuei 0:03b5121a232e 20454 int err = 0;
pcercuei 0:03b5121a232e 20455 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
pcercuei 0:03b5121a232e 20456 xmlSchemaBasicItemPtr prev, item;
pcercuei 0:03b5121a232e 20457 int wasRedefined;
pcercuei 0:03b5121a232e 20458
pcercuei 0:03b5121a232e 20459 if (redef == NULL)
pcercuei 0:03b5121a232e 20460 return(0);
pcercuei 0:03b5121a232e 20461
pcercuei 0:03b5121a232e 20462 do {
pcercuei 0:03b5121a232e 20463 item = redef->item;
pcercuei 0:03b5121a232e 20464 /*
pcercuei 0:03b5121a232e 20465 * First try to locate the redefined component in the
pcercuei 0:03b5121a232e 20466 * schema graph starting with the redefined schema.
pcercuei 0:03b5121a232e 20467 * NOTE: According to this schema bug entry:
pcercuei 0:03b5121a232e 20468 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
pcercuei 0:03b5121a232e 20469 * it's not clear if the referenced component needs to originate
pcercuei 0:03b5121a232e 20470 * from the <redefine>d schema _document_ or the schema; the latter
pcercuei 0:03b5121a232e 20471 * would include all imported and included sub-schemas of the
pcercuei 0:03b5121a232e 20472 * <redefine>d schema. Currenlty we latter approach is used.
pcercuei 0:03b5121a232e 20473 * SUPPLEMENT: It seems that the WG moves towards the latter
pcercuei 0:03b5121a232e 20474 * approach, so we are doing it right.
pcercuei 0:03b5121a232e 20475 *
pcercuei 0:03b5121a232e 20476 */
pcercuei 0:03b5121a232e 20477 prev = xmlSchemaFindRedefCompInGraph(
pcercuei 0:03b5121a232e 20478 redef->targetBucket, item->type,
pcercuei 0:03b5121a232e 20479 redef->refName, redef->refTargetNs);
pcercuei 0:03b5121a232e 20480 if (prev == NULL) {
pcercuei 0:03b5121a232e 20481 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 20482 xmlNodePtr node;
pcercuei 0:03b5121a232e 20483
pcercuei 0:03b5121a232e 20484 /*
pcercuei 0:03b5121a232e 20485 * SPEC src-redefine:
pcercuei 0:03b5121a232e 20486 * (6.2.1) "The `actual value` of its own name attribute plus
pcercuei 0:03b5121a232e 20487 * target namespace must successfully `resolve` to a model
pcercuei 0:03b5121a232e 20488 * group definition in I."
pcercuei 0:03b5121a232e 20489 * (7.2.1) "The `actual value` of its own name attribute plus
pcercuei 0:03b5121a232e 20490 * target namespace must successfully `resolve` to an attribute
pcercuei 0:03b5121a232e 20491 * group definition in I."
pcercuei 0:03b5121a232e 20492
pcercuei 0:03b5121a232e 20493 *
pcercuei 0:03b5121a232e 20494 * Note that, if we are redefining with the use of references
pcercuei 0:03b5121a232e 20495 * to components, the spec assumes the src-resolve to be used;
pcercuei 0:03b5121a232e 20496 * but this won't assure that we search only *inside* the
pcercuei 0:03b5121a232e 20497 * redefined schema.
pcercuei 0:03b5121a232e 20498 */
pcercuei 0:03b5121a232e 20499 if (redef->reference)
pcercuei 0:03b5121a232e 20500 node = WXS_ITEM_NODE(redef->reference);
pcercuei 0:03b5121a232e 20501 else
pcercuei 0:03b5121a232e 20502 node = WXS_ITEM_NODE(item);
pcercuei 0:03b5121a232e 20503 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 20504 /*
pcercuei 0:03b5121a232e 20505 * TODO: error code.
pcercuei 0:03b5121a232e 20506 * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
pcercuei 0:03b5121a232e 20507 * reference kind.
pcercuei 0:03b5121a232e 20508 */
pcercuei 0:03b5121a232e 20509 XML_SCHEMAP_SRC_REDEFINE, node, NULL,
pcercuei 0:03b5121a232e 20510 "The %s '%s' to be redefined could not be found in "
pcercuei 0:03b5121a232e 20511 "the redefined schema",
pcercuei 0:03b5121a232e 20512 WXS_ITEM_TYPE_NAME(item),
pcercuei 0:03b5121a232e 20513 xmlSchemaFormatQName(&str, redef->refTargetNs,
pcercuei 0:03b5121a232e 20514 redef->refName));
pcercuei 0:03b5121a232e 20515 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 20516 err = pctxt->err;
pcercuei 0:03b5121a232e 20517 redef = redef->next;
pcercuei 0:03b5121a232e 20518 continue;
pcercuei 0:03b5121a232e 20519 }
pcercuei 0:03b5121a232e 20520 /*
pcercuei 0:03b5121a232e 20521 * TODO: Obtaining and setting the redefinition state is really
pcercuei 0:03b5121a232e 20522 * clumsy.
pcercuei 0:03b5121a232e 20523 */
pcercuei 0:03b5121a232e 20524 wasRedefined = 0;
pcercuei 0:03b5121a232e 20525 switch (item->type) {
pcercuei 0:03b5121a232e 20526 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 20527 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 20528 if ((WXS_TYPE_CAST prev)->flags &
pcercuei 0:03b5121a232e 20529 XML_SCHEMAS_TYPE_REDEFINED)
pcercuei 0:03b5121a232e 20530 {
pcercuei 0:03b5121a232e 20531 wasRedefined = 1;
pcercuei 0:03b5121a232e 20532 break;
pcercuei 0:03b5121a232e 20533 }
pcercuei 0:03b5121a232e 20534 /* Mark it as redefined. */
pcercuei 0:03b5121a232e 20535 (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
pcercuei 0:03b5121a232e 20536 /*
pcercuei 0:03b5121a232e 20537 * Assign the redefined type to the
pcercuei 0:03b5121a232e 20538 * base type of the redefining type.
pcercuei 0:03b5121a232e 20539 * TODO: How
pcercuei 0:03b5121a232e 20540 */
pcercuei 0:03b5121a232e 20541 ((xmlSchemaTypePtr) item)->baseType =
pcercuei 0:03b5121a232e 20542 (xmlSchemaTypePtr) prev;
pcercuei 0:03b5121a232e 20543 break;
pcercuei 0:03b5121a232e 20544 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 20545 if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
pcercuei 0:03b5121a232e 20546 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
pcercuei 0:03b5121a232e 20547 {
pcercuei 0:03b5121a232e 20548 wasRedefined = 1;
pcercuei 0:03b5121a232e 20549 break;
pcercuei 0:03b5121a232e 20550 }
pcercuei 0:03b5121a232e 20551 /* Mark it as redefined. */
pcercuei 0:03b5121a232e 20552 (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
pcercuei 0:03b5121a232e 20553 XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
pcercuei 0:03b5121a232e 20554 if (redef->reference != NULL) {
pcercuei 0:03b5121a232e 20555 /*
pcercuei 0:03b5121a232e 20556 * Overwrite the QName-reference with the
pcercuei 0:03b5121a232e 20557 * referenced model group def.
pcercuei 0:03b5121a232e 20558 */
pcercuei 0:03b5121a232e 20559 (WXS_PTC_CAST redef->reference)->children =
pcercuei 0:03b5121a232e 20560 WXS_TREE_CAST prev;
pcercuei 0:03b5121a232e 20561 }
pcercuei 0:03b5121a232e 20562 redef->target = prev;
pcercuei 0:03b5121a232e 20563 break;
pcercuei 0:03b5121a232e 20564 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 20565 if ((WXS_ATTR_GROUP_CAST prev)->flags &
pcercuei 0:03b5121a232e 20566 XML_SCHEMAS_ATTRGROUP_REDEFINED)
pcercuei 0:03b5121a232e 20567 {
pcercuei 0:03b5121a232e 20568 wasRedefined = 1;
pcercuei 0:03b5121a232e 20569 break;
pcercuei 0:03b5121a232e 20570 }
pcercuei 0:03b5121a232e 20571 (WXS_ATTR_GROUP_CAST prev)->flags |=
pcercuei 0:03b5121a232e 20572 XML_SCHEMAS_ATTRGROUP_REDEFINED;
pcercuei 0:03b5121a232e 20573 if (redef->reference != NULL) {
pcercuei 0:03b5121a232e 20574 /*
pcercuei 0:03b5121a232e 20575 * Assign the redefined attribute group to the
pcercuei 0:03b5121a232e 20576 * QName-reference component.
pcercuei 0:03b5121a232e 20577 * This is the easy case, since we will just
pcercuei 0:03b5121a232e 20578 * expand the redefined group.
pcercuei 0:03b5121a232e 20579 */
pcercuei 0:03b5121a232e 20580 (WXS_QNAME_CAST redef->reference)->item = prev;
pcercuei 0:03b5121a232e 20581 redef->target = NULL;
pcercuei 0:03b5121a232e 20582 } else {
pcercuei 0:03b5121a232e 20583 /*
pcercuei 0:03b5121a232e 20584 * This is the complicated case: we need
pcercuei 0:03b5121a232e 20585 * to apply src-redefine (7.2.2) at a later
pcercuei 0:03b5121a232e 20586 * stage, i.e. when attribute group references
pcercuei 0:03b5121a232e 20587 * have beed expanded and simple types have
pcercuei 0:03b5121a232e 20588 * beed fixed.
pcercuei 0:03b5121a232e 20589 */
pcercuei 0:03b5121a232e 20590 redef->target = prev;
pcercuei 0:03b5121a232e 20591 }
pcercuei 0:03b5121a232e 20592 break;
pcercuei 0:03b5121a232e 20593 default:
pcercuei 0:03b5121a232e 20594 PERROR_INT("xmlSchemaResolveRedefReferences",
pcercuei 0:03b5121a232e 20595 "Unexpected redefined component type");
pcercuei 0:03b5121a232e 20596 return(-1);
pcercuei 0:03b5121a232e 20597 }
pcercuei 0:03b5121a232e 20598 if (wasRedefined) {
pcercuei 0:03b5121a232e 20599 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 20600 xmlNodePtr node;
pcercuei 0:03b5121a232e 20601
pcercuei 0:03b5121a232e 20602 if (redef->reference)
pcercuei 0:03b5121a232e 20603 node = WXS_ITEM_NODE(redef->reference);
pcercuei 0:03b5121a232e 20604 else
pcercuei 0:03b5121a232e 20605 node = WXS_ITEM_NODE(redef->item);
pcercuei 0:03b5121a232e 20606
pcercuei 0:03b5121a232e 20607 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 20608 /* TODO: error code. */
pcercuei 0:03b5121a232e 20609 XML_SCHEMAP_SRC_REDEFINE,
pcercuei 0:03b5121a232e 20610 node, NULL,
pcercuei 0:03b5121a232e 20611 "The referenced %s was already redefined. Multiple "
pcercuei 0:03b5121a232e 20612 "redefinition of the same component is not supported",
pcercuei 0:03b5121a232e 20613 xmlSchemaGetComponentDesignation(&str, prev),
pcercuei 0:03b5121a232e 20614 NULL);
pcercuei 0:03b5121a232e 20615 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 20616 err = pctxt->err;
pcercuei 0:03b5121a232e 20617 redef = redef->next;
pcercuei 0:03b5121a232e 20618 continue;
pcercuei 0:03b5121a232e 20619 }
pcercuei 0:03b5121a232e 20620 redef = redef->next;
pcercuei 0:03b5121a232e 20621 } while (redef != NULL);
pcercuei 0:03b5121a232e 20622
pcercuei 0:03b5121a232e 20623 return(err);
pcercuei 0:03b5121a232e 20624 }
pcercuei 0:03b5121a232e 20625
pcercuei 0:03b5121a232e 20626 static int
pcercuei 0:03b5121a232e 20627 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
pcercuei 0:03b5121a232e 20628 {
pcercuei 0:03b5121a232e 20629 int err = 0;
pcercuei 0:03b5121a232e 20630 xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
pcercuei 0:03b5121a232e 20631 xmlSchemaBasicItemPtr item;
pcercuei 0:03b5121a232e 20632
pcercuei 0:03b5121a232e 20633 if (redef == NULL)
pcercuei 0:03b5121a232e 20634 return(0);
pcercuei 0:03b5121a232e 20635
pcercuei 0:03b5121a232e 20636 do {
pcercuei 0:03b5121a232e 20637 if (redef->target == NULL) {
pcercuei 0:03b5121a232e 20638 redef = redef->next;
pcercuei 0:03b5121a232e 20639 continue;
pcercuei 0:03b5121a232e 20640 }
pcercuei 0:03b5121a232e 20641 item = redef->item;
pcercuei 0:03b5121a232e 20642
pcercuei 0:03b5121a232e 20643 switch (item->type) {
pcercuei 0:03b5121a232e 20644 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 20645 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 20646 /*
pcercuei 0:03b5121a232e 20647 * Since the spec wants the {name} of the redefined
pcercuei 0:03b5121a232e 20648 * type to be 'absent', we'll NULL it.
pcercuei 0:03b5121a232e 20649 */
pcercuei 0:03b5121a232e 20650 (WXS_TYPE_CAST redef->target)->name = NULL;
pcercuei 0:03b5121a232e 20651
pcercuei 0:03b5121a232e 20652 /*
pcercuei 0:03b5121a232e 20653 * TODO: Seems like there's nothing more to do. The normal
pcercuei 0:03b5121a232e 20654 * inheritance mechanism is used. But not 100% sure.
pcercuei 0:03b5121a232e 20655 */
pcercuei 0:03b5121a232e 20656 break;
pcercuei 0:03b5121a232e 20657 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 20658 /*
pcercuei 0:03b5121a232e 20659 * URGENT TODO:
pcercuei 0:03b5121a232e 20660 * SPEC src-redefine:
pcercuei 0:03b5121a232e 20661 * (6.2.2) "The {model group} of the model group definition
pcercuei 0:03b5121a232e 20662 * which corresponds to it per XML Representation of Model
pcercuei 0:03b5121a232e 20663 * Group Definition Schema Components ($3.7.2) must be a
pcercuei 0:03b5121a232e 20664 * `valid restriction` of the {model group} of that model
pcercuei 0:03b5121a232e 20665 * group definition in I, as defined in Particle Valid
pcercuei 0:03b5121a232e 20666 * (Restriction) ($3.9.6)."
pcercuei 0:03b5121a232e 20667 */
pcercuei 0:03b5121a232e 20668 break;
pcercuei 0:03b5121a232e 20669 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 20670 /*
pcercuei 0:03b5121a232e 20671 * SPEC src-redefine:
pcercuei 0:03b5121a232e 20672 * (7.2.2) "The {attribute uses} and {attribute wildcard} of
pcercuei 0:03b5121a232e 20673 * the attribute group definition which corresponds to it
pcercuei 0:03b5121a232e 20674 * per XML Representation of Attribute Group Definition Schema
pcercuei 0:03b5121a232e 20675 * Components ($3.6.2) must be `valid restrictions` of the
pcercuei 0:03b5121a232e 20676 * {attribute uses} and {attribute wildcard} of that attribute
pcercuei 0:03b5121a232e 20677 * group definition in I, as defined in clause 2, clause 3 and
pcercuei 0:03b5121a232e 20678 * clause 4 of Derivation Valid (Restriction, Complex)
pcercuei 0:03b5121a232e 20679 * ($3.4.6) (where references to the base type definition are
pcercuei 0:03b5121a232e 20680 * understood as references to the attribute group definition
pcercuei 0:03b5121a232e 20681 * in I)."
pcercuei 0:03b5121a232e 20682 */
pcercuei 0:03b5121a232e 20683 err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
pcercuei 0:03b5121a232e 20684 XML_SCHEMA_ACTION_REDEFINE,
pcercuei 0:03b5121a232e 20685 item, redef->target,
pcercuei 0:03b5121a232e 20686 (WXS_ATTR_GROUP_CAST item)->attrUses,
pcercuei 0:03b5121a232e 20687 (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
pcercuei 0:03b5121a232e 20688 (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
pcercuei 0:03b5121a232e 20689 (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
pcercuei 0:03b5121a232e 20690 if (err == -1)
pcercuei 0:03b5121a232e 20691 return(-1);
pcercuei 0:03b5121a232e 20692 break;
pcercuei 0:03b5121a232e 20693 default:
pcercuei 0:03b5121a232e 20694 break;
pcercuei 0:03b5121a232e 20695 }
pcercuei 0:03b5121a232e 20696 redef = redef->next;
pcercuei 0:03b5121a232e 20697 } while (redef != NULL);
pcercuei 0:03b5121a232e 20698 return(0);
pcercuei 0:03b5121a232e 20699 }
pcercuei 0:03b5121a232e 20700
pcercuei 0:03b5121a232e 20701
pcercuei 0:03b5121a232e 20702 static int
pcercuei 0:03b5121a232e 20703 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 20704 xmlSchemaBucketPtr bucket)
pcercuei 0:03b5121a232e 20705 {
pcercuei 0:03b5121a232e 20706 xmlSchemaBasicItemPtr item;
pcercuei 0:03b5121a232e 20707 int err;
pcercuei 0:03b5121a232e 20708 xmlHashTablePtr *table;
pcercuei 0:03b5121a232e 20709 const xmlChar *name;
pcercuei 0:03b5121a232e 20710 int i;
pcercuei 0:03b5121a232e 20711
pcercuei 0:03b5121a232e 20712 #define WXS_GET_GLOBAL_HASH(c, slot) { \
pcercuei 0:03b5121a232e 20713 if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
pcercuei 0:03b5121a232e 20714 table = &(WXS_IMPBUCKET((c))->schema->slot); \
pcercuei 0:03b5121a232e 20715 else \
pcercuei 0:03b5121a232e 20716 table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
pcercuei 0:03b5121a232e 20717
pcercuei 0:03b5121a232e 20718 /*
pcercuei 0:03b5121a232e 20719 * Add global components to the schema's hash tables.
pcercuei 0:03b5121a232e 20720 * This is the place where duplicate components will be
pcercuei 0:03b5121a232e 20721 * detected.
pcercuei 0:03b5121a232e 20722 * TODO: I think normally we should support imports of the
pcercuei 0:03b5121a232e 20723 * same namespace from multiple locations. We don't do currently,
pcercuei 0:03b5121a232e 20724 * but if we do then according to:
pcercuei 0:03b5121a232e 20725 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
pcercuei 0:03b5121a232e 20726 * we would need, if imported directly, to import redefined
pcercuei 0:03b5121a232e 20727 * components as well to be able to catch clashing components.
pcercuei 0:03b5121a232e 20728 * (I hope I'll still know what this means after some months :-()
pcercuei 0:03b5121a232e 20729 */
pcercuei 0:03b5121a232e 20730 if (bucket == NULL)
pcercuei 0:03b5121a232e 20731 return(-1);
pcercuei 0:03b5121a232e 20732 if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
pcercuei 0:03b5121a232e 20733 return(0);
pcercuei 0:03b5121a232e 20734 bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
pcercuei 0:03b5121a232e 20735
pcercuei 0:03b5121a232e 20736 for (i = 0; i < bucket->globals->nbItems; i++) {
pcercuei 0:03b5121a232e 20737 item = bucket->globals->items[i];
pcercuei 0:03b5121a232e 20738 table = NULL;
pcercuei 0:03b5121a232e 20739 switch (item->type) {
pcercuei 0:03b5121a232e 20740 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 20741 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 20742 if (WXS_REDEFINED_TYPE(item))
pcercuei 0:03b5121a232e 20743 continue;
pcercuei 0:03b5121a232e 20744 name = (WXS_TYPE_CAST item)->name;
pcercuei 0:03b5121a232e 20745 WXS_GET_GLOBAL_HASH(bucket, typeDecl)
pcercuei 0:03b5121a232e 20746 break;
pcercuei 0:03b5121a232e 20747 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 20748 name = (WXS_ELEM_CAST item)->name;
pcercuei 0:03b5121a232e 20749 WXS_GET_GLOBAL_HASH(bucket, elemDecl)
pcercuei 0:03b5121a232e 20750 break;
pcercuei 0:03b5121a232e 20751 case XML_SCHEMA_TYPE_ATTRIBUTE:
pcercuei 0:03b5121a232e 20752 name = (WXS_ATTR_CAST item)->name;
pcercuei 0:03b5121a232e 20753 WXS_GET_GLOBAL_HASH(bucket, attrDecl)
pcercuei 0:03b5121a232e 20754 break;
pcercuei 0:03b5121a232e 20755 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 20756 if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
pcercuei 0:03b5121a232e 20757 continue;
pcercuei 0:03b5121a232e 20758 name = (WXS_MODEL_GROUPDEF_CAST item)->name;
pcercuei 0:03b5121a232e 20759 WXS_GET_GLOBAL_HASH(bucket, groupDecl)
pcercuei 0:03b5121a232e 20760 break;
pcercuei 0:03b5121a232e 20761 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 20762 if (WXS_REDEFINED_ATTR_GROUP(item))
pcercuei 0:03b5121a232e 20763 continue;
pcercuei 0:03b5121a232e 20764 name = (WXS_ATTR_GROUP_CAST item)->name;
pcercuei 0:03b5121a232e 20765 WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
pcercuei 0:03b5121a232e 20766 break;
pcercuei 0:03b5121a232e 20767 case XML_SCHEMA_TYPE_IDC_KEY:
pcercuei 0:03b5121a232e 20768 case XML_SCHEMA_TYPE_IDC_UNIQUE:
pcercuei 0:03b5121a232e 20769 case XML_SCHEMA_TYPE_IDC_KEYREF:
pcercuei 0:03b5121a232e 20770 name = (WXS_IDC_CAST item)->name;
pcercuei 0:03b5121a232e 20771 WXS_GET_GLOBAL_HASH(bucket, idcDef)
pcercuei 0:03b5121a232e 20772 break;
pcercuei 0:03b5121a232e 20773 case XML_SCHEMA_TYPE_NOTATION:
pcercuei 0:03b5121a232e 20774 name = ((xmlSchemaNotationPtr) item)->name;
pcercuei 0:03b5121a232e 20775 WXS_GET_GLOBAL_HASH(bucket, notaDecl)
pcercuei 0:03b5121a232e 20776 break;
pcercuei 0:03b5121a232e 20777 default:
pcercuei 0:03b5121a232e 20778 PERROR_INT("xmlSchemaAddComponents",
pcercuei 0:03b5121a232e 20779 "Unexpected global component type");
pcercuei 0:03b5121a232e 20780 continue;
pcercuei 0:03b5121a232e 20781 }
pcercuei 0:03b5121a232e 20782 if (*table == NULL) {
pcercuei 0:03b5121a232e 20783 *table = xmlHashCreateDict(10, pctxt->dict);
pcercuei 0:03b5121a232e 20784 if (*table == NULL) {
pcercuei 0:03b5121a232e 20785 PERROR_INT("xmlSchemaAddComponents",
pcercuei 0:03b5121a232e 20786 "failed to create a component hash table");
pcercuei 0:03b5121a232e 20787 return(-1);
pcercuei 0:03b5121a232e 20788 }
pcercuei 0:03b5121a232e 20789 }
pcercuei 0:03b5121a232e 20790 err = xmlHashAddEntry(*table, name, item);
pcercuei 0:03b5121a232e 20791 if (err != 0) {
pcercuei 0:03b5121a232e 20792 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 20793
pcercuei 0:03b5121a232e 20794 xmlSchemaCustomErr(ACTXT_CAST pctxt,
pcercuei 0:03b5121a232e 20795 XML_SCHEMAP_REDEFINED_TYPE,
pcercuei 0:03b5121a232e 20796 WXS_ITEM_NODE(item),
pcercuei 0:03b5121a232e 20797 WXS_BASIC_CAST item,
pcercuei 0:03b5121a232e 20798 "A global %s '%s' does already exist",
pcercuei 0:03b5121a232e 20799 WXS_ITEM_TYPE_NAME(item),
pcercuei 0:03b5121a232e 20800 xmlSchemaGetComponentQName(&str, item));
pcercuei 0:03b5121a232e 20801 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 20802 }
pcercuei 0:03b5121a232e 20803 }
pcercuei 0:03b5121a232e 20804 /*
pcercuei 0:03b5121a232e 20805 * Process imported/included schemas.
pcercuei 0:03b5121a232e 20806 */
pcercuei 0:03b5121a232e 20807 if (bucket->relations != NULL) {
pcercuei 0:03b5121a232e 20808 xmlSchemaSchemaRelationPtr rel = bucket->relations;
pcercuei 0:03b5121a232e 20809 do {
pcercuei 0:03b5121a232e 20810 if ((rel->bucket != NULL) &&
pcercuei 0:03b5121a232e 20811 ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
pcercuei 0:03b5121a232e 20812 if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
pcercuei 0:03b5121a232e 20813 return(-1);
pcercuei 0:03b5121a232e 20814 }
pcercuei 0:03b5121a232e 20815 rel = rel->next;
pcercuei 0:03b5121a232e 20816 } while (rel != NULL);
pcercuei 0:03b5121a232e 20817 }
pcercuei 0:03b5121a232e 20818 return(0);
pcercuei 0:03b5121a232e 20819 }
pcercuei 0:03b5121a232e 20820
pcercuei 0:03b5121a232e 20821 static int
pcercuei 0:03b5121a232e 20822 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
pcercuei 0:03b5121a232e 20823 xmlSchemaBucketPtr rootBucket)
pcercuei 0:03b5121a232e 20824 {
pcercuei 0:03b5121a232e 20825 xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
pcercuei 0:03b5121a232e 20826 xmlSchemaTreeItemPtr item, *items;
pcercuei 0:03b5121a232e 20827 int nbItems, i, ret = 0;
pcercuei 0:03b5121a232e 20828 xmlSchemaBucketPtr oldbucket = con->bucket;
pcercuei 0:03b5121a232e 20829 xmlSchemaElementPtr elemDecl;
pcercuei 0:03b5121a232e 20830
pcercuei 0:03b5121a232e 20831 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
pcercuei 0:03b5121a232e 20832
pcercuei 0:03b5121a232e 20833 if ((con->pending == NULL) ||
pcercuei 0:03b5121a232e 20834 (con->pending->nbItems == 0))
pcercuei 0:03b5121a232e 20835 return(0);
pcercuei 0:03b5121a232e 20836
pcercuei 0:03b5121a232e 20837 /*
pcercuei 0:03b5121a232e 20838 * Since xmlSchemaFixupComplexType() will create new particles
pcercuei 0:03b5121a232e 20839 * (local components), and those particle components need a bucket
pcercuei 0:03b5121a232e 20840 * on the constructor, we'll assure here that the constructor has
pcercuei 0:03b5121a232e 20841 * a bucket.
pcercuei 0:03b5121a232e 20842 * TODO: Think about storing locals _only_ on the main bucket.
pcercuei 0:03b5121a232e 20843 */
pcercuei 0:03b5121a232e 20844 if (con->bucket == NULL)
pcercuei 0:03b5121a232e 20845 con->bucket = rootBucket;
pcercuei 0:03b5121a232e 20846
pcercuei 0:03b5121a232e 20847 /* TODO:
pcercuei 0:03b5121a232e 20848 * SPEC (src-redefine):
pcercuei 0:03b5121a232e 20849 * (6.2) "If it has no such self-reference, then all of the
pcercuei 0:03b5121a232e 20850 * following must be true:"
pcercuei 0:03b5121a232e 20851
pcercuei 0:03b5121a232e 20852 * (6.2.2) The {model group} of the model group definition which
pcercuei 0:03b5121a232e 20853 * corresponds to it per XML Representation of Model Group
pcercuei 0:03b5121a232e 20854 * Definition Schema Components ($3.7.2) must be a `valid
pcercuei 0:03b5121a232e 20855 * restriction` of the {model group} of that model group definition
pcercuei 0:03b5121a232e 20856 * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
pcercuei 0:03b5121a232e 20857 */
pcercuei 0:03b5121a232e 20858 xmlSchemaCheckSRCRedefineFirst(pctxt);
pcercuei 0:03b5121a232e 20859
pcercuei 0:03b5121a232e 20860 /*
pcercuei 0:03b5121a232e 20861 * Add global components to the schemata's hash tables.
pcercuei 0:03b5121a232e 20862 */
pcercuei 0:03b5121a232e 20863 xmlSchemaAddComponents(pctxt, rootBucket);
pcercuei 0:03b5121a232e 20864
pcercuei 0:03b5121a232e 20865 pctxt->ctxtType = NULL;
pcercuei 0:03b5121a232e 20866 items = (xmlSchemaTreeItemPtr *) con->pending->items;
pcercuei 0:03b5121a232e 20867 nbItems = con->pending->nbItems;
pcercuei 0:03b5121a232e 20868 /*
pcercuei 0:03b5121a232e 20869 * Now that we have parsed *all* the schema document(s) and converted
pcercuei 0:03b5121a232e 20870 * them to schema components, we can resolve references, apply component
pcercuei 0:03b5121a232e 20871 * constraints, create the FSA from the content model, etc.
pcercuei 0:03b5121a232e 20872 */
pcercuei 0:03b5121a232e 20873 /*
pcercuei 0:03b5121a232e 20874 * Resolve references of..
pcercuei 0:03b5121a232e 20875 *
pcercuei 0:03b5121a232e 20876 * 1. element declarations:
pcercuei 0:03b5121a232e 20877 * - the type definition
pcercuei 0:03b5121a232e 20878 * - the substitution group affiliation
pcercuei 0:03b5121a232e 20879 * 2. simple/complex types:
pcercuei 0:03b5121a232e 20880 * - the base type definition
pcercuei 0:03b5121a232e 20881 * - the memberTypes of union types
pcercuei 0:03b5121a232e 20882 * - the itemType of list types
pcercuei 0:03b5121a232e 20883 * 3. attributes declarations and attribute uses:
pcercuei 0:03b5121a232e 20884 * - the type definition
pcercuei 0:03b5121a232e 20885 * - if an attribute use, then the attribute declaration
pcercuei 0:03b5121a232e 20886 * 4. attribute group references:
pcercuei 0:03b5121a232e 20887 * - the attribute group definition
pcercuei 0:03b5121a232e 20888 * 5. particles:
pcercuei 0:03b5121a232e 20889 * - the term of the particle (e.g. a model group)
pcercuei 0:03b5121a232e 20890 * 6. IDC key-references:
pcercuei 0:03b5121a232e 20891 * - the referenced IDC 'key' or 'unique' definition
pcercuei 0:03b5121a232e 20892 * 7. Attribute prohibitions which had a "ref" attribute.
pcercuei 0:03b5121a232e 20893 */
pcercuei 0:03b5121a232e 20894 for (i = 0; i < nbItems; i++) {
pcercuei 0:03b5121a232e 20895 item = items[i];
pcercuei 0:03b5121a232e 20896 switch (item->type) {
pcercuei 0:03b5121a232e 20897 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 20898 xmlSchemaResolveElementReferences(
pcercuei 0:03b5121a232e 20899 (xmlSchemaElementPtr) item, pctxt);
pcercuei 0:03b5121a232e 20900 FIXHFAILURE;
pcercuei 0:03b5121a232e 20901 break;
pcercuei 0:03b5121a232e 20902 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 20903 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 20904 xmlSchemaResolveTypeReferences(
pcercuei 0:03b5121a232e 20905 (xmlSchemaTypePtr) item, pctxt);
pcercuei 0:03b5121a232e 20906 FIXHFAILURE;
pcercuei 0:03b5121a232e 20907 break;
pcercuei 0:03b5121a232e 20908 case XML_SCHEMA_TYPE_ATTRIBUTE:
pcercuei 0:03b5121a232e 20909 xmlSchemaResolveAttrTypeReferences(
pcercuei 0:03b5121a232e 20910 (xmlSchemaAttributePtr) item, pctxt);
pcercuei 0:03b5121a232e 20911 FIXHFAILURE;
pcercuei 0:03b5121a232e 20912 break;
pcercuei 0:03b5121a232e 20913 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
pcercuei 0:03b5121a232e 20914 xmlSchemaResolveAttrUseReferences(
pcercuei 0:03b5121a232e 20915 (xmlSchemaAttributeUsePtr) item, pctxt);
pcercuei 0:03b5121a232e 20916 FIXHFAILURE;
pcercuei 0:03b5121a232e 20917 break;
pcercuei 0:03b5121a232e 20918 case XML_SCHEMA_EXTRA_QNAMEREF:
pcercuei 0:03b5121a232e 20919 if ((WXS_QNAME_CAST item)->itemType ==
pcercuei 0:03b5121a232e 20920 XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
pcercuei 0:03b5121a232e 20921 {
pcercuei 0:03b5121a232e 20922 xmlSchemaResolveAttrGroupReferences(
pcercuei 0:03b5121a232e 20923 WXS_QNAME_CAST item, pctxt);
pcercuei 0:03b5121a232e 20924 }
pcercuei 0:03b5121a232e 20925 FIXHFAILURE;
pcercuei 0:03b5121a232e 20926 break;
pcercuei 0:03b5121a232e 20927 case XML_SCHEMA_TYPE_SEQUENCE:
pcercuei 0:03b5121a232e 20928 case XML_SCHEMA_TYPE_CHOICE:
pcercuei 0:03b5121a232e 20929 case XML_SCHEMA_TYPE_ALL:
pcercuei 0:03b5121a232e 20930 xmlSchemaResolveModelGroupParticleReferences(pctxt,
pcercuei 0:03b5121a232e 20931 WXS_MODEL_GROUP_CAST item);
pcercuei 0:03b5121a232e 20932 FIXHFAILURE;
pcercuei 0:03b5121a232e 20933 break;
pcercuei 0:03b5121a232e 20934 case XML_SCHEMA_TYPE_IDC_KEY:
pcercuei 0:03b5121a232e 20935 case XML_SCHEMA_TYPE_IDC_UNIQUE:
pcercuei 0:03b5121a232e 20936 case XML_SCHEMA_TYPE_IDC_KEYREF:
pcercuei 0:03b5121a232e 20937 xmlSchemaResolveIDCKeyReferences(
pcercuei 0:03b5121a232e 20938 (xmlSchemaIDCPtr) item, pctxt);
pcercuei 0:03b5121a232e 20939 FIXHFAILURE;
pcercuei 0:03b5121a232e 20940 break;
pcercuei 0:03b5121a232e 20941 case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
pcercuei 0:03b5121a232e 20942 /*
pcercuei 0:03b5121a232e 20943 * Handle attribue prohibition which had a
pcercuei 0:03b5121a232e 20944 * "ref" attribute.
pcercuei 0:03b5121a232e 20945 */
pcercuei 0:03b5121a232e 20946 xmlSchemaResolveAttrUseProhibReferences(
pcercuei 0:03b5121a232e 20947 WXS_ATTR_PROHIB_CAST item, pctxt);
pcercuei 0:03b5121a232e 20948 FIXHFAILURE;
pcercuei 0:03b5121a232e 20949 break;
pcercuei 0:03b5121a232e 20950 default:
pcercuei 0:03b5121a232e 20951 break;
pcercuei 0:03b5121a232e 20952 }
pcercuei 0:03b5121a232e 20953 }
pcercuei 0:03b5121a232e 20954 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 20955 goto exit_error;
pcercuei 0:03b5121a232e 20956
pcercuei 0:03b5121a232e 20957 /*
pcercuei 0:03b5121a232e 20958 * Now that all references are resolved we
pcercuei 0:03b5121a232e 20959 * can check for circularity of...
pcercuei 0:03b5121a232e 20960 * 1. the base axis of type definitions
pcercuei 0:03b5121a232e 20961 * 2. nested model group definitions
pcercuei 0:03b5121a232e 20962 * 3. nested attribute group definitions
pcercuei 0:03b5121a232e 20963 * TODO: check for circual substitution groups.
pcercuei 0:03b5121a232e 20964 */
pcercuei 0:03b5121a232e 20965 for (i = 0; i < nbItems; i++) {
pcercuei 0:03b5121a232e 20966 item = items[i];
pcercuei 0:03b5121a232e 20967 /*
pcercuei 0:03b5121a232e 20968 * Let's better stop on the first error here.
pcercuei 0:03b5121a232e 20969 */
pcercuei 0:03b5121a232e 20970 switch (item->type) {
pcercuei 0:03b5121a232e 20971 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 20972 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 20973 xmlSchemaCheckTypeDefCircular(
pcercuei 0:03b5121a232e 20974 (xmlSchemaTypePtr) item, pctxt);
pcercuei 0:03b5121a232e 20975 FIXHFAILURE;
pcercuei 0:03b5121a232e 20976 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 20977 goto exit_error;
pcercuei 0:03b5121a232e 20978 break;
pcercuei 0:03b5121a232e 20979 case XML_SCHEMA_TYPE_GROUP:
pcercuei 0:03b5121a232e 20980 xmlSchemaCheckGroupDefCircular(
pcercuei 0:03b5121a232e 20981 (xmlSchemaModelGroupDefPtr) item, pctxt);
pcercuei 0:03b5121a232e 20982 FIXHFAILURE;
pcercuei 0:03b5121a232e 20983 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 20984 goto exit_error;
pcercuei 0:03b5121a232e 20985 break;
pcercuei 0:03b5121a232e 20986 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 20987 xmlSchemaCheckAttrGroupCircular(
pcercuei 0:03b5121a232e 20988 (xmlSchemaAttributeGroupPtr) item, pctxt);
pcercuei 0:03b5121a232e 20989 FIXHFAILURE;
pcercuei 0:03b5121a232e 20990 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 20991 goto exit_error;
pcercuei 0:03b5121a232e 20992 break;
pcercuei 0:03b5121a232e 20993 default:
pcercuei 0:03b5121a232e 20994 break;
pcercuei 0:03b5121a232e 20995 }
pcercuei 0:03b5121a232e 20996 }
pcercuei 0:03b5121a232e 20997 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 20998 goto exit_error;
pcercuei 0:03b5121a232e 20999 /*
pcercuei 0:03b5121a232e 21000 * Model group definition references:
pcercuei 0:03b5121a232e 21001 * Such a reference is reflected by a particle at the component
pcercuei 0:03b5121a232e 21002 * level. Until now the 'term' of such particles pointed
pcercuei 0:03b5121a232e 21003 * to the model group definition; this was done, in order to
pcercuei 0:03b5121a232e 21004 * ease circularity checks. Now we need to set the 'term' of
pcercuei 0:03b5121a232e 21005 * such particles to the model group of the model group definition.
pcercuei 0:03b5121a232e 21006 */
pcercuei 0:03b5121a232e 21007 for (i = 0; i < nbItems; i++) {
pcercuei 0:03b5121a232e 21008 item = items[i];
pcercuei 0:03b5121a232e 21009 switch (item->type) {
pcercuei 0:03b5121a232e 21010 case XML_SCHEMA_TYPE_SEQUENCE:
pcercuei 0:03b5121a232e 21011 case XML_SCHEMA_TYPE_CHOICE:
pcercuei 0:03b5121a232e 21012 xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
pcercuei 0:03b5121a232e 21013 WXS_MODEL_GROUP_CAST item);
pcercuei 0:03b5121a232e 21014 break;
pcercuei 0:03b5121a232e 21015 default:
pcercuei 0:03b5121a232e 21016 break;
pcercuei 0:03b5121a232e 21017 }
pcercuei 0:03b5121a232e 21018 }
pcercuei 0:03b5121a232e 21019 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 21020 goto exit_error;
pcercuei 0:03b5121a232e 21021 /*
pcercuei 0:03b5121a232e 21022 * Expand attribute group references of attribute group definitions.
pcercuei 0:03b5121a232e 21023 */
pcercuei 0:03b5121a232e 21024 for (i = 0; i < nbItems; i++) {
pcercuei 0:03b5121a232e 21025 item = items[i];
pcercuei 0:03b5121a232e 21026 switch (item->type) {
pcercuei 0:03b5121a232e 21027 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 21028 if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
pcercuei 0:03b5121a232e 21029 WXS_ATTR_GROUP_HAS_REFS(item))
pcercuei 0:03b5121a232e 21030 {
pcercuei 0:03b5121a232e 21031 xmlSchemaAttributeGroupExpandRefs(pctxt,
pcercuei 0:03b5121a232e 21032 WXS_ATTR_GROUP_CAST item);
pcercuei 0:03b5121a232e 21033 FIXHFAILURE;
pcercuei 0:03b5121a232e 21034 }
pcercuei 0:03b5121a232e 21035 break;
pcercuei 0:03b5121a232e 21036 default:
pcercuei 0:03b5121a232e 21037 break;
pcercuei 0:03b5121a232e 21038 }
pcercuei 0:03b5121a232e 21039 }
pcercuei 0:03b5121a232e 21040 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 21041 goto exit_error;
pcercuei 0:03b5121a232e 21042 /*
pcercuei 0:03b5121a232e 21043 * First compute the variety of simple types. This is needed as
pcercuei 0:03b5121a232e 21044 * a seperate step, since otherwise we won't be able to detect
pcercuei 0:03b5121a232e 21045 * circular union types in all cases.
pcercuei 0:03b5121a232e 21046 */
pcercuei 0:03b5121a232e 21047 for (i = 0; i < nbItems; i++) {
pcercuei 0:03b5121a232e 21048 item = items[i];
pcercuei 0:03b5121a232e 21049 switch (item->type) {
pcercuei 0:03b5121a232e 21050 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 21051 if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
pcercuei 0:03b5121a232e 21052 xmlSchemaFixupSimpleTypeStageOne(pctxt,
pcercuei 0:03b5121a232e 21053 (xmlSchemaTypePtr) item);
pcercuei 0:03b5121a232e 21054 FIXHFAILURE;
pcercuei 0:03b5121a232e 21055 }
pcercuei 0:03b5121a232e 21056 break;
pcercuei 0:03b5121a232e 21057 default:
pcercuei 0:03b5121a232e 21058 break;
pcercuei 0:03b5121a232e 21059 }
pcercuei 0:03b5121a232e 21060 }
pcercuei 0:03b5121a232e 21061 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 21062 goto exit_error;
pcercuei 0:03b5121a232e 21063 /*
pcercuei 0:03b5121a232e 21064 * Detect circular union types. Note that this needs the variety to
pcercuei 0:03b5121a232e 21065 * be already computed.
pcercuei 0:03b5121a232e 21066 */
pcercuei 0:03b5121a232e 21067 for (i = 0; i < nbItems; i++) {
pcercuei 0:03b5121a232e 21068 item = items[i];
pcercuei 0:03b5121a232e 21069 switch (item->type) {
pcercuei 0:03b5121a232e 21070 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 21071 if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
pcercuei 0:03b5121a232e 21072 xmlSchemaCheckUnionTypeDefCircular(pctxt,
pcercuei 0:03b5121a232e 21073 (xmlSchemaTypePtr) item);
pcercuei 0:03b5121a232e 21074 FIXHFAILURE;
pcercuei 0:03b5121a232e 21075 }
pcercuei 0:03b5121a232e 21076 break;
pcercuei 0:03b5121a232e 21077 default:
pcercuei 0:03b5121a232e 21078 break;
pcercuei 0:03b5121a232e 21079 }
pcercuei 0:03b5121a232e 21080 }
pcercuei 0:03b5121a232e 21081 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 21082 goto exit_error;
pcercuei 0:03b5121a232e 21083
pcercuei 0:03b5121a232e 21084 /*
pcercuei 0:03b5121a232e 21085 * Do the complete type fixup for simple types.
pcercuei 0:03b5121a232e 21086 */
pcercuei 0:03b5121a232e 21087 for (i = 0; i < nbItems; i++) {
pcercuei 0:03b5121a232e 21088 item = items[i];
pcercuei 0:03b5121a232e 21089 switch (item->type) {
pcercuei 0:03b5121a232e 21090 case XML_SCHEMA_TYPE_SIMPLE:
pcercuei 0:03b5121a232e 21091 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
pcercuei 0:03b5121a232e 21092 xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
pcercuei 0:03b5121a232e 21093 FIXHFAILURE;
pcercuei 0:03b5121a232e 21094 }
pcercuei 0:03b5121a232e 21095 break;
pcercuei 0:03b5121a232e 21096 default:
pcercuei 0:03b5121a232e 21097 break;
pcercuei 0:03b5121a232e 21098 }
pcercuei 0:03b5121a232e 21099 }
pcercuei 0:03b5121a232e 21100 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 21101 goto exit_error;
pcercuei 0:03b5121a232e 21102 /*
pcercuei 0:03b5121a232e 21103 * At this point we need build and check all simple types.
pcercuei 0:03b5121a232e 21104 */
pcercuei 0:03b5121a232e 21105 /*
pcercuei 0:03b5121a232e 21106 * Apply contraints for attribute declarations.
pcercuei 0:03b5121a232e 21107 */
pcercuei 0:03b5121a232e 21108 for (i = 0; i < nbItems; i++) {
pcercuei 0:03b5121a232e 21109 item = items[i];
pcercuei 0:03b5121a232e 21110 switch (item->type) {
pcercuei 0:03b5121a232e 21111 case XML_SCHEMA_TYPE_ATTRIBUTE:
pcercuei 0:03b5121a232e 21112 xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
pcercuei 0:03b5121a232e 21113 FIXHFAILURE;
pcercuei 0:03b5121a232e 21114 break;
pcercuei 0:03b5121a232e 21115 default:
pcercuei 0:03b5121a232e 21116 break;
pcercuei 0:03b5121a232e 21117 }
pcercuei 0:03b5121a232e 21118 }
pcercuei 0:03b5121a232e 21119 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 21120 goto exit_error;
pcercuei 0:03b5121a232e 21121 /*
pcercuei 0:03b5121a232e 21122 * Apply constraints for attribute uses.
pcercuei 0:03b5121a232e 21123 */
pcercuei 0:03b5121a232e 21124 for (i = 0; i < nbItems; i++) {
pcercuei 0:03b5121a232e 21125 item = items[i];
pcercuei 0:03b5121a232e 21126 switch (item->type) {
pcercuei 0:03b5121a232e 21127 case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
pcercuei 0:03b5121a232e 21128 if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
pcercuei 0:03b5121a232e 21129 xmlSchemaCheckAttrUsePropsCorrect(pctxt,
pcercuei 0:03b5121a232e 21130 WXS_ATTR_USE_CAST item);
pcercuei 0:03b5121a232e 21131 FIXHFAILURE;
pcercuei 0:03b5121a232e 21132 }
pcercuei 0:03b5121a232e 21133 break;
pcercuei 0:03b5121a232e 21134 default:
pcercuei 0:03b5121a232e 21135 break;
pcercuei 0:03b5121a232e 21136 }
pcercuei 0:03b5121a232e 21137 }
pcercuei 0:03b5121a232e 21138 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 21139 goto exit_error;
pcercuei 0:03b5121a232e 21140
pcercuei 0:03b5121a232e 21141 /*
pcercuei 0:03b5121a232e 21142 * Apply constraints for attribute group definitions.
pcercuei 0:03b5121a232e 21143 */
pcercuei 0:03b5121a232e 21144 for (i = 0; i < nbItems; i++) {
pcercuei 0:03b5121a232e 21145 item = items[i];
pcercuei 0:03b5121a232e 21146 switch (item->type) {
pcercuei 0:03b5121a232e 21147 case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
pcercuei 0:03b5121a232e 21148 if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
pcercuei 0:03b5121a232e 21149 ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
pcercuei 0:03b5121a232e 21150 {
pcercuei 0:03b5121a232e 21151 xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
pcercuei 0:03b5121a232e 21152 FIXHFAILURE;
pcercuei 0:03b5121a232e 21153 }
pcercuei 0:03b5121a232e 21154 break;
pcercuei 0:03b5121a232e 21155 default:
pcercuei 0:03b5121a232e 21156 break;
pcercuei 0:03b5121a232e 21157 }
pcercuei 0:03b5121a232e 21158 }
pcercuei 0:03b5121a232e 21159 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 21160 goto exit_error;
pcercuei 0:03b5121a232e 21161
pcercuei 0:03b5121a232e 21162 /*
pcercuei 0:03b5121a232e 21163 * Apply constraints for redefinitions.
pcercuei 0:03b5121a232e 21164 */
pcercuei 0:03b5121a232e 21165 if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
pcercuei 0:03b5121a232e 21166 xmlSchemaCheckSRCRedefineSecond(pctxt);
pcercuei 0:03b5121a232e 21167 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 21168 goto exit_error;
pcercuei 0:03b5121a232e 21169
pcercuei 0:03b5121a232e 21170 /*
pcercuei 0:03b5121a232e 21171 * Complex types are builded and checked.
pcercuei 0:03b5121a232e 21172 */
pcercuei 0:03b5121a232e 21173 for (i = 0; i < nbItems; i++) {
pcercuei 0:03b5121a232e 21174 item = con->pending->items[i];
pcercuei 0:03b5121a232e 21175 switch (item->type) {
pcercuei 0:03b5121a232e 21176 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 21177 if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
pcercuei 0:03b5121a232e 21178 xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
pcercuei 0:03b5121a232e 21179 FIXHFAILURE;
pcercuei 0:03b5121a232e 21180 }
pcercuei 0:03b5121a232e 21181 break;
pcercuei 0:03b5121a232e 21182 default:
pcercuei 0:03b5121a232e 21183 break;
pcercuei 0:03b5121a232e 21184 }
pcercuei 0:03b5121a232e 21185 }
pcercuei 0:03b5121a232e 21186 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 21187 goto exit_error;
pcercuei 0:03b5121a232e 21188
pcercuei 0:03b5121a232e 21189 /*
pcercuei 0:03b5121a232e 21190 * The list could have changed, since xmlSchemaFixupComplexType()
pcercuei 0:03b5121a232e 21191 * will create particles and model groups in some cases.
pcercuei 0:03b5121a232e 21192 */
pcercuei 0:03b5121a232e 21193 items = (xmlSchemaTreeItemPtr *) con->pending->items;
pcercuei 0:03b5121a232e 21194 nbItems = con->pending->nbItems;
pcercuei 0:03b5121a232e 21195
pcercuei 0:03b5121a232e 21196 /*
pcercuei 0:03b5121a232e 21197 * Apply some constraints for element declarations.
pcercuei 0:03b5121a232e 21198 */
pcercuei 0:03b5121a232e 21199 for (i = 0; i < nbItems; i++) {
pcercuei 0:03b5121a232e 21200 item = items[i];
pcercuei 0:03b5121a232e 21201 switch (item->type) {
pcercuei 0:03b5121a232e 21202 case XML_SCHEMA_TYPE_ELEMENT:
pcercuei 0:03b5121a232e 21203 elemDecl = (xmlSchemaElementPtr) item;
pcercuei 0:03b5121a232e 21204
pcercuei 0:03b5121a232e 21205 if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
pcercuei 0:03b5121a232e 21206 {
pcercuei 0:03b5121a232e 21207 xmlSchemaCheckElementDeclComponent(
pcercuei 0:03b5121a232e 21208 (xmlSchemaElementPtr) elemDecl, pctxt);
pcercuei 0:03b5121a232e 21209 FIXHFAILURE;
pcercuei 0:03b5121a232e 21210 }
pcercuei 0:03b5121a232e 21211
pcercuei 0:03b5121a232e 21212 #ifdef WXS_ELEM_DECL_CONS_ENABLED
pcercuei 0:03b5121a232e 21213 /*
pcercuei 0:03b5121a232e 21214 * Schema Component Constraint: Element Declarations Consistent
pcercuei 0:03b5121a232e 21215 * Apply this constraint to local types of element declarations.
pcercuei 0:03b5121a232e 21216 */
pcercuei 0:03b5121a232e 21217 if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
pcercuei 0:03b5121a232e 21218 (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
pcercuei 0:03b5121a232e 21219 (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
pcercuei 0:03b5121a232e 21220 {
pcercuei 0:03b5121a232e 21221 xmlSchemaCheckElementDeclConsistent(pctxt,
pcercuei 0:03b5121a232e 21222 WXS_BASIC_CAST elemDecl,
pcercuei 0:03b5121a232e 21223 WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
pcercuei 0:03b5121a232e 21224 NULL, NULL, 0);
pcercuei 0:03b5121a232e 21225 }
pcercuei 0:03b5121a232e 21226 #endif
pcercuei 0:03b5121a232e 21227 break;
pcercuei 0:03b5121a232e 21228 default:
pcercuei 0:03b5121a232e 21229 break;
pcercuei 0:03b5121a232e 21230 }
pcercuei 0:03b5121a232e 21231 }
pcercuei 0:03b5121a232e 21232 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 21233 goto exit_error;
pcercuei 0:03b5121a232e 21234
pcercuei 0:03b5121a232e 21235 /*
pcercuei 0:03b5121a232e 21236 * Finally we can build the automaton from the content model of
pcercuei 0:03b5121a232e 21237 * complex types.
pcercuei 0:03b5121a232e 21238 */
pcercuei 0:03b5121a232e 21239
pcercuei 0:03b5121a232e 21240 for (i = 0; i < nbItems; i++) {
pcercuei 0:03b5121a232e 21241 item = items[i];
pcercuei 0:03b5121a232e 21242 switch (item->type) {
pcercuei 0:03b5121a232e 21243 case XML_SCHEMA_TYPE_COMPLEX:
pcercuei 0:03b5121a232e 21244 xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
pcercuei 0:03b5121a232e 21245 /* FIXHFAILURE; */
pcercuei 0:03b5121a232e 21246 break;
pcercuei 0:03b5121a232e 21247 default:
pcercuei 0:03b5121a232e 21248 break;
pcercuei 0:03b5121a232e 21249 }
pcercuei 0:03b5121a232e 21250 }
pcercuei 0:03b5121a232e 21251 if (pctxt->nberrors != 0)
pcercuei 0:03b5121a232e 21252 goto exit_error;
pcercuei 0:03b5121a232e 21253 /*
pcercuei 0:03b5121a232e 21254 * URGENT TODO: cos-element-consistent
pcercuei 0:03b5121a232e 21255 */
pcercuei 0:03b5121a232e 21256 goto exit;
pcercuei 0:03b5121a232e 21257
pcercuei 0:03b5121a232e 21258 exit_error:
pcercuei 0:03b5121a232e 21259 ret = pctxt->err;
pcercuei 0:03b5121a232e 21260 goto exit;
pcercuei 0:03b5121a232e 21261
pcercuei 0:03b5121a232e 21262 exit_failure:
pcercuei 0:03b5121a232e 21263 ret = -1;
pcercuei 0:03b5121a232e 21264
pcercuei 0:03b5121a232e 21265 exit:
pcercuei 0:03b5121a232e 21266 /*
pcercuei 0:03b5121a232e 21267 * Reset the constructor. This is needed for XSI acquisition, since
pcercuei 0:03b5121a232e 21268 * those items will be processed over and over again for every XSI
pcercuei 0:03b5121a232e 21269 * if not cleared here.
pcercuei 0:03b5121a232e 21270 */
pcercuei 0:03b5121a232e 21271 con->bucket = oldbucket;
pcercuei 0:03b5121a232e 21272 con->pending->nbItems = 0;
pcercuei 0:03b5121a232e 21273 if (con->substGroups != NULL) {
pcercuei 0:03b5121a232e 21274 xmlHashFree(con->substGroups,
pcercuei 0:03b5121a232e 21275 (xmlHashDeallocator) xmlSchemaSubstGroupFree);
pcercuei 0:03b5121a232e 21276 con->substGroups = NULL;
pcercuei 0:03b5121a232e 21277 }
pcercuei 0:03b5121a232e 21278 if (con->redefs != NULL) {
pcercuei 0:03b5121a232e 21279 xmlSchemaRedefListFree(con->redefs);
pcercuei 0:03b5121a232e 21280 con->redefs = NULL;
pcercuei 0:03b5121a232e 21281 }
pcercuei 0:03b5121a232e 21282 return(ret);
pcercuei 0:03b5121a232e 21283 }
pcercuei 0:03b5121a232e 21284 /**
pcercuei 0:03b5121a232e 21285 * xmlSchemaParse:
pcercuei 0:03b5121a232e 21286 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 21287 *
pcercuei 0:03b5121a232e 21288 * parse a schema definition resource and build an internal
pcercuei 0:03b5121a232e 21289 * XML Shema struture which can be used to validate instances.
pcercuei 0:03b5121a232e 21290 *
pcercuei 0:03b5121a232e 21291 * Returns the internal XML Schema structure built from the resource or
pcercuei 0:03b5121a232e 21292 * NULL in case of error
pcercuei 0:03b5121a232e 21293 */
pcercuei 0:03b5121a232e 21294 xmlSchemaPtr
pcercuei 0:03b5121a232e 21295 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
pcercuei 0:03b5121a232e 21296 {
pcercuei 0:03b5121a232e 21297 xmlSchemaPtr mainSchema = NULL;
pcercuei 0:03b5121a232e 21298 xmlSchemaBucketPtr bucket = NULL;
pcercuei 0:03b5121a232e 21299 int res;
pcercuei 0:03b5121a232e 21300
pcercuei 0:03b5121a232e 21301 /*
pcercuei 0:03b5121a232e 21302 * This one is used if the schema to be parsed was specified via
pcercuei 0:03b5121a232e 21303 * the API; i.e. not automatically by the validated instance document.
pcercuei 0:03b5121a232e 21304 */
pcercuei 0:03b5121a232e 21305
pcercuei 0:03b5121a232e 21306 xmlSchemaInitTypes();
pcercuei 0:03b5121a232e 21307
pcercuei 0:03b5121a232e 21308 if (ctxt == NULL)
pcercuei 0:03b5121a232e 21309 return (NULL);
pcercuei 0:03b5121a232e 21310
pcercuei 0:03b5121a232e 21311 /* TODO: Init the context. Is this all we need?*/
pcercuei 0:03b5121a232e 21312 ctxt->nberrors = 0;
pcercuei 0:03b5121a232e 21313 ctxt->err = 0;
pcercuei 0:03b5121a232e 21314 ctxt->counter = 0;
pcercuei 0:03b5121a232e 21315
pcercuei 0:03b5121a232e 21316 /* Create the *main* schema. */
pcercuei 0:03b5121a232e 21317 mainSchema = xmlSchemaNewSchema(ctxt);
pcercuei 0:03b5121a232e 21318 if (mainSchema == NULL)
pcercuei 0:03b5121a232e 21319 goto exit_failure;
pcercuei 0:03b5121a232e 21320 /*
pcercuei 0:03b5121a232e 21321 * Create the schema constructor.
pcercuei 0:03b5121a232e 21322 */
pcercuei 0:03b5121a232e 21323 if (ctxt->constructor == NULL) {
pcercuei 0:03b5121a232e 21324 ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
pcercuei 0:03b5121a232e 21325 if (ctxt->constructor == NULL)
pcercuei 0:03b5121a232e 21326 return(NULL);
pcercuei 0:03b5121a232e 21327 /* Take ownership of the constructor to be able to free it. */
pcercuei 0:03b5121a232e 21328 ctxt->ownsConstructor = 1;
pcercuei 0:03b5121a232e 21329 }
pcercuei 0:03b5121a232e 21330 ctxt->constructor->mainSchema = mainSchema;
pcercuei 0:03b5121a232e 21331 /*
pcercuei 0:03b5121a232e 21332 * Locate and add the schema document.
pcercuei 0:03b5121a232e 21333 */
pcercuei 0:03b5121a232e 21334 res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
pcercuei 0:03b5121a232e 21335 ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
pcercuei 0:03b5121a232e 21336 NULL, NULL, &bucket);
pcercuei 0:03b5121a232e 21337 if (res == -1)
pcercuei 0:03b5121a232e 21338 goto exit_failure;
pcercuei 0:03b5121a232e 21339 if (res != 0)
pcercuei 0:03b5121a232e 21340 goto exit;
pcercuei 0:03b5121a232e 21341
pcercuei 0:03b5121a232e 21342 if (bucket == NULL) {
pcercuei 0:03b5121a232e 21343 /* TODO: Error code, actually we failed to *locate* the schema. */
pcercuei 0:03b5121a232e 21344 if (ctxt->URL)
pcercuei 0:03b5121a232e 21345 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
pcercuei 0:03b5121a232e 21346 NULL, NULL,
pcercuei 0:03b5121a232e 21347 "Failed to locate the main schema resource at '%s'",
pcercuei 0:03b5121a232e 21348 ctxt->URL, NULL);
pcercuei 0:03b5121a232e 21349 else
pcercuei 0:03b5121a232e 21350 xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
pcercuei 0:03b5121a232e 21351 NULL, NULL,
pcercuei 0:03b5121a232e 21352 "Failed to locate the main schema resource",
pcercuei 0:03b5121a232e 21353 NULL, NULL);
pcercuei 0:03b5121a232e 21354 goto exit;
pcercuei 0:03b5121a232e 21355 }
pcercuei 0:03b5121a232e 21356 /* Then do the parsing for good. */
pcercuei 0:03b5121a232e 21357 if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
pcercuei 0:03b5121a232e 21358 goto exit_failure;
pcercuei 0:03b5121a232e 21359 if (ctxt->nberrors != 0)
pcercuei 0:03b5121a232e 21360 goto exit;
pcercuei 0:03b5121a232e 21361
pcercuei 0:03b5121a232e 21362 mainSchema->doc = bucket->doc;
pcercuei 0:03b5121a232e 21363 mainSchema->preserve = ctxt->preserve;
pcercuei 0:03b5121a232e 21364
pcercuei 0:03b5121a232e 21365 ctxt->schema = mainSchema;
pcercuei 0:03b5121a232e 21366
pcercuei 0:03b5121a232e 21367 if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
pcercuei 0:03b5121a232e 21368 goto exit_failure;
pcercuei 0:03b5121a232e 21369
pcercuei 0:03b5121a232e 21370 /*
pcercuei 0:03b5121a232e 21371 * TODO: This is not nice, since we cannot distinguish from the
pcercuei 0:03b5121a232e 21372 * result if there was an internal error or not.
pcercuei 0:03b5121a232e 21373 */
pcercuei 0:03b5121a232e 21374 exit:
pcercuei 0:03b5121a232e 21375 if (ctxt->nberrors != 0) {
pcercuei 0:03b5121a232e 21376 if (mainSchema) {
pcercuei 0:03b5121a232e 21377 xmlSchemaFree(mainSchema);
pcercuei 0:03b5121a232e 21378 mainSchema = NULL;
pcercuei 0:03b5121a232e 21379 }
pcercuei 0:03b5121a232e 21380 if (ctxt->constructor) {
pcercuei 0:03b5121a232e 21381 xmlSchemaConstructionCtxtFree(ctxt->constructor);
pcercuei 0:03b5121a232e 21382 ctxt->constructor = NULL;
pcercuei 0:03b5121a232e 21383 ctxt->ownsConstructor = 0;
pcercuei 0:03b5121a232e 21384 }
pcercuei 0:03b5121a232e 21385 }
pcercuei 0:03b5121a232e 21386 ctxt->schema = NULL;
pcercuei 0:03b5121a232e 21387 return(mainSchema);
pcercuei 0:03b5121a232e 21388 exit_failure:
pcercuei 0:03b5121a232e 21389 /*
pcercuei 0:03b5121a232e 21390 * Quite verbose, but should catch internal errors, which were
pcercuei 0:03b5121a232e 21391 * not communitated.
pcercuei 0:03b5121a232e 21392 */
pcercuei 0:03b5121a232e 21393 if (mainSchema) {
pcercuei 0:03b5121a232e 21394 xmlSchemaFree(mainSchema);
pcercuei 0:03b5121a232e 21395 mainSchema = NULL;
pcercuei 0:03b5121a232e 21396 }
pcercuei 0:03b5121a232e 21397 if (ctxt->constructor) {
pcercuei 0:03b5121a232e 21398 xmlSchemaConstructionCtxtFree(ctxt->constructor);
pcercuei 0:03b5121a232e 21399 ctxt->constructor = NULL;
pcercuei 0:03b5121a232e 21400 ctxt->ownsConstructor = 0;
pcercuei 0:03b5121a232e 21401 }
pcercuei 0:03b5121a232e 21402 PERROR_INT2("xmlSchemaParse",
pcercuei 0:03b5121a232e 21403 "An internal error occured");
pcercuei 0:03b5121a232e 21404 ctxt->schema = NULL;
pcercuei 0:03b5121a232e 21405 return(NULL);
pcercuei 0:03b5121a232e 21406 }
pcercuei 0:03b5121a232e 21407
pcercuei 0:03b5121a232e 21408 /**
pcercuei 0:03b5121a232e 21409 * xmlSchemaSetParserErrors:
pcercuei 0:03b5121a232e 21410 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 21411 * @err: the error callback
pcercuei 0:03b5121a232e 21412 * @warn: the warning callback
pcercuei 0:03b5121a232e 21413 * @ctx: contextual data for the callbacks
pcercuei 0:03b5121a232e 21414 *
pcercuei 0:03b5121a232e 21415 * Set the callback functions used to handle errors for a validation context
pcercuei 0:03b5121a232e 21416 */
pcercuei 0:03b5121a232e 21417 void
pcercuei 0:03b5121a232e 21418 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 21419 xmlSchemaValidityErrorFunc err,
pcercuei 0:03b5121a232e 21420 xmlSchemaValidityWarningFunc warn, void *ctx)
pcercuei 0:03b5121a232e 21421 {
pcercuei 0:03b5121a232e 21422 if (ctxt == NULL)
pcercuei 0:03b5121a232e 21423 return;
pcercuei 0:03b5121a232e 21424 ctxt->error = err;
pcercuei 0:03b5121a232e 21425 ctxt->warning = warn;
pcercuei 0:03b5121a232e 21426 ctxt->errCtxt = ctx;
pcercuei 0:03b5121a232e 21427 if (ctxt->vctxt != NULL)
pcercuei 0:03b5121a232e 21428 xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
pcercuei 0:03b5121a232e 21429 }
pcercuei 0:03b5121a232e 21430
pcercuei 0:03b5121a232e 21431 /**
pcercuei 0:03b5121a232e 21432 * xmlSchemaSetParserStructuredErrors:
pcercuei 0:03b5121a232e 21433 * @ctxt: a schema parser context
pcercuei 0:03b5121a232e 21434 * @serror: the structured error function
pcercuei 0:03b5121a232e 21435 * @ctx: the functions context
pcercuei 0:03b5121a232e 21436 *
pcercuei 0:03b5121a232e 21437 * Set the structured error callback
pcercuei 0:03b5121a232e 21438 */
pcercuei 0:03b5121a232e 21439 void
pcercuei 0:03b5121a232e 21440 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 21441 xmlStructuredErrorFunc serror,
pcercuei 0:03b5121a232e 21442 void *ctx)
pcercuei 0:03b5121a232e 21443 {
pcercuei 0:03b5121a232e 21444 if (ctxt == NULL)
pcercuei 0:03b5121a232e 21445 return;
pcercuei 0:03b5121a232e 21446 ctxt->serror = serror;
pcercuei 0:03b5121a232e 21447 ctxt->errCtxt = ctx;
pcercuei 0:03b5121a232e 21448 if (ctxt->vctxt != NULL)
pcercuei 0:03b5121a232e 21449 xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
pcercuei 0:03b5121a232e 21450 }
pcercuei 0:03b5121a232e 21451
pcercuei 0:03b5121a232e 21452 /**
pcercuei 0:03b5121a232e 21453 * xmlSchemaGetParserErrors:
pcercuei 0:03b5121a232e 21454 * @ctxt: a XMl-Schema parser context
pcercuei 0:03b5121a232e 21455 * @err: the error callback result
pcercuei 0:03b5121a232e 21456 * @warn: the warning callback result
pcercuei 0:03b5121a232e 21457 * @ctx: contextual data for the callbacks result
pcercuei 0:03b5121a232e 21458 *
pcercuei 0:03b5121a232e 21459 * Get the callback information used to handle errors for a parser context
pcercuei 0:03b5121a232e 21460 *
pcercuei 0:03b5121a232e 21461 * Returns -1 in case of failure, 0 otherwise
pcercuei 0:03b5121a232e 21462 */
pcercuei 0:03b5121a232e 21463 int
pcercuei 0:03b5121a232e 21464 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
pcercuei 0:03b5121a232e 21465 xmlSchemaValidityErrorFunc * err,
pcercuei 0:03b5121a232e 21466 xmlSchemaValidityWarningFunc * warn, void **ctx)
pcercuei 0:03b5121a232e 21467 {
pcercuei 0:03b5121a232e 21468 if (ctxt == NULL)
pcercuei 0:03b5121a232e 21469 return(-1);
pcercuei 0:03b5121a232e 21470 if (err != NULL)
pcercuei 0:03b5121a232e 21471 *err = ctxt->error;
pcercuei 0:03b5121a232e 21472 if (warn != NULL)
pcercuei 0:03b5121a232e 21473 *warn = ctxt->warning;
pcercuei 0:03b5121a232e 21474 if (ctx != NULL)
pcercuei 0:03b5121a232e 21475 *ctx = ctxt->errCtxt;
pcercuei 0:03b5121a232e 21476 return(0);
pcercuei 0:03b5121a232e 21477 }
pcercuei 0:03b5121a232e 21478
pcercuei 0:03b5121a232e 21479 /**
pcercuei 0:03b5121a232e 21480 * xmlSchemaFacetTypeToString:
pcercuei 0:03b5121a232e 21481 * @type: the facet type
pcercuei 0:03b5121a232e 21482 *
pcercuei 0:03b5121a232e 21483 * Convert the xmlSchemaTypeType to a char string.
pcercuei 0:03b5121a232e 21484 *
pcercuei 0:03b5121a232e 21485 * Returns the char string representation of the facet type if the
pcercuei 0:03b5121a232e 21486 * type is a facet and an "Internal Error" string otherwise.
pcercuei 0:03b5121a232e 21487 */
pcercuei 0:03b5121a232e 21488 static const xmlChar *
pcercuei 0:03b5121a232e 21489 xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
pcercuei 0:03b5121a232e 21490 {
pcercuei 0:03b5121a232e 21491 switch (type) {
pcercuei 0:03b5121a232e 21492 case XML_SCHEMA_FACET_PATTERN:
pcercuei 0:03b5121a232e 21493 return (BAD_CAST "pattern");
pcercuei 0:03b5121a232e 21494 case XML_SCHEMA_FACET_MAXEXCLUSIVE:
pcercuei 0:03b5121a232e 21495 return (BAD_CAST "maxExclusive");
pcercuei 0:03b5121a232e 21496 case XML_SCHEMA_FACET_MAXINCLUSIVE:
pcercuei 0:03b5121a232e 21497 return (BAD_CAST "maxInclusive");
pcercuei 0:03b5121a232e 21498 case XML_SCHEMA_FACET_MINEXCLUSIVE:
pcercuei 0:03b5121a232e 21499 return (BAD_CAST "minExclusive");
pcercuei 0:03b5121a232e 21500 case XML_SCHEMA_FACET_MININCLUSIVE:
pcercuei 0:03b5121a232e 21501 return (BAD_CAST "minInclusive");
pcercuei 0:03b5121a232e 21502 case XML_SCHEMA_FACET_WHITESPACE:
pcercuei 0:03b5121a232e 21503 return (BAD_CAST "whiteSpace");
pcercuei 0:03b5121a232e 21504 case XML_SCHEMA_FACET_ENUMERATION:
pcercuei 0:03b5121a232e 21505 return (BAD_CAST "enumeration");
pcercuei 0:03b5121a232e 21506 case XML_SCHEMA_FACET_LENGTH:
pcercuei 0:03b5121a232e 21507 return (BAD_CAST "length");
pcercuei 0:03b5121a232e 21508 case XML_SCHEMA_FACET_MAXLENGTH:
pcercuei 0:03b5121a232e 21509 return (BAD_CAST "maxLength");
pcercuei 0:03b5121a232e 21510 case XML_SCHEMA_FACET_MINLENGTH:
pcercuei 0:03b5121a232e 21511 return (BAD_CAST "minLength");
pcercuei 0:03b5121a232e 21512 case XML_SCHEMA_FACET_TOTALDIGITS:
pcercuei 0:03b5121a232e 21513 return (BAD_CAST "totalDigits");
pcercuei 0:03b5121a232e 21514 case XML_SCHEMA_FACET_FRACTIONDIGITS:
pcercuei 0:03b5121a232e 21515 return (BAD_CAST "fractionDigits");
pcercuei 0:03b5121a232e 21516 default:
pcercuei 0:03b5121a232e 21517 break;
pcercuei 0:03b5121a232e 21518 }
pcercuei 0:03b5121a232e 21519 return (BAD_CAST "Internal Error");
pcercuei 0:03b5121a232e 21520 }
pcercuei 0:03b5121a232e 21521
pcercuei 0:03b5121a232e 21522 static xmlSchemaWhitespaceValueType
pcercuei 0:03b5121a232e 21523 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
pcercuei 0:03b5121a232e 21524 {
pcercuei 0:03b5121a232e 21525 /*
pcercuei 0:03b5121a232e 21526 * The normalization type can be changed only for types which are derived
pcercuei 0:03b5121a232e 21527 * from xsd:string.
pcercuei 0:03b5121a232e 21528 */
pcercuei 0:03b5121a232e 21529 if (type->type == XML_SCHEMA_TYPE_BASIC) {
pcercuei 0:03b5121a232e 21530 /*
pcercuei 0:03b5121a232e 21531 * Note that we assume a whitespace of preserve for anySimpleType.
pcercuei 0:03b5121a232e 21532 */
pcercuei 0:03b5121a232e 21533 if ((type->builtInType == XML_SCHEMAS_STRING) ||
pcercuei 0:03b5121a232e 21534 (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
pcercuei 0:03b5121a232e 21535 return(XML_SCHEMA_WHITESPACE_PRESERVE);
pcercuei 0:03b5121a232e 21536 else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
pcercuei 0:03b5121a232e 21537 return(XML_SCHEMA_WHITESPACE_REPLACE);
pcercuei 0:03b5121a232e 21538 else {
pcercuei 0:03b5121a232e 21539 /*
pcercuei 0:03b5121a232e 21540 * For all `atomic` datatypes other than string (and types `derived`
pcercuei 0:03b5121a232e 21541 * by `restriction` from it) the value of whiteSpace is fixed to
pcercuei 0:03b5121a232e 21542 * collapse
pcercuei 0:03b5121a232e 21543 * Note that this includes built-in list datatypes.
pcercuei 0:03b5121a232e 21544 */
pcercuei 0:03b5121a232e 21545 return(XML_SCHEMA_WHITESPACE_COLLAPSE);
pcercuei 0:03b5121a232e 21546 }
pcercuei 0:03b5121a232e 21547 } else if (WXS_IS_LIST(type)) {
pcercuei 0:03b5121a232e 21548 /*
pcercuei 0:03b5121a232e 21549 * For list types the facet "whiteSpace" is fixed to "collapse".
pcercuei 0:03b5121a232e 21550 */
pcercuei 0:03b5121a232e 21551 return (XML_SCHEMA_WHITESPACE_COLLAPSE);
pcercuei 0:03b5121a232e 21552 } else if (WXS_IS_UNION(type)) {
pcercuei 0:03b5121a232e 21553 return (XML_SCHEMA_WHITESPACE_UNKNOWN);
pcercuei 0:03b5121a232e 21554 } else if (WXS_IS_ATOMIC(type)) {
pcercuei 0:03b5121a232e 21555 if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
pcercuei 0:03b5121a232e 21556 return (XML_SCHEMA_WHITESPACE_PRESERVE);
pcercuei 0:03b5121a232e 21557 else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
pcercuei 0:03b5121a232e 21558 return (XML_SCHEMA_WHITESPACE_REPLACE);
pcercuei 0:03b5121a232e 21559 else
pcercuei 0:03b5121a232e 21560 return (XML_SCHEMA_WHITESPACE_COLLAPSE);
pcercuei 0:03b5121a232e 21561 }
pcercuei 0:03b5121a232e 21562 return (-1);
pcercuei 0:03b5121a232e 21563 }
pcercuei 0:03b5121a232e 21564
pcercuei 0:03b5121a232e 21565 /************************************************************************
pcercuei 0:03b5121a232e 21566 * *
pcercuei 0:03b5121a232e 21567 * Simple type validation *
pcercuei 0:03b5121a232e 21568 * *
pcercuei 0:03b5121a232e 21569 ************************************************************************/
pcercuei 0:03b5121a232e 21570
pcercuei 0:03b5121a232e 21571
pcercuei 0:03b5121a232e 21572 /************************************************************************
pcercuei 0:03b5121a232e 21573 * *
pcercuei 0:03b5121a232e 21574 * DOM Validation code *
pcercuei 0:03b5121a232e 21575 * *
pcercuei 0:03b5121a232e 21576 ************************************************************************/
pcercuei 0:03b5121a232e 21577
pcercuei 0:03b5121a232e 21578 /**
pcercuei 0:03b5121a232e 21579 * xmlSchemaAssembleByLocation:
pcercuei 0:03b5121a232e 21580 * @pctxt: a schema parser context
pcercuei 0:03b5121a232e 21581 * @vctxt: a schema validation context
pcercuei 0:03b5121a232e 21582 * @schema: the existing schema
pcercuei 0:03b5121a232e 21583 * @node: the node that fired the assembling
pcercuei 0:03b5121a232e 21584 * @nsName: the namespace name of the new schema
pcercuei 0:03b5121a232e 21585 * @location: the location of the schema
pcercuei 0:03b5121a232e 21586 *
pcercuei 0:03b5121a232e 21587 * Expands an existing schema by an additional schema.
pcercuei 0:03b5121a232e 21588 *
pcercuei 0:03b5121a232e 21589 * Returns 0 if the new schema is correct, a positive error code
pcercuei 0:03b5121a232e 21590 * number otherwise and -1 in case of an internal or API error.
pcercuei 0:03b5121a232e 21591 */
pcercuei 0:03b5121a232e 21592 static int
pcercuei 0:03b5121a232e 21593 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 21594 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 21595 xmlNodePtr node,
pcercuei 0:03b5121a232e 21596 const xmlChar *nsName,
pcercuei 0:03b5121a232e 21597 const xmlChar *location)
pcercuei 0:03b5121a232e 21598 {
pcercuei 0:03b5121a232e 21599 int ret = 0;
pcercuei 0:03b5121a232e 21600 xmlSchemaParserCtxtPtr pctxt;
pcercuei 0:03b5121a232e 21601 xmlSchemaBucketPtr bucket = NULL;
pcercuei 0:03b5121a232e 21602
pcercuei 0:03b5121a232e 21603 if ((vctxt == NULL) || (schema == NULL))
pcercuei 0:03b5121a232e 21604 return (-1);
pcercuei 0:03b5121a232e 21605
pcercuei 0:03b5121a232e 21606 if (vctxt->pctxt == NULL) {
pcercuei 0:03b5121a232e 21607 VERROR_INT("xmlSchemaAssembleByLocation",
pcercuei 0:03b5121a232e 21608 "no parser context available");
pcercuei 0:03b5121a232e 21609 return(-1);
pcercuei 0:03b5121a232e 21610 }
pcercuei 0:03b5121a232e 21611 pctxt = vctxt->pctxt;
pcercuei 0:03b5121a232e 21612 if (pctxt->constructor == NULL) {
pcercuei 0:03b5121a232e 21613 PERROR_INT("xmlSchemaAssembleByLocation",
pcercuei 0:03b5121a232e 21614 "no constructor");
pcercuei 0:03b5121a232e 21615 return(-1);
pcercuei 0:03b5121a232e 21616 }
pcercuei 0:03b5121a232e 21617 /*
pcercuei 0:03b5121a232e 21618 * Acquire the schema document.
pcercuei 0:03b5121a232e 21619 */
pcercuei 0:03b5121a232e 21620 location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
pcercuei 0:03b5121a232e 21621 location, node);
pcercuei 0:03b5121a232e 21622 /*
pcercuei 0:03b5121a232e 21623 * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
pcercuei 0:03b5121a232e 21624 * the process will automatically change this to
pcercuei 0:03b5121a232e 21625 * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
pcercuei 0:03b5121a232e 21626 */
pcercuei 0:03b5121a232e 21627 ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
pcercuei 0:03b5121a232e 21628 location, NULL, NULL, 0, node, NULL, nsName,
pcercuei 0:03b5121a232e 21629 &bucket);
pcercuei 0:03b5121a232e 21630 if (ret != 0)
pcercuei 0:03b5121a232e 21631 return(ret);
pcercuei 0:03b5121a232e 21632 if (bucket == NULL) {
pcercuei 0:03b5121a232e 21633 /*
pcercuei 0:03b5121a232e 21634 * Generate a warning that the document could not be located.
pcercuei 0:03b5121a232e 21635 */
pcercuei 0:03b5121a232e 21636 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
pcercuei 0:03b5121a232e 21637 node, NULL,
pcercuei 0:03b5121a232e 21638 "The document at location '%s' could not be acquired",
pcercuei 0:03b5121a232e 21639 location, NULL, NULL);
pcercuei 0:03b5121a232e 21640 return(ret);
pcercuei 0:03b5121a232e 21641 }
pcercuei 0:03b5121a232e 21642 /*
pcercuei 0:03b5121a232e 21643 * The first located schema will be handled as if all other
pcercuei 0:03b5121a232e 21644 * schemas imported by XSI were imported by this first schema.
pcercuei 0:03b5121a232e 21645 */
pcercuei 0:03b5121a232e 21646 if ((bucket != NULL) &&
pcercuei 0:03b5121a232e 21647 (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
pcercuei 0:03b5121a232e 21648 WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
pcercuei 0:03b5121a232e 21649 /*
pcercuei 0:03b5121a232e 21650 * TODO: Is this handled like an import? I.e. is it not an error
pcercuei 0:03b5121a232e 21651 * if the schema cannot be located?
pcercuei 0:03b5121a232e 21652 */
pcercuei 0:03b5121a232e 21653 if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
pcercuei 0:03b5121a232e 21654 return(0);
pcercuei 0:03b5121a232e 21655 /*
pcercuei 0:03b5121a232e 21656 * We will reuse the parser context for every schema imported
pcercuei 0:03b5121a232e 21657 * directly via XSI. So reset the context.
pcercuei 0:03b5121a232e 21658 */
pcercuei 0:03b5121a232e 21659 pctxt->nberrors = 0;
pcercuei 0:03b5121a232e 21660 pctxt->err = 0;
pcercuei 0:03b5121a232e 21661 pctxt->doc = bucket->doc;
pcercuei 0:03b5121a232e 21662
pcercuei 0:03b5121a232e 21663 ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
pcercuei 0:03b5121a232e 21664 if (ret == -1) {
pcercuei 0:03b5121a232e 21665 pctxt->doc = NULL;
pcercuei 0:03b5121a232e 21666 goto exit_failure;
pcercuei 0:03b5121a232e 21667 }
pcercuei 0:03b5121a232e 21668 /* Paranoid error channelling. */
pcercuei 0:03b5121a232e 21669 if ((ret == 0) && (pctxt->nberrors != 0))
pcercuei 0:03b5121a232e 21670 ret = pctxt->err;
pcercuei 0:03b5121a232e 21671 if (pctxt->nberrors == 0) {
pcercuei 0:03b5121a232e 21672 /*
pcercuei 0:03b5121a232e 21673 * Only bother to fixup pending components, if there was
pcercuei 0:03b5121a232e 21674 * no error yet.
pcercuei 0:03b5121a232e 21675 * For every XSI acquired schema (and its sub-schemata) we will
pcercuei 0:03b5121a232e 21676 * fixup the components.
pcercuei 0:03b5121a232e 21677 */
pcercuei 0:03b5121a232e 21678 xmlSchemaFixupComponents(pctxt, bucket);
pcercuei 0:03b5121a232e 21679 ret = pctxt->err;
pcercuei 0:03b5121a232e 21680 /*
pcercuei 0:03b5121a232e 21681 * Not nice, but we need somehow to channel the schema parser
pcercuei 0:03b5121a232e 21682 * error to the validation context.
pcercuei 0:03b5121a232e 21683 */
pcercuei 0:03b5121a232e 21684 if ((ret != 0) && (vctxt->err == 0))
pcercuei 0:03b5121a232e 21685 vctxt->err = ret;
pcercuei 0:03b5121a232e 21686 vctxt->nberrors += pctxt->nberrors;
pcercuei 0:03b5121a232e 21687 } else {
pcercuei 0:03b5121a232e 21688 /* Add to validation error sum. */
pcercuei 0:03b5121a232e 21689 vctxt->nberrors += pctxt->nberrors;
pcercuei 0:03b5121a232e 21690 }
pcercuei 0:03b5121a232e 21691 pctxt->doc = NULL;
pcercuei 0:03b5121a232e 21692 return(ret);
pcercuei 0:03b5121a232e 21693 exit_failure:
pcercuei 0:03b5121a232e 21694 pctxt->doc = NULL;
pcercuei 0:03b5121a232e 21695 return (-1);
pcercuei 0:03b5121a232e 21696 }
pcercuei 0:03b5121a232e 21697
pcercuei 0:03b5121a232e 21698 static xmlSchemaAttrInfoPtr
pcercuei 0:03b5121a232e 21699 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 21700 int metaType)
pcercuei 0:03b5121a232e 21701 {
pcercuei 0:03b5121a232e 21702 if (vctxt->nbAttrInfos == 0)
pcercuei 0:03b5121a232e 21703 return (NULL);
pcercuei 0:03b5121a232e 21704 {
pcercuei 0:03b5121a232e 21705 int i;
pcercuei 0:03b5121a232e 21706 xmlSchemaAttrInfoPtr iattr;
pcercuei 0:03b5121a232e 21707
pcercuei 0:03b5121a232e 21708 for (i = 0; i < vctxt->nbAttrInfos; i++) {
pcercuei 0:03b5121a232e 21709 iattr = vctxt->attrInfos[i];
pcercuei 0:03b5121a232e 21710 if (iattr->metaType == metaType)
pcercuei 0:03b5121a232e 21711 return (iattr);
pcercuei 0:03b5121a232e 21712 }
pcercuei 0:03b5121a232e 21713
pcercuei 0:03b5121a232e 21714 }
pcercuei 0:03b5121a232e 21715 return (NULL);
pcercuei 0:03b5121a232e 21716 }
pcercuei 0:03b5121a232e 21717
pcercuei 0:03b5121a232e 21718 /**
pcercuei 0:03b5121a232e 21719 * xmlSchemaAssembleByXSI:
pcercuei 0:03b5121a232e 21720 * @vctxt: a schema validation context
pcercuei 0:03b5121a232e 21721 *
pcercuei 0:03b5121a232e 21722 * Expands an existing schema by an additional schema using
pcercuei 0:03b5121a232e 21723 * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
pcercuei 0:03b5121a232e 21724 * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
pcercuei 0:03b5121a232e 21725 * must be set to 1.
pcercuei 0:03b5121a232e 21726 *
pcercuei 0:03b5121a232e 21727 * Returns 0 if the new schema is correct, a positive error code
pcercuei 0:03b5121a232e 21728 * number otherwise and -1 in case of an internal or API error.
pcercuei 0:03b5121a232e 21729 */
pcercuei 0:03b5121a232e 21730 static int
pcercuei 0:03b5121a232e 21731 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 21732 {
pcercuei 0:03b5121a232e 21733 const xmlChar *cur, *end;
pcercuei 0:03b5121a232e 21734 const xmlChar *nsname = NULL, *location;
pcercuei 0:03b5121a232e 21735 int count = 0;
pcercuei 0:03b5121a232e 21736 int ret = 0;
pcercuei 0:03b5121a232e 21737 xmlSchemaAttrInfoPtr iattr;
pcercuei 0:03b5121a232e 21738
pcercuei 0:03b5121a232e 21739 /*
pcercuei 0:03b5121a232e 21740 * Parse the value; we will assume an even number of values
pcercuei 0:03b5121a232e 21741 * to be given (this is how Xerces and XSV work).
pcercuei 0:03b5121a232e 21742 *
pcercuei 0:03b5121a232e 21743 * URGENT TODO: !! This needs to work for both
pcercuei 0:03b5121a232e 21744 * @noNamespaceSchemaLocation AND @schemaLocation on the same
pcercuei 0:03b5121a232e 21745 * element !!
pcercuei 0:03b5121a232e 21746 */
pcercuei 0:03b5121a232e 21747 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
pcercuei 0:03b5121a232e 21748 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
pcercuei 0:03b5121a232e 21749 if (iattr == NULL)
pcercuei 0:03b5121a232e 21750 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
pcercuei 0:03b5121a232e 21751 XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
pcercuei 0:03b5121a232e 21752 if (iattr == NULL)
pcercuei 0:03b5121a232e 21753 return (0);
pcercuei 0:03b5121a232e 21754 cur = iattr->value;
pcercuei 0:03b5121a232e 21755 do {
pcercuei 0:03b5121a232e 21756 /*
pcercuei 0:03b5121a232e 21757 * TODO: Move the string parsing mechanism away from here.
pcercuei 0:03b5121a232e 21758 */
pcercuei 0:03b5121a232e 21759 if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
pcercuei 0:03b5121a232e 21760 /*
pcercuei 0:03b5121a232e 21761 * Get the namespace name.
pcercuei 0:03b5121a232e 21762 */
pcercuei 0:03b5121a232e 21763 while (IS_BLANK_CH(*cur))
pcercuei 0:03b5121a232e 21764 cur++;
pcercuei 0:03b5121a232e 21765 end = cur;
pcercuei 0:03b5121a232e 21766 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
pcercuei 0:03b5121a232e 21767 end++;
pcercuei 0:03b5121a232e 21768 if (end == cur)
pcercuei 0:03b5121a232e 21769 break;
pcercuei 0:03b5121a232e 21770 count++; /* TODO: Don't use the schema's dict. */
pcercuei 0:03b5121a232e 21771 nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
pcercuei 0:03b5121a232e 21772 cur = end;
pcercuei 0:03b5121a232e 21773 }
pcercuei 0:03b5121a232e 21774 /*
pcercuei 0:03b5121a232e 21775 * Get the URI.
pcercuei 0:03b5121a232e 21776 */
pcercuei 0:03b5121a232e 21777 while (IS_BLANK_CH(*cur))
pcercuei 0:03b5121a232e 21778 cur++;
pcercuei 0:03b5121a232e 21779 end = cur;
pcercuei 0:03b5121a232e 21780 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
pcercuei 0:03b5121a232e 21781 end++;
pcercuei 0:03b5121a232e 21782 if (end == cur) {
pcercuei 0:03b5121a232e 21783 if (iattr->metaType ==
pcercuei 0:03b5121a232e 21784 XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
pcercuei 0:03b5121a232e 21785 {
pcercuei 0:03b5121a232e 21786 /*
pcercuei 0:03b5121a232e 21787 * If using @schemaLocation then tuples are expected.
pcercuei 0:03b5121a232e 21788 * I.e. the namespace name *and* the document's URI.
pcercuei 0:03b5121a232e 21789 */
pcercuei 0:03b5121a232e 21790 xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
pcercuei 0:03b5121a232e 21791 iattr->node, NULL,
pcercuei 0:03b5121a232e 21792 "The value must consist of tuples: the target namespace "
pcercuei 0:03b5121a232e 21793 "name and the document's URI", NULL, NULL, NULL);
pcercuei 0:03b5121a232e 21794 }
pcercuei 0:03b5121a232e 21795 break;
pcercuei 0:03b5121a232e 21796 }
pcercuei 0:03b5121a232e 21797 count++; /* TODO: Don't use the schema's dict. */
pcercuei 0:03b5121a232e 21798 location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
pcercuei 0:03b5121a232e 21799 cur = end;
pcercuei 0:03b5121a232e 21800 ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
pcercuei 0:03b5121a232e 21801 iattr->node, nsname, location);
pcercuei 0:03b5121a232e 21802 if (ret == -1) {
pcercuei 0:03b5121a232e 21803 VERROR_INT("xmlSchemaAssembleByXSI",
pcercuei 0:03b5121a232e 21804 "assembling schemata");
pcercuei 0:03b5121a232e 21805 return (-1);
pcercuei 0:03b5121a232e 21806 }
pcercuei 0:03b5121a232e 21807 } while (*cur != 0);
pcercuei 0:03b5121a232e 21808 return (ret);
pcercuei 0:03b5121a232e 21809 }
pcercuei 0:03b5121a232e 21810
pcercuei 0:03b5121a232e 21811 static const xmlChar *
pcercuei 0:03b5121a232e 21812 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 21813 const xmlChar *prefix)
pcercuei 0:03b5121a232e 21814 {
pcercuei 0:03b5121a232e 21815 if (vctxt->sax != NULL) {
pcercuei 0:03b5121a232e 21816 int i, j;
pcercuei 0:03b5121a232e 21817 xmlSchemaNodeInfoPtr inode;
pcercuei 0:03b5121a232e 21818
pcercuei 0:03b5121a232e 21819 for (i = vctxt->depth; i >= 0; i--) {
pcercuei 0:03b5121a232e 21820 if (vctxt->elemInfos[i]->nbNsBindings != 0) {
pcercuei 0:03b5121a232e 21821 inode = vctxt->elemInfos[i];
pcercuei 0:03b5121a232e 21822 for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
pcercuei 0:03b5121a232e 21823 if (((prefix == NULL) &&
pcercuei 0:03b5121a232e 21824 (inode->nsBindings[j] == NULL)) ||
pcercuei 0:03b5121a232e 21825 ((prefix != NULL) && xmlStrEqual(prefix,
pcercuei 0:03b5121a232e 21826 inode->nsBindings[j]))) {
pcercuei 0:03b5121a232e 21827
pcercuei 0:03b5121a232e 21828 /*
pcercuei 0:03b5121a232e 21829 * Note that the namespace bindings are already
pcercuei 0:03b5121a232e 21830 * in a string dict.
pcercuei 0:03b5121a232e 21831 */
pcercuei 0:03b5121a232e 21832 return (inode->nsBindings[j+1]);
pcercuei 0:03b5121a232e 21833 }
pcercuei 0:03b5121a232e 21834 }
pcercuei 0:03b5121a232e 21835 }
pcercuei 0:03b5121a232e 21836 }
pcercuei 0:03b5121a232e 21837 return (NULL);
pcercuei 0:03b5121a232e 21838 #ifdef LIBXML_READER_ENABLED
pcercuei 0:03b5121a232e 21839 } else if (vctxt->reader != NULL) {
pcercuei 0:03b5121a232e 21840 xmlChar *nsName;
pcercuei 0:03b5121a232e 21841
pcercuei 0:03b5121a232e 21842 nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
pcercuei 0:03b5121a232e 21843 if (nsName != NULL) {
pcercuei 0:03b5121a232e 21844 const xmlChar *ret;
pcercuei 0:03b5121a232e 21845
pcercuei 0:03b5121a232e 21846 ret = xmlDictLookup(vctxt->dict, nsName, -1);
pcercuei 0:03b5121a232e 21847 xmlFree(nsName);
pcercuei 0:03b5121a232e 21848 return (ret);
pcercuei 0:03b5121a232e 21849 } else
pcercuei 0:03b5121a232e 21850 return (NULL);
pcercuei 0:03b5121a232e 21851 #endif
pcercuei 0:03b5121a232e 21852 } else {
pcercuei 0:03b5121a232e 21853 xmlNsPtr ns;
pcercuei 0:03b5121a232e 21854
pcercuei 0:03b5121a232e 21855 if ((vctxt->inode->node == NULL) ||
pcercuei 0:03b5121a232e 21856 (vctxt->inode->node->doc == NULL)) {
pcercuei 0:03b5121a232e 21857 VERROR_INT("xmlSchemaLookupNamespace",
pcercuei 0:03b5121a232e 21858 "no node or node's doc avaliable");
pcercuei 0:03b5121a232e 21859 return (NULL);
pcercuei 0:03b5121a232e 21860 }
pcercuei 0:03b5121a232e 21861 ns = xmlSearchNs(vctxt->inode->node->doc,
pcercuei 0:03b5121a232e 21862 vctxt->inode->node, prefix);
pcercuei 0:03b5121a232e 21863 if (ns != NULL)
pcercuei 0:03b5121a232e 21864 return (ns->href);
pcercuei 0:03b5121a232e 21865 return (NULL);
pcercuei 0:03b5121a232e 21866 }
pcercuei 0:03b5121a232e 21867 }
pcercuei 0:03b5121a232e 21868
pcercuei 0:03b5121a232e 21869 /*
pcercuei 0:03b5121a232e 21870 * This one works on the schema of the validation context.
pcercuei 0:03b5121a232e 21871 */
pcercuei 0:03b5121a232e 21872 static int
pcercuei 0:03b5121a232e 21873 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 21874 xmlSchemaPtr schema,
pcercuei 0:03b5121a232e 21875 xmlNodePtr node,
pcercuei 0:03b5121a232e 21876 const xmlChar *value,
pcercuei 0:03b5121a232e 21877 xmlSchemaValPtr *val,
pcercuei 0:03b5121a232e 21878 int valNeeded)
pcercuei 0:03b5121a232e 21879 {
pcercuei 0:03b5121a232e 21880 int ret;
pcercuei 0:03b5121a232e 21881
pcercuei 0:03b5121a232e 21882 if (vctxt && (vctxt->schema == NULL)) {
pcercuei 0:03b5121a232e 21883 VERROR_INT("xmlSchemaValidateNotation",
pcercuei 0:03b5121a232e 21884 "a schema is needed on the validation context");
pcercuei 0:03b5121a232e 21885 return (-1);
pcercuei 0:03b5121a232e 21886 }
pcercuei 0:03b5121a232e 21887 ret = xmlValidateQName(value, 1);
pcercuei 0:03b5121a232e 21888 if (ret != 0)
pcercuei 0:03b5121a232e 21889 return (ret);
pcercuei 0:03b5121a232e 21890 {
pcercuei 0:03b5121a232e 21891 xmlChar *localName = NULL;
pcercuei 0:03b5121a232e 21892 xmlChar *prefix = NULL;
pcercuei 0:03b5121a232e 21893
pcercuei 0:03b5121a232e 21894 localName = xmlSplitQName2(value, &prefix);
pcercuei 0:03b5121a232e 21895 if (prefix != NULL) {
pcercuei 0:03b5121a232e 21896 const xmlChar *nsName = NULL;
pcercuei 0:03b5121a232e 21897
pcercuei 0:03b5121a232e 21898 if (vctxt != NULL)
pcercuei 0:03b5121a232e 21899 nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
pcercuei 0:03b5121a232e 21900 else if (node != NULL) {
pcercuei 0:03b5121a232e 21901 xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
pcercuei 0:03b5121a232e 21902 if (ns != NULL)
pcercuei 0:03b5121a232e 21903 nsName = ns->href;
pcercuei 0:03b5121a232e 21904 } else {
pcercuei 0:03b5121a232e 21905 xmlFree(prefix);
pcercuei 0:03b5121a232e 21906 xmlFree(localName);
pcercuei 0:03b5121a232e 21907 return (1);
pcercuei 0:03b5121a232e 21908 }
pcercuei 0:03b5121a232e 21909 if (nsName == NULL) {
pcercuei 0:03b5121a232e 21910 xmlFree(prefix);
pcercuei 0:03b5121a232e 21911 xmlFree(localName);
pcercuei 0:03b5121a232e 21912 return (1);
pcercuei 0:03b5121a232e 21913 }
pcercuei 0:03b5121a232e 21914 if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
pcercuei 0:03b5121a232e 21915 if ((valNeeded) && (val != NULL)) {
pcercuei 0:03b5121a232e 21916 (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
pcercuei 0:03b5121a232e 21917 xmlStrdup(nsName));
pcercuei 0:03b5121a232e 21918 if (*val == NULL)
pcercuei 0:03b5121a232e 21919 ret = -1;
pcercuei 0:03b5121a232e 21920 }
pcercuei 0:03b5121a232e 21921 } else
pcercuei 0:03b5121a232e 21922 ret = 1;
pcercuei 0:03b5121a232e 21923 xmlFree(prefix);
pcercuei 0:03b5121a232e 21924 xmlFree(localName);
pcercuei 0:03b5121a232e 21925 } else {
pcercuei 0:03b5121a232e 21926 if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
pcercuei 0:03b5121a232e 21927 if (valNeeded && (val != NULL)) {
pcercuei 0:03b5121a232e 21928 (*val) = xmlSchemaNewNOTATIONValue(
pcercuei 0:03b5121a232e 21929 BAD_CAST xmlStrdup(value), NULL);
pcercuei 0:03b5121a232e 21930 if (*val == NULL)
pcercuei 0:03b5121a232e 21931 ret = -1;
pcercuei 0:03b5121a232e 21932 }
pcercuei 0:03b5121a232e 21933 } else
pcercuei 0:03b5121a232e 21934 return (1);
pcercuei 0:03b5121a232e 21935 }
pcercuei 0:03b5121a232e 21936 }
pcercuei 0:03b5121a232e 21937 return (ret);
pcercuei 0:03b5121a232e 21938 }
pcercuei 0:03b5121a232e 21939
pcercuei 0:03b5121a232e 21940 static int
pcercuei 0:03b5121a232e 21941 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 21942 const xmlChar* lname,
pcercuei 0:03b5121a232e 21943 const xmlChar* nsname)
pcercuei 0:03b5121a232e 21944 {
pcercuei 0:03b5121a232e 21945 int i;
pcercuei 0:03b5121a232e 21946
pcercuei 0:03b5121a232e 21947 lname = xmlDictLookup(vctxt->dict, lname, -1);
pcercuei 0:03b5121a232e 21948 if (lname == NULL)
pcercuei 0:03b5121a232e 21949 return(-1);
pcercuei 0:03b5121a232e 21950 if (nsname != NULL) {
pcercuei 0:03b5121a232e 21951 nsname = xmlDictLookup(vctxt->dict, nsname, -1);
pcercuei 0:03b5121a232e 21952 if (nsname == NULL)
pcercuei 0:03b5121a232e 21953 return(-1);
pcercuei 0:03b5121a232e 21954 }
pcercuei 0:03b5121a232e 21955 for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
pcercuei 0:03b5121a232e 21956 if ((vctxt->nodeQNames->items [i] == lname) &&
pcercuei 0:03b5121a232e 21957 (vctxt->nodeQNames->items[i +1] == nsname))
pcercuei 0:03b5121a232e 21958 /* Already there */
pcercuei 0:03b5121a232e 21959 return(i);
pcercuei 0:03b5121a232e 21960 }
pcercuei 0:03b5121a232e 21961 /* Add new entry. */
pcercuei 0:03b5121a232e 21962 i = vctxt->nodeQNames->nbItems;
pcercuei 0:03b5121a232e 21963 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
pcercuei 0:03b5121a232e 21964 xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
pcercuei 0:03b5121a232e 21965 return(i);
pcercuei 0:03b5121a232e 21966 }
pcercuei 0:03b5121a232e 21967
pcercuei 0:03b5121a232e 21968 /************************************************************************
pcercuei 0:03b5121a232e 21969 * *
pcercuei 0:03b5121a232e 21970 * Validation of identity-constraints (IDC) *
pcercuei 0:03b5121a232e 21971 * *
pcercuei 0:03b5121a232e 21972 ************************************************************************/
pcercuei 0:03b5121a232e 21973
pcercuei 0:03b5121a232e 21974 /**
pcercuei 0:03b5121a232e 21975 * xmlSchemaAugmentIDC:
pcercuei 0:03b5121a232e 21976 * @idcDef: the IDC definition
pcercuei 0:03b5121a232e 21977 *
pcercuei 0:03b5121a232e 21978 * Creates an augmented IDC definition item.
pcercuei 0:03b5121a232e 21979 *
pcercuei 0:03b5121a232e 21980 * Returns the item, or NULL on internal errors.
pcercuei 0:03b5121a232e 21981 */
pcercuei 0:03b5121a232e 21982 static void
pcercuei 0:03b5121a232e 21983 xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
pcercuei 0:03b5121a232e 21984 xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 21985 {
pcercuei 0:03b5121a232e 21986 xmlSchemaIDCAugPtr aidc;
pcercuei 0:03b5121a232e 21987
pcercuei 0:03b5121a232e 21988 aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
pcercuei 0:03b5121a232e 21989 if (aidc == NULL) {
pcercuei 0:03b5121a232e 21990 xmlSchemaVErrMemory(vctxt,
pcercuei 0:03b5121a232e 21991 "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
pcercuei 0:03b5121a232e 21992 NULL);
pcercuei 0:03b5121a232e 21993 return;
pcercuei 0:03b5121a232e 21994 }
pcercuei 0:03b5121a232e 21995 aidc->keyrefDepth = -1;
pcercuei 0:03b5121a232e 21996 aidc->def = idcDef;
pcercuei 0:03b5121a232e 21997 aidc->next = NULL;
pcercuei 0:03b5121a232e 21998 if (vctxt->aidcs == NULL)
pcercuei 0:03b5121a232e 21999 vctxt->aidcs = aidc;
pcercuei 0:03b5121a232e 22000 else {
pcercuei 0:03b5121a232e 22001 aidc->next = vctxt->aidcs;
pcercuei 0:03b5121a232e 22002 vctxt->aidcs = aidc;
pcercuei 0:03b5121a232e 22003 }
pcercuei 0:03b5121a232e 22004 /*
pcercuei 0:03b5121a232e 22005 * Save if we have keyrefs at all.
pcercuei 0:03b5121a232e 22006 */
pcercuei 0:03b5121a232e 22007 if ((vctxt->hasKeyrefs == 0) &&
pcercuei 0:03b5121a232e 22008 (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
pcercuei 0:03b5121a232e 22009 vctxt->hasKeyrefs = 1;
pcercuei 0:03b5121a232e 22010 }
pcercuei 0:03b5121a232e 22011
pcercuei 0:03b5121a232e 22012 /**
pcercuei 0:03b5121a232e 22013 * xmlSchemaAugmentImportedIDC:
pcercuei 0:03b5121a232e 22014 * @imported: the imported schema
pcercuei 0:03b5121a232e 22015 *
pcercuei 0:03b5121a232e 22016 * Creates an augmented IDC definition for the imported schema.
pcercuei 0:03b5121a232e 22017 */
pcercuei 0:03b5121a232e 22018 static void
pcercuei 0:03b5121a232e 22019 xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
pcercuei 0:03b5121a232e 22020 if (imported->schema->idcDef != NULL) {
pcercuei 0:03b5121a232e 22021 xmlHashScan(imported->schema->idcDef ,
pcercuei 0:03b5121a232e 22022 (xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
pcercuei 0:03b5121a232e 22023 }
pcercuei 0:03b5121a232e 22024 }
pcercuei 0:03b5121a232e 22025
pcercuei 0:03b5121a232e 22026 /**
pcercuei 0:03b5121a232e 22027 * xmlSchemaIDCNewBinding:
pcercuei 0:03b5121a232e 22028 * @idcDef: the IDC definition of this binding
pcercuei 0:03b5121a232e 22029 *
pcercuei 0:03b5121a232e 22030 * Creates a new IDC binding.
pcercuei 0:03b5121a232e 22031 *
pcercuei 0:03b5121a232e 22032 * Returns the new IDC binding, NULL on internal errors.
pcercuei 0:03b5121a232e 22033 */
pcercuei 0:03b5121a232e 22034 static xmlSchemaPSVIIDCBindingPtr
pcercuei 0:03b5121a232e 22035 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
pcercuei 0:03b5121a232e 22036 {
pcercuei 0:03b5121a232e 22037 xmlSchemaPSVIIDCBindingPtr ret;
pcercuei 0:03b5121a232e 22038
pcercuei 0:03b5121a232e 22039 ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
pcercuei 0:03b5121a232e 22040 sizeof(xmlSchemaPSVIIDCBinding));
pcercuei 0:03b5121a232e 22041 if (ret == NULL) {
pcercuei 0:03b5121a232e 22042 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 22043 "allocating a PSVI IDC binding item", NULL);
pcercuei 0:03b5121a232e 22044 return (NULL);
pcercuei 0:03b5121a232e 22045 }
pcercuei 0:03b5121a232e 22046 memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
pcercuei 0:03b5121a232e 22047 ret->definition = idcDef;
pcercuei 0:03b5121a232e 22048 return (ret);
pcercuei 0:03b5121a232e 22049 }
pcercuei 0:03b5121a232e 22050
pcercuei 0:03b5121a232e 22051 /**
pcercuei 0:03b5121a232e 22052 * xmlSchemaIDCStoreNodeTableItem:
pcercuei 0:03b5121a232e 22053 * @vctxt: the WXS validation context
pcercuei 0:03b5121a232e 22054 * @item: the IDC node table item
pcercuei 0:03b5121a232e 22055 *
pcercuei 0:03b5121a232e 22056 * The validation context is used to store IDC node table items.
pcercuei 0:03b5121a232e 22057 * They are stored to avoid copying them if IDC node-tables are merged
pcercuei 0:03b5121a232e 22058 * with corresponding parent IDC node-tables (bubbling).
pcercuei 0:03b5121a232e 22059 *
pcercuei 0:03b5121a232e 22060 * Returns 0 if succeeded, -1 on internal errors.
pcercuei 0:03b5121a232e 22061 */
pcercuei 0:03b5121a232e 22062 static int
pcercuei 0:03b5121a232e 22063 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 22064 xmlSchemaPSVIIDCNodePtr item)
pcercuei 0:03b5121a232e 22065 {
pcercuei 0:03b5121a232e 22066 /*
pcercuei 0:03b5121a232e 22067 * Add to gobal list.
pcercuei 0:03b5121a232e 22068 */
pcercuei 0:03b5121a232e 22069 if (vctxt->idcNodes == NULL) {
pcercuei 0:03b5121a232e 22070 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
pcercuei 0:03b5121a232e 22071 xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
pcercuei 0:03b5121a232e 22072 if (vctxt->idcNodes == NULL) {
pcercuei 0:03b5121a232e 22073 xmlSchemaVErrMemory(vctxt,
pcercuei 0:03b5121a232e 22074 "allocating the IDC node table item list", NULL);
pcercuei 0:03b5121a232e 22075 return (-1);
pcercuei 0:03b5121a232e 22076 }
pcercuei 0:03b5121a232e 22077 vctxt->sizeIdcNodes = 20;
pcercuei 0:03b5121a232e 22078 } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
pcercuei 0:03b5121a232e 22079 vctxt->sizeIdcNodes *= 2;
pcercuei 0:03b5121a232e 22080 vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
pcercuei 0:03b5121a232e 22081 xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
pcercuei 0:03b5121a232e 22082 sizeof(xmlSchemaPSVIIDCNodePtr));
pcercuei 0:03b5121a232e 22083 if (vctxt->idcNodes == NULL) {
pcercuei 0:03b5121a232e 22084 xmlSchemaVErrMemory(vctxt,
pcercuei 0:03b5121a232e 22085 "re-allocating the IDC node table item list", NULL);
pcercuei 0:03b5121a232e 22086 return (-1);
pcercuei 0:03b5121a232e 22087 }
pcercuei 0:03b5121a232e 22088 }
pcercuei 0:03b5121a232e 22089 vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
pcercuei 0:03b5121a232e 22090
pcercuei 0:03b5121a232e 22091 return (0);
pcercuei 0:03b5121a232e 22092 }
pcercuei 0:03b5121a232e 22093
pcercuei 0:03b5121a232e 22094 /**
pcercuei 0:03b5121a232e 22095 * xmlSchemaIDCStoreKey:
pcercuei 0:03b5121a232e 22096 * @vctxt: the WXS validation context
pcercuei 0:03b5121a232e 22097 * @item: the IDC key
pcercuei 0:03b5121a232e 22098 *
pcercuei 0:03b5121a232e 22099 * The validation context is used to store an IDC key.
pcercuei 0:03b5121a232e 22100 *
pcercuei 0:03b5121a232e 22101 * Returns 0 if succeeded, -1 on internal errors.
pcercuei 0:03b5121a232e 22102 */
pcercuei 0:03b5121a232e 22103 static int
pcercuei 0:03b5121a232e 22104 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 22105 xmlSchemaPSVIIDCKeyPtr key)
pcercuei 0:03b5121a232e 22106 {
pcercuei 0:03b5121a232e 22107 /*
pcercuei 0:03b5121a232e 22108 * Add to gobal list.
pcercuei 0:03b5121a232e 22109 */
pcercuei 0:03b5121a232e 22110 if (vctxt->idcKeys == NULL) {
pcercuei 0:03b5121a232e 22111 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
pcercuei 0:03b5121a232e 22112 xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
pcercuei 0:03b5121a232e 22113 if (vctxt->idcKeys == NULL) {
pcercuei 0:03b5121a232e 22114 xmlSchemaVErrMemory(vctxt,
pcercuei 0:03b5121a232e 22115 "allocating the IDC key storage list", NULL);
pcercuei 0:03b5121a232e 22116 return (-1);
pcercuei 0:03b5121a232e 22117 }
pcercuei 0:03b5121a232e 22118 vctxt->sizeIdcKeys = 40;
pcercuei 0:03b5121a232e 22119 } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
pcercuei 0:03b5121a232e 22120 vctxt->sizeIdcKeys *= 2;
pcercuei 0:03b5121a232e 22121 vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
pcercuei 0:03b5121a232e 22122 xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
pcercuei 0:03b5121a232e 22123 sizeof(xmlSchemaPSVIIDCKeyPtr));
pcercuei 0:03b5121a232e 22124 if (vctxt->idcKeys == NULL) {
pcercuei 0:03b5121a232e 22125 xmlSchemaVErrMemory(vctxt,
pcercuei 0:03b5121a232e 22126 "re-allocating the IDC key storage list", NULL);
pcercuei 0:03b5121a232e 22127 return (-1);
pcercuei 0:03b5121a232e 22128 }
pcercuei 0:03b5121a232e 22129 }
pcercuei 0:03b5121a232e 22130 vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
pcercuei 0:03b5121a232e 22131
pcercuei 0:03b5121a232e 22132 return (0);
pcercuei 0:03b5121a232e 22133 }
pcercuei 0:03b5121a232e 22134
pcercuei 0:03b5121a232e 22135 /**
pcercuei 0:03b5121a232e 22136 * xmlSchemaIDCAppendNodeTableItem:
pcercuei 0:03b5121a232e 22137 * @bind: the IDC binding
pcercuei 0:03b5121a232e 22138 * @ntItem: the node-table item
pcercuei 0:03b5121a232e 22139 *
pcercuei 0:03b5121a232e 22140 * Appends the IDC node-table item to the binding.
pcercuei 0:03b5121a232e 22141 *
pcercuei 0:03b5121a232e 22142 * Returns 0 on success and -1 on internal errors.
pcercuei 0:03b5121a232e 22143 */
pcercuei 0:03b5121a232e 22144 static int
pcercuei 0:03b5121a232e 22145 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
pcercuei 0:03b5121a232e 22146 xmlSchemaPSVIIDCNodePtr ntItem)
pcercuei 0:03b5121a232e 22147 {
pcercuei 0:03b5121a232e 22148 if (bind->nodeTable == NULL) {
pcercuei 0:03b5121a232e 22149 bind->sizeNodes = 10;
pcercuei 0:03b5121a232e 22150 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
pcercuei 0:03b5121a232e 22151 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
pcercuei 0:03b5121a232e 22152 if (bind->nodeTable == NULL) {
pcercuei 0:03b5121a232e 22153 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 22154 "allocating an array of IDC node-table items", NULL);
pcercuei 0:03b5121a232e 22155 return(-1);
pcercuei 0:03b5121a232e 22156 }
pcercuei 0:03b5121a232e 22157 } else if (bind->sizeNodes <= bind->nbNodes) {
pcercuei 0:03b5121a232e 22158 bind->sizeNodes *= 2;
pcercuei 0:03b5121a232e 22159 bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
pcercuei 0:03b5121a232e 22160 xmlRealloc(bind->nodeTable, bind->sizeNodes *
pcercuei 0:03b5121a232e 22161 sizeof(xmlSchemaPSVIIDCNodePtr));
pcercuei 0:03b5121a232e 22162 if (bind->nodeTable == NULL) {
pcercuei 0:03b5121a232e 22163 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 22164 "re-allocating an array of IDC node-table items", NULL);
pcercuei 0:03b5121a232e 22165 return(-1);
pcercuei 0:03b5121a232e 22166 }
pcercuei 0:03b5121a232e 22167 }
pcercuei 0:03b5121a232e 22168 bind->nodeTable[bind->nbNodes++] = ntItem;
pcercuei 0:03b5121a232e 22169 return(0);
pcercuei 0:03b5121a232e 22170 }
pcercuei 0:03b5121a232e 22171
pcercuei 0:03b5121a232e 22172 /**
pcercuei 0:03b5121a232e 22173 * xmlSchemaIDCAcquireBinding:
pcercuei 0:03b5121a232e 22174 * @vctxt: the WXS validation context
pcercuei 0:03b5121a232e 22175 * @matcher: the IDC matcher
pcercuei 0:03b5121a232e 22176 *
pcercuei 0:03b5121a232e 22177 * Looks up an PSVI IDC binding, for the IDC definition and
pcercuei 0:03b5121a232e 22178 * of the given matcher. If none found, a new one is created
pcercuei 0:03b5121a232e 22179 * and added to the IDC table.
pcercuei 0:03b5121a232e 22180 *
pcercuei 0:03b5121a232e 22181 * Returns an IDC binding or NULL on internal errors.
pcercuei 0:03b5121a232e 22182 */
pcercuei 0:03b5121a232e 22183 static xmlSchemaPSVIIDCBindingPtr
pcercuei 0:03b5121a232e 22184 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 22185 xmlSchemaIDCMatcherPtr matcher)
pcercuei 0:03b5121a232e 22186 {
pcercuei 0:03b5121a232e 22187 xmlSchemaNodeInfoPtr ielem;
pcercuei 0:03b5121a232e 22188
pcercuei 0:03b5121a232e 22189 ielem = vctxt->elemInfos[matcher->depth];
pcercuei 0:03b5121a232e 22190
pcercuei 0:03b5121a232e 22191 if (ielem->idcTable == NULL) {
pcercuei 0:03b5121a232e 22192 ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
pcercuei 0:03b5121a232e 22193 if (ielem->idcTable == NULL)
pcercuei 0:03b5121a232e 22194 return (NULL);
pcercuei 0:03b5121a232e 22195 return(ielem->idcTable);
pcercuei 0:03b5121a232e 22196 } else {
pcercuei 0:03b5121a232e 22197 xmlSchemaPSVIIDCBindingPtr bind = NULL;
pcercuei 0:03b5121a232e 22198
pcercuei 0:03b5121a232e 22199 bind = ielem->idcTable;
pcercuei 0:03b5121a232e 22200 do {
pcercuei 0:03b5121a232e 22201 if (bind->definition == matcher->aidc->def)
pcercuei 0:03b5121a232e 22202 return(bind);
pcercuei 0:03b5121a232e 22203 if (bind->next == NULL) {
pcercuei 0:03b5121a232e 22204 bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
pcercuei 0:03b5121a232e 22205 if (bind->next == NULL)
pcercuei 0:03b5121a232e 22206 return (NULL);
pcercuei 0:03b5121a232e 22207 return(bind->next);
pcercuei 0:03b5121a232e 22208 }
pcercuei 0:03b5121a232e 22209 bind = bind->next;
pcercuei 0:03b5121a232e 22210 } while (bind != NULL);
pcercuei 0:03b5121a232e 22211 }
pcercuei 0:03b5121a232e 22212 return (NULL);
pcercuei 0:03b5121a232e 22213 }
pcercuei 0:03b5121a232e 22214
pcercuei 0:03b5121a232e 22215 static xmlSchemaItemListPtr
pcercuei 0:03b5121a232e 22216 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 22217 xmlSchemaIDCMatcherPtr matcher)
pcercuei 0:03b5121a232e 22218 {
pcercuei 0:03b5121a232e 22219 if (matcher->targets == NULL)
pcercuei 0:03b5121a232e 22220 matcher->targets = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 22221 return(matcher->targets);
pcercuei 0:03b5121a232e 22222 }
pcercuei 0:03b5121a232e 22223
pcercuei 0:03b5121a232e 22224 /**
pcercuei 0:03b5121a232e 22225 * xmlSchemaIDCFreeKey:
pcercuei 0:03b5121a232e 22226 * @key: the IDC key
pcercuei 0:03b5121a232e 22227 *
pcercuei 0:03b5121a232e 22228 * Frees an IDC key together with its compiled value.
pcercuei 0:03b5121a232e 22229 */
pcercuei 0:03b5121a232e 22230 static void
pcercuei 0:03b5121a232e 22231 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
pcercuei 0:03b5121a232e 22232 {
pcercuei 0:03b5121a232e 22233 if (key->val != NULL)
pcercuei 0:03b5121a232e 22234 xmlSchemaFreeValue(key->val);
pcercuei 0:03b5121a232e 22235 xmlFree(key);
pcercuei 0:03b5121a232e 22236 }
pcercuei 0:03b5121a232e 22237
pcercuei 0:03b5121a232e 22238 /**
pcercuei 0:03b5121a232e 22239 * xmlSchemaIDCFreeBinding:
pcercuei 0:03b5121a232e 22240 *
pcercuei 0:03b5121a232e 22241 * Frees an IDC binding. Note that the node table-items
pcercuei 0:03b5121a232e 22242 * are not freed.
pcercuei 0:03b5121a232e 22243 */
pcercuei 0:03b5121a232e 22244 static void
pcercuei 0:03b5121a232e 22245 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
pcercuei 0:03b5121a232e 22246 {
pcercuei 0:03b5121a232e 22247 if (bind->nodeTable != NULL)
pcercuei 0:03b5121a232e 22248 xmlFree(bind->nodeTable);
pcercuei 0:03b5121a232e 22249 if (bind->dupls != NULL)
pcercuei 0:03b5121a232e 22250 xmlSchemaItemListFree(bind->dupls);
pcercuei 0:03b5121a232e 22251 xmlFree(bind);
pcercuei 0:03b5121a232e 22252 }
pcercuei 0:03b5121a232e 22253
pcercuei 0:03b5121a232e 22254 /**
pcercuei 0:03b5121a232e 22255 * xmlSchemaIDCFreeIDCTable:
pcercuei 0:03b5121a232e 22256 * @bind: the first IDC binding in the list
pcercuei 0:03b5121a232e 22257 *
pcercuei 0:03b5121a232e 22258 * Frees an IDC table, i.e. all the IDC bindings in the list.
pcercuei 0:03b5121a232e 22259 */
pcercuei 0:03b5121a232e 22260 static void
pcercuei 0:03b5121a232e 22261 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
pcercuei 0:03b5121a232e 22262 {
pcercuei 0:03b5121a232e 22263 xmlSchemaPSVIIDCBindingPtr prev;
pcercuei 0:03b5121a232e 22264
pcercuei 0:03b5121a232e 22265 while (bind != NULL) {
pcercuei 0:03b5121a232e 22266 prev = bind;
pcercuei 0:03b5121a232e 22267 bind = bind->next;
pcercuei 0:03b5121a232e 22268 xmlSchemaIDCFreeBinding(prev);
pcercuei 0:03b5121a232e 22269 }
pcercuei 0:03b5121a232e 22270 }
pcercuei 0:03b5121a232e 22271
pcercuei 0:03b5121a232e 22272 /**
pcercuei 0:03b5121a232e 22273 * xmlSchemaIDCFreeMatcherList:
pcercuei 0:03b5121a232e 22274 * @matcher: the first IDC matcher in the list
pcercuei 0:03b5121a232e 22275 *
pcercuei 0:03b5121a232e 22276 * Frees a list of IDC matchers.
pcercuei 0:03b5121a232e 22277 */
pcercuei 0:03b5121a232e 22278 static void
pcercuei 0:03b5121a232e 22279 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
pcercuei 0:03b5121a232e 22280 {
pcercuei 0:03b5121a232e 22281 xmlSchemaIDCMatcherPtr next;
pcercuei 0:03b5121a232e 22282
pcercuei 0:03b5121a232e 22283 while (matcher != NULL) {
pcercuei 0:03b5121a232e 22284 next = matcher->next;
pcercuei 0:03b5121a232e 22285 if (matcher->keySeqs != NULL) {
pcercuei 0:03b5121a232e 22286 int i;
pcercuei 0:03b5121a232e 22287 for (i = 0; i < matcher->sizeKeySeqs; i++)
pcercuei 0:03b5121a232e 22288 if (matcher->keySeqs[i] != NULL)
pcercuei 0:03b5121a232e 22289 xmlFree(matcher->keySeqs[i]);
pcercuei 0:03b5121a232e 22290 xmlFree(matcher->keySeqs);
pcercuei 0:03b5121a232e 22291 }
pcercuei 0:03b5121a232e 22292 if (matcher->targets != NULL) {
pcercuei 0:03b5121a232e 22293 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
pcercuei 0:03b5121a232e 22294 int i;
pcercuei 0:03b5121a232e 22295 xmlSchemaPSVIIDCNodePtr idcNode;
pcercuei 0:03b5121a232e 22296 /*
pcercuei 0:03b5121a232e 22297 * Node-table items for keyrefs are not stored globally
pcercuei 0:03b5121a232e 22298 * to the validation context, since they are not bubbled.
pcercuei 0:03b5121a232e 22299 * We need to free them here.
pcercuei 0:03b5121a232e 22300 */
pcercuei 0:03b5121a232e 22301 for (i = 0; i < matcher->targets->nbItems; i++) {
pcercuei 0:03b5121a232e 22302 idcNode =
pcercuei 0:03b5121a232e 22303 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
pcercuei 0:03b5121a232e 22304 xmlFree(idcNode->keys);
pcercuei 0:03b5121a232e 22305 xmlFree(idcNode);
pcercuei 0:03b5121a232e 22306 }
pcercuei 0:03b5121a232e 22307 }
pcercuei 0:03b5121a232e 22308 xmlSchemaItemListFree(matcher->targets);
pcercuei 0:03b5121a232e 22309 }
pcercuei 0:03b5121a232e 22310 xmlFree(matcher);
pcercuei 0:03b5121a232e 22311 matcher = next;
pcercuei 0:03b5121a232e 22312 }
pcercuei 0:03b5121a232e 22313 }
pcercuei 0:03b5121a232e 22314
pcercuei 0:03b5121a232e 22315 /**
pcercuei 0:03b5121a232e 22316 * xmlSchemaIDCReleaseMatcherList:
pcercuei 0:03b5121a232e 22317 * @vctxt: the WXS validation context
pcercuei 0:03b5121a232e 22318 * @matcher: the first IDC matcher in the list
pcercuei 0:03b5121a232e 22319 *
pcercuei 0:03b5121a232e 22320 * Caches a list of IDC matchers for reuse.
pcercuei 0:03b5121a232e 22321 */
pcercuei 0:03b5121a232e 22322 static void
pcercuei 0:03b5121a232e 22323 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 22324 xmlSchemaIDCMatcherPtr matcher)
pcercuei 0:03b5121a232e 22325 {
pcercuei 0:03b5121a232e 22326 xmlSchemaIDCMatcherPtr next;
pcercuei 0:03b5121a232e 22327
pcercuei 0:03b5121a232e 22328 while (matcher != NULL) {
pcercuei 0:03b5121a232e 22329 next = matcher->next;
pcercuei 0:03b5121a232e 22330 if (matcher->keySeqs != NULL) {
pcercuei 0:03b5121a232e 22331 int i;
pcercuei 0:03b5121a232e 22332 /*
pcercuei 0:03b5121a232e 22333 * Don't free the array, but only the content.
pcercuei 0:03b5121a232e 22334 */
pcercuei 0:03b5121a232e 22335 for (i = 0; i < matcher->sizeKeySeqs; i++)
pcercuei 0:03b5121a232e 22336 if (matcher->keySeqs[i] != NULL) {
pcercuei 0:03b5121a232e 22337 xmlFree(matcher->keySeqs[i]);
pcercuei 0:03b5121a232e 22338 matcher->keySeqs[i] = NULL;
pcercuei 0:03b5121a232e 22339 }
pcercuei 0:03b5121a232e 22340 }
pcercuei 0:03b5121a232e 22341 if (matcher->targets) {
pcercuei 0:03b5121a232e 22342 if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
pcercuei 0:03b5121a232e 22343 int i;
pcercuei 0:03b5121a232e 22344 xmlSchemaPSVIIDCNodePtr idcNode;
pcercuei 0:03b5121a232e 22345 /*
pcercuei 0:03b5121a232e 22346 * Node-table items for keyrefs are not stored globally
pcercuei 0:03b5121a232e 22347 * to the validation context, since they are not bubbled.
pcercuei 0:03b5121a232e 22348 * We need to free them here.
pcercuei 0:03b5121a232e 22349 */
pcercuei 0:03b5121a232e 22350 for (i = 0; i < matcher->targets->nbItems; i++) {
pcercuei 0:03b5121a232e 22351 idcNode =
pcercuei 0:03b5121a232e 22352 (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
pcercuei 0:03b5121a232e 22353 xmlFree(idcNode->keys);
pcercuei 0:03b5121a232e 22354 xmlFree(idcNode);
pcercuei 0:03b5121a232e 22355 }
pcercuei 0:03b5121a232e 22356 }
pcercuei 0:03b5121a232e 22357 xmlSchemaItemListFree(matcher->targets);
pcercuei 0:03b5121a232e 22358 matcher->targets = NULL;
pcercuei 0:03b5121a232e 22359 }
pcercuei 0:03b5121a232e 22360 matcher->next = NULL;
pcercuei 0:03b5121a232e 22361 /*
pcercuei 0:03b5121a232e 22362 * Cache the matcher.
pcercuei 0:03b5121a232e 22363 */
pcercuei 0:03b5121a232e 22364 if (vctxt->idcMatcherCache != NULL)
pcercuei 0:03b5121a232e 22365 matcher->nextCached = vctxt->idcMatcherCache;
pcercuei 0:03b5121a232e 22366 vctxt->idcMatcherCache = matcher;
pcercuei 0:03b5121a232e 22367
pcercuei 0:03b5121a232e 22368 matcher = next;
pcercuei 0:03b5121a232e 22369 }
pcercuei 0:03b5121a232e 22370 }
pcercuei 0:03b5121a232e 22371
pcercuei 0:03b5121a232e 22372 /**
pcercuei 0:03b5121a232e 22373 * xmlSchemaIDCAddStateObject:
pcercuei 0:03b5121a232e 22374 * @vctxt: the WXS validation context
pcercuei 0:03b5121a232e 22375 * @matcher: the IDC matcher
pcercuei 0:03b5121a232e 22376 * @sel: the XPath information
pcercuei 0:03b5121a232e 22377 * @parent: the parent "selector" state object if any
pcercuei 0:03b5121a232e 22378 * @type: "selector" or "field"
pcercuei 0:03b5121a232e 22379 *
pcercuei 0:03b5121a232e 22380 * Creates/reuses and activates state objects for the given
pcercuei 0:03b5121a232e 22381 * XPath information; if the XPath expression consists of unions,
pcercuei 0:03b5121a232e 22382 * multiple state objects are created for every unioned expression.
pcercuei 0:03b5121a232e 22383 *
pcercuei 0:03b5121a232e 22384 * Returns 0 on success and -1 on internal errors.
pcercuei 0:03b5121a232e 22385 */
pcercuei 0:03b5121a232e 22386 static int
pcercuei 0:03b5121a232e 22387 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 22388 xmlSchemaIDCMatcherPtr matcher,
pcercuei 0:03b5121a232e 22389 xmlSchemaIDCSelectPtr sel,
pcercuei 0:03b5121a232e 22390 int type)
pcercuei 0:03b5121a232e 22391 {
pcercuei 0:03b5121a232e 22392 xmlSchemaIDCStateObjPtr sto;
pcercuei 0:03b5121a232e 22393
pcercuei 0:03b5121a232e 22394 /*
pcercuei 0:03b5121a232e 22395 * Reuse the state objects from the pool.
pcercuei 0:03b5121a232e 22396 */
pcercuei 0:03b5121a232e 22397 if (vctxt->xpathStatePool != NULL) {
pcercuei 0:03b5121a232e 22398 sto = vctxt->xpathStatePool;
pcercuei 0:03b5121a232e 22399 vctxt->xpathStatePool = sto->next;
pcercuei 0:03b5121a232e 22400 sto->next = NULL;
pcercuei 0:03b5121a232e 22401 } else {
pcercuei 0:03b5121a232e 22402 /*
pcercuei 0:03b5121a232e 22403 * Create a new state object.
pcercuei 0:03b5121a232e 22404 */
pcercuei 0:03b5121a232e 22405 sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
pcercuei 0:03b5121a232e 22406 if (sto == NULL) {
pcercuei 0:03b5121a232e 22407 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 22408 "allocating an IDC state object", NULL);
pcercuei 0:03b5121a232e 22409 return (-1);
pcercuei 0:03b5121a232e 22410 }
pcercuei 0:03b5121a232e 22411 memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
pcercuei 0:03b5121a232e 22412 }
pcercuei 0:03b5121a232e 22413 /*
pcercuei 0:03b5121a232e 22414 * Add to global list.
pcercuei 0:03b5121a232e 22415 */
pcercuei 0:03b5121a232e 22416 if (vctxt->xpathStates != NULL)
pcercuei 0:03b5121a232e 22417 sto->next = vctxt->xpathStates;
pcercuei 0:03b5121a232e 22418 vctxt->xpathStates = sto;
pcercuei 0:03b5121a232e 22419
pcercuei 0:03b5121a232e 22420 /*
pcercuei 0:03b5121a232e 22421 * Free the old xpath validation context.
pcercuei 0:03b5121a232e 22422 */
pcercuei 0:03b5121a232e 22423 if (sto->xpathCtxt != NULL)
pcercuei 0:03b5121a232e 22424 xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
pcercuei 0:03b5121a232e 22425
pcercuei 0:03b5121a232e 22426 /*
pcercuei 0:03b5121a232e 22427 * Create a new XPath (pattern) validation context.
pcercuei 0:03b5121a232e 22428 */
pcercuei 0:03b5121a232e 22429 sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
pcercuei 0:03b5121a232e 22430 (xmlPatternPtr) sel->xpathComp);
pcercuei 0:03b5121a232e 22431 if (sto->xpathCtxt == NULL) {
pcercuei 0:03b5121a232e 22432 VERROR_INT("xmlSchemaIDCAddStateObject",
pcercuei 0:03b5121a232e 22433 "failed to create an XPath validation context");
pcercuei 0:03b5121a232e 22434 return (-1);
pcercuei 0:03b5121a232e 22435 }
pcercuei 0:03b5121a232e 22436 sto->type = type;
pcercuei 0:03b5121a232e 22437 sto->depth = vctxt->depth;
pcercuei 0:03b5121a232e 22438 sto->matcher = matcher;
pcercuei 0:03b5121a232e 22439 sto->sel = sel;
pcercuei 0:03b5121a232e 22440 sto->nbHistory = 0;
pcercuei 0:03b5121a232e 22441
pcercuei 0:03b5121a232e 22442 #ifdef DEBUG_IDC
pcercuei 0:03b5121a232e 22443 xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n",
pcercuei 0:03b5121a232e 22444 sto->sel->xpath);
pcercuei 0:03b5121a232e 22445 #endif
pcercuei 0:03b5121a232e 22446 return (0);
pcercuei 0:03b5121a232e 22447 }
pcercuei 0:03b5121a232e 22448
pcercuei 0:03b5121a232e 22449 /**
pcercuei 0:03b5121a232e 22450 * xmlSchemaXPathEvaluate:
pcercuei 0:03b5121a232e 22451 * @vctxt: the WXS validation context
pcercuei 0:03b5121a232e 22452 * @nodeType: the nodeType of the current node
pcercuei 0:03b5121a232e 22453 *
pcercuei 0:03b5121a232e 22454 * Evaluates all active XPath state objects.
pcercuei 0:03b5121a232e 22455 *
pcercuei 0:03b5121a232e 22456 * Returns the number of IC "field" state objects which resolved to
pcercuei 0:03b5121a232e 22457 * this node, 0 if none resolved and -1 on internal errors.
pcercuei 0:03b5121a232e 22458 */
pcercuei 0:03b5121a232e 22459 static int
pcercuei 0:03b5121a232e 22460 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 22461 xmlElementType nodeType)
pcercuei 0:03b5121a232e 22462 {
pcercuei 0:03b5121a232e 22463 xmlSchemaIDCStateObjPtr sto, head = NULL, first;
pcercuei 0:03b5121a232e 22464 int res, resolved = 0, depth = vctxt->depth;
pcercuei 0:03b5121a232e 22465
pcercuei 0:03b5121a232e 22466 if (vctxt->xpathStates == NULL)
pcercuei 0:03b5121a232e 22467 return (0);
pcercuei 0:03b5121a232e 22468
pcercuei 0:03b5121a232e 22469 if (nodeType == XML_ATTRIBUTE_NODE)
pcercuei 0:03b5121a232e 22470 depth++;
pcercuei 0:03b5121a232e 22471 #ifdef DEBUG_IDC
pcercuei 0:03b5121a232e 22472 {
pcercuei 0:03b5121a232e 22473 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 22474 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 22475 "IDC: EVAL on %s, depth %d, type %d\n",
pcercuei 0:03b5121a232e 22476 xmlSchemaFormatQName(&str, vctxt->inode->nsName,
pcercuei 0:03b5121a232e 22477 vctxt->inode->localName), depth, nodeType);
pcercuei 0:03b5121a232e 22478 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 22479 }
pcercuei 0:03b5121a232e 22480 #endif
pcercuei 0:03b5121a232e 22481 /*
pcercuei 0:03b5121a232e 22482 * Process all active XPath state objects.
pcercuei 0:03b5121a232e 22483 */
pcercuei 0:03b5121a232e 22484 first = vctxt->xpathStates;
pcercuei 0:03b5121a232e 22485 sto = first;
pcercuei 0:03b5121a232e 22486 while (sto != head) {
pcercuei 0:03b5121a232e 22487 #ifdef DEBUG_IDC
pcercuei 0:03b5121a232e 22488 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
pcercuei 0:03b5121a232e 22489 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n",
pcercuei 0:03b5121a232e 22490 sto->matcher->aidc->def->name, sto->sel->xpath);
pcercuei 0:03b5121a232e 22491 else
pcercuei 0:03b5121a232e 22492 xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n",
pcercuei 0:03b5121a232e 22493 sto->matcher->aidc->def->name, sto->sel->xpath);
pcercuei 0:03b5121a232e 22494 #endif
pcercuei 0:03b5121a232e 22495 if (nodeType == XML_ELEMENT_NODE)
pcercuei 0:03b5121a232e 22496 res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
pcercuei 0:03b5121a232e 22497 vctxt->inode->localName, vctxt->inode->nsName);
pcercuei 0:03b5121a232e 22498 else
pcercuei 0:03b5121a232e 22499 res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
pcercuei 0:03b5121a232e 22500 vctxt->inode->localName, vctxt->inode->nsName);
pcercuei 0:03b5121a232e 22501
pcercuei 0:03b5121a232e 22502 if (res == -1) {
pcercuei 0:03b5121a232e 22503 VERROR_INT("xmlSchemaXPathEvaluate",
pcercuei 0:03b5121a232e 22504 "calling xmlStreamPush()");
pcercuei 0:03b5121a232e 22505 return (-1);
pcercuei 0:03b5121a232e 22506 }
pcercuei 0:03b5121a232e 22507 if (res == 0)
pcercuei 0:03b5121a232e 22508 goto next_sto;
pcercuei 0:03b5121a232e 22509 /*
pcercuei 0:03b5121a232e 22510 * Full match.
pcercuei 0:03b5121a232e 22511 */
pcercuei 0:03b5121a232e 22512 #ifdef DEBUG_IDC
pcercuei 0:03b5121a232e 22513 xmlGenericError(xmlGenericErrorContext, "IDC: "
pcercuei 0:03b5121a232e 22514 "MATCH\n");
pcercuei 0:03b5121a232e 22515 #endif
pcercuei 0:03b5121a232e 22516 /*
pcercuei 0:03b5121a232e 22517 * Register a match in the state object history.
pcercuei 0:03b5121a232e 22518 */
pcercuei 0:03b5121a232e 22519 if (sto->history == NULL) {
pcercuei 0:03b5121a232e 22520 sto->history = (int *) xmlMalloc(5 * sizeof(int));
pcercuei 0:03b5121a232e 22521 if (sto->history == NULL) {
pcercuei 0:03b5121a232e 22522 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 22523 "allocating the state object history", NULL);
pcercuei 0:03b5121a232e 22524 return(-1);
pcercuei 0:03b5121a232e 22525 }
pcercuei 0:03b5121a232e 22526 sto->sizeHistory = 5;
pcercuei 0:03b5121a232e 22527 } else if (sto->sizeHistory <= sto->nbHistory) {
pcercuei 0:03b5121a232e 22528 sto->sizeHistory *= 2;
pcercuei 0:03b5121a232e 22529 sto->history = (int *) xmlRealloc(sto->history,
pcercuei 0:03b5121a232e 22530 sto->sizeHistory * sizeof(int));
pcercuei 0:03b5121a232e 22531 if (sto->history == NULL) {
pcercuei 0:03b5121a232e 22532 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 22533 "re-allocating the state object history", NULL);
pcercuei 0:03b5121a232e 22534 return(-1);
pcercuei 0:03b5121a232e 22535 }
pcercuei 0:03b5121a232e 22536 }
pcercuei 0:03b5121a232e 22537 sto->history[sto->nbHistory++] = depth;
pcercuei 0:03b5121a232e 22538
pcercuei 0:03b5121a232e 22539 #ifdef DEBUG_IDC
pcercuei 0:03b5121a232e 22540 xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n",
pcercuei 0:03b5121a232e 22541 vctxt->depth);
pcercuei 0:03b5121a232e 22542 #endif
pcercuei 0:03b5121a232e 22543
pcercuei 0:03b5121a232e 22544 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
pcercuei 0:03b5121a232e 22545 xmlSchemaIDCSelectPtr sel;
pcercuei 0:03b5121a232e 22546 /*
pcercuei 0:03b5121a232e 22547 * Activate state objects for the IDC fields of
pcercuei 0:03b5121a232e 22548 * the IDC selector.
pcercuei 0:03b5121a232e 22549 */
pcercuei 0:03b5121a232e 22550 #ifdef DEBUG_IDC
pcercuei 0:03b5121a232e 22551 xmlGenericError(xmlGenericErrorContext, "IDC: "
pcercuei 0:03b5121a232e 22552 "activating field states\n");
pcercuei 0:03b5121a232e 22553 #endif
pcercuei 0:03b5121a232e 22554 sel = sto->matcher->aidc->def->fields;
pcercuei 0:03b5121a232e 22555 while (sel != NULL) {
pcercuei 0:03b5121a232e 22556 if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
pcercuei 0:03b5121a232e 22557 sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
pcercuei 0:03b5121a232e 22558 return (-1);
pcercuei 0:03b5121a232e 22559 sel = sel->next;
pcercuei 0:03b5121a232e 22560 }
pcercuei 0:03b5121a232e 22561 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
pcercuei 0:03b5121a232e 22562 /*
pcercuei 0:03b5121a232e 22563 * An IDC key node was found by the IDC field.
pcercuei 0:03b5121a232e 22564 */
pcercuei 0:03b5121a232e 22565 #ifdef DEBUG_IDC
pcercuei 0:03b5121a232e 22566 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 22567 "IDC: key found\n");
pcercuei 0:03b5121a232e 22568 #endif
pcercuei 0:03b5121a232e 22569 /*
pcercuei 0:03b5121a232e 22570 * Notify that the character value of this node is
pcercuei 0:03b5121a232e 22571 * needed.
pcercuei 0:03b5121a232e 22572 */
pcercuei 0:03b5121a232e 22573 if (resolved == 0) {
pcercuei 0:03b5121a232e 22574 if ((vctxt->inode->flags &
pcercuei 0:03b5121a232e 22575 XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
pcercuei 0:03b5121a232e 22576 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
pcercuei 0:03b5121a232e 22577 }
pcercuei 0:03b5121a232e 22578 resolved++;
pcercuei 0:03b5121a232e 22579 }
pcercuei 0:03b5121a232e 22580 next_sto:
pcercuei 0:03b5121a232e 22581 if (sto->next == NULL) {
pcercuei 0:03b5121a232e 22582 /*
pcercuei 0:03b5121a232e 22583 * Evaluate field state objects created on this node as well.
pcercuei 0:03b5121a232e 22584 */
pcercuei 0:03b5121a232e 22585 head = first;
pcercuei 0:03b5121a232e 22586 sto = vctxt->xpathStates;
pcercuei 0:03b5121a232e 22587 } else
pcercuei 0:03b5121a232e 22588 sto = sto->next;
pcercuei 0:03b5121a232e 22589 }
pcercuei 0:03b5121a232e 22590 return (resolved);
pcercuei 0:03b5121a232e 22591 }
pcercuei 0:03b5121a232e 22592
pcercuei 0:03b5121a232e 22593 static const xmlChar *
pcercuei 0:03b5121a232e 22594 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 22595 xmlChar **buf,
pcercuei 0:03b5121a232e 22596 xmlSchemaPSVIIDCKeyPtr *seq,
pcercuei 0:03b5121a232e 22597 int count)
pcercuei 0:03b5121a232e 22598 {
pcercuei 0:03b5121a232e 22599 int i, res;
pcercuei 0:03b5121a232e 22600 xmlChar *value = NULL;
pcercuei 0:03b5121a232e 22601
pcercuei 0:03b5121a232e 22602 *buf = xmlStrdup(BAD_CAST "[");
pcercuei 0:03b5121a232e 22603 for (i = 0; i < count; i++) {
pcercuei 0:03b5121a232e 22604 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 22605 res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
pcercuei 0:03b5121a232e 22606 xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
pcercuei 0:03b5121a232e 22607 &value);
pcercuei 0:03b5121a232e 22608 if (res == 0)
pcercuei 0:03b5121a232e 22609 *buf = xmlStrcat(*buf, BAD_CAST value);
pcercuei 0:03b5121a232e 22610 else {
pcercuei 0:03b5121a232e 22611 VERROR_INT("xmlSchemaFormatIDCKeySequence",
pcercuei 0:03b5121a232e 22612 "failed to compute a canonical value");
pcercuei 0:03b5121a232e 22613 *buf = xmlStrcat(*buf, BAD_CAST "???");
pcercuei 0:03b5121a232e 22614 }
pcercuei 0:03b5121a232e 22615 if (i < count -1)
pcercuei 0:03b5121a232e 22616 *buf = xmlStrcat(*buf, BAD_CAST "', ");
pcercuei 0:03b5121a232e 22617 else
pcercuei 0:03b5121a232e 22618 *buf = xmlStrcat(*buf, BAD_CAST "'");
pcercuei 0:03b5121a232e 22619 if (value != NULL) {
pcercuei 0:03b5121a232e 22620 xmlFree(value);
pcercuei 0:03b5121a232e 22621 value = NULL;
pcercuei 0:03b5121a232e 22622 }
pcercuei 0:03b5121a232e 22623 }
pcercuei 0:03b5121a232e 22624 *buf = xmlStrcat(*buf, BAD_CAST "]");
pcercuei 0:03b5121a232e 22625
pcercuei 0:03b5121a232e 22626 return (BAD_CAST *buf);
pcercuei 0:03b5121a232e 22627 }
pcercuei 0:03b5121a232e 22628
pcercuei 0:03b5121a232e 22629 /**
pcercuei 0:03b5121a232e 22630 * xmlSchemaXPathPop:
pcercuei 0:03b5121a232e 22631 * @vctxt: the WXS validation context
pcercuei 0:03b5121a232e 22632 *
pcercuei 0:03b5121a232e 22633 * Pops all XPath states.
pcercuei 0:03b5121a232e 22634 *
pcercuei 0:03b5121a232e 22635 * Returns 0 on success and -1 on internal errors.
pcercuei 0:03b5121a232e 22636 */
pcercuei 0:03b5121a232e 22637 static int
pcercuei 0:03b5121a232e 22638 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 22639 {
pcercuei 0:03b5121a232e 22640 xmlSchemaIDCStateObjPtr sto;
pcercuei 0:03b5121a232e 22641 int res;
pcercuei 0:03b5121a232e 22642
pcercuei 0:03b5121a232e 22643 if (vctxt->xpathStates == NULL)
pcercuei 0:03b5121a232e 22644 return(0);
pcercuei 0:03b5121a232e 22645 sto = vctxt->xpathStates;
pcercuei 0:03b5121a232e 22646 do {
pcercuei 0:03b5121a232e 22647 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
pcercuei 0:03b5121a232e 22648 if (res == -1)
pcercuei 0:03b5121a232e 22649 return (-1);
pcercuei 0:03b5121a232e 22650 sto = sto->next;
pcercuei 0:03b5121a232e 22651 } while (sto != NULL);
pcercuei 0:03b5121a232e 22652 return(0);
pcercuei 0:03b5121a232e 22653 }
pcercuei 0:03b5121a232e 22654
pcercuei 0:03b5121a232e 22655 /**
pcercuei 0:03b5121a232e 22656 * xmlSchemaXPathProcessHistory:
pcercuei 0:03b5121a232e 22657 * @vctxt: the WXS validation context
pcercuei 0:03b5121a232e 22658 * @type: the simple/complex type of the current node if any at all
pcercuei 0:03b5121a232e 22659 * @val: the precompiled value
pcercuei 0:03b5121a232e 22660 *
pcercuei 0:03b5121a232e 22661 * Processes and pops the history items of the IDC state objects.
pcercuei 0:03b5121a232e 22662 * IDC key-sequences are validated/created on IDC bindings.
pcercuei 0:03b5121a232e 22663 *
pcercuei 0:03b5121a232e 22664 * Returns 0 on success and -1 on internal errors.
pcercuei 0:03b5121a232e 22665 */
pcercuei 0:03b5121a232e 22666 static int
pcercuei 0:03b5121a232e 22667 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 22668 int depth)
pcercuei 0:03b5121a232e 22669 {
pcercuei 0:03b5121a232e 22670 xmlSchemaIDCStateObjPtr sto, nextsto;
pcercuei 0:03b5121a232e 22671 int res, matchDepth;
pcercuei 0:03b5121a232e 22672 xmlSchemaPSVIIDCKeyPtr key = NULL;
pcercuei 0:03b5121a232e 22673 xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
pcercuei 0:03b5121a232e 22674
pcercuei 0:03b5121a232e 22675 if (vctxt->xpathStates == NULL)
pcercuei 0:03b5121a232e 22676 return (0);
pcercuei 0:03b5121a232e 22677 sto = vctxt->xpathStates;
pcercuei 0:03b5121a232e 22678
pcercuei 0:03b5121a232e 22679 #ifdef DEBUG_IDC
pcercuei 0:03b5121a232e 22680 {
pcercuei 0:03b5121a232e 22681 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 22682 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 22683 "IDC: BACK on %s, depth %d\n",
pcercuei 0:03b5121a232e 22684 xmlSchemaFormatQName(&str, vctxt->inode->nsName,
pcercuei 0:03b5121a232e 22685 vctxt->inode->localName), vctxt->depth);
pcercuei 0:03b5121a232e 22686 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 22687 }
pcercuei 0:03b5121a232e 22688 #endif
pcercuei 0:03b5121a232e 22689 /*
pcercuei 0:03b5121a232e 22690 * Evaluate the state objects.
pcercuei 0:03b5121a232e 22691 */
pcercuei 0:03b5121a232e 22692 while (sto != NULL) {
pcercuei 0:03b5121a232e 22693 res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
pcercuei 0:03b5121a232e 22694 if (res == -1) {
pcercuei 0:03b5121a232e 22695 VERROR_INT("xmlSchemaXPathProcessHistory",
pcercuei 0:03b5121a232e 22696 "calling xmlStreamPop()");
pcercuei 0:03b5121a232e 22697 return (-1);
pcercuei 0:03b5121a232e 22698 }
pcercuei 0:03b5121a232e 22699 #ifdef DEBUG_IDC
pcercuei 0:03b5121a232e 22700 xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n",
pcercuei 0:03b5121a232e 22701 sto->sel->xpath);
pcercuei 0:03b5121a232e 22702 #endif
pcercuei 0:03b5121a232e 22703 if (sto->nbHistory == 0)
pcercuei 0:03b5121a232e 22704 goto deregister_check;
pcercuei 0:03b5121a232e 22705
pcercuei 0:03b5121a232e 22706 matchDepth = sto->history[sto->nbHistory -1];
pcercuei 0:03b5121a232e 22707
pcercuei 0:03b5121a232e 22708 /*
pcercuei 0:03b5121a232e 22709 * Only matches at the current depth are of interest.
pcercuei 0:03b5121a232e 22710 */
pcercuei 0:03b5121a232e 22711 if (matchDepth != depth) {
pcercuei 0:03b5121a232e 22712 sto = sto->next;
pcercuei 0:03b5121a232e 22713 continue;
pcercuei 0:03b5121a232e 22714 }
pcercuei 0:03b5121a232e 22715 if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
pcercuei 0:03b5121a232e 22716 /*
pcercuei 0:03b5121a232e 22717 * NOTE: According to
pcercuei 0:03b5121a232e 22718 * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
pcercuei 0:03b5121a232e 22719 * ... the simple-content of complex types is also allowed.
pcercuei 0:03b5121a232e 22720 */
pcercuei 0:03b5121a232e 22721
pcercuei 0:03b5121a232e 22722 if (WXS_IS_COMPLEX(type)) {
pcercuei 0:03b5121a232e 22723 if (WXS_HAS_SIMPLE_CONTENT(type)) {
pcercuei 0:03b5121a232e 22724 /*
pcercuei 0:03b5121a232e 22725 * Sanity check for complex types with simple content.
pcercuei 0:03b5121a232e 22726 */
pcercuei 0:03b5121a232e 22727 simpleType = type->contentTypeDef;
pcercuei 0:03b5121a232e 22728 if (simpleType == NULL) {
pcercuei 0:03b5121a232e 22729 VERROR_INT("xmlSchemaXPathProcessHistory",
pcercuei 0:03b5121a232e 22730 "field resolves to a CT with simple content "
pcercuei 0:03b5121a232e 22731 "but the CT is missing the ST definition");
pcercuei 0:03b5121a232e 22732 return (-1);
pcercuei 0:03b5121a232e 22733 }
pcercuei 0:03b5121a232e 22734 } else
pcercuei 0:03b5121a232e 22735 simpleType = NULL;
pcercuei 0:03b5121a232e 22736 } else
pcercuei 0:03b5121a232e 22737 simpleType = type;
pcercuei 0:03b5121a232e 22738 if (simpleType == NULL) {
pcercuei 0:03b5121a232e 22739 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 22740
pcercuei 0:03b5121a232e 22741 /*
pcercuei 0:03b5121a232e 22742 * Not qualified if the field resolves to a node of non
pcercuei 0:03b5121a232e 22743 * simple type.
pcercuei 0:03b5121a232e 22744 */
pcercuei 0:03b5121a232e 22745 xmlSchemaCustomErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 22746 XML_SCHEMAV_CVC_IDC, NULL,
pcercuei 0:03b5121a232e 22747 WXS_BASIC_CAST sto->matcher->aidc->def,
pcercuei 0:03b5121a232e 22748 "The XPath '%s' of a field of %s does evaluate to a node of "
pcercuei 0:03b5121a232e 22749 "non-simple type",
pcercuei 0:03b5121a232e 22750 sto->sel->xpath,
pcercuei 0:03b5121a232e 22751 xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
pcercuei 0:03b5121a232e 22752 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 22753 sto->nbHistory--;
pcercuei 0:03b5121a232e 22754 goto deregister_check;
pcercuei 0:03b5121a232e 22755 }
pcercuei 0:03b5121a232e 22756
pcercuei 0:03b5121a232e 22757 if ((key == NULL) && (vctxt->inode->val == NULL)) {
pcercuei 0:03b5121a232e 22758 /*
pcercuei 0:03b5121a232e 22759 * Failed to provide the normalized value; maybe
pcercuei 0:03b5121a232e 22760 * the value was invalid.
pcercuei 0:03b5121a232e 22761 */
pcercuei 0:03b5121a232e 22762 VERROR(XML_SCHEMAV_CVC_IDC,
pcercuei 0:03b5121a232e 22763 WXS_BASIC_CAST sto->matcher->aidc->def,
pcercuei 0:03b5121a232e 22764 "Warning: No precomputed value available, the value "
pcercuei 0:03b5121a232e 22765 "was either invalid or something strange happend");
pcercuei 0:03b5121a232e 22766 sto->nbHistory--;
pcercuei 0:03b5121a232e 22767 goto deregister_check;
pcercuei 0:03b5121a232e 22768 } else {
pcercuei 0:03b5121a232e 22769 xmlSchemaIDCMatcherPtr matcher = sto->matcher;
pcercuei 0:03b5121a232e 22770 xmlSchemaPSVIIDCKeyPtr *keySeq;
pcercuei 0:03b5121a232e 22771 int pos, idx;
pcercuei 0:03b5121a232e 22772
pcercuei 0:03b5121a232e 22773 /*
pcercuei 0:03b5121a232e 22774 * The key will be anchored on the matcher's list of
pcercuei 0:03b5121a232e 22775 * key-sequences. The position in this list is determined
pcercuei 0:03b5121a232e 22776 * by the target node's depth relative to the matcher's
pcercuei 0:03b5121a232e 22777 * depth of creation (i.e. the depth of the scope element).
pcercuei 0:03b5121a232e 22778 *
pcercuei 0:03b5121a232e 22779 * Element Depth Pos List-entries
pcercuei 0:03b5121a232e 22780 * <scope> 0 NULL
pcercuei 0:03b5121a232e 22781 * <bar> 1 NULL
pcercuei 0:03b5121a232e 22782 * <target/> 2 2 target
pcercuei 0:03b5121a232e 22783 * <bar>
pcercuei 0:03b5121a232e 22784 * </scope>
pcercuei 0:03b5121a232e 22785 *
pcercuei 0:03b5121a232e 22786 * The size of the list is only dependant on the depth of
pcercuei 0:03b5121a232e 22787 * the tree.
pcercuei 0:03b5121a232e 22788 * An entry will be NULLed in selector_leave, i.e. when
pcercuei 0:03b5121a232e 22789 * we hit the target's
pcercuei 0:03b5121a232e 22790 */
pcercuei 0:03b5121a232e 22791 pos = sto->depth - matcher->depth;
pcercuei 0:03b5121a232e 22792 idx = sto->sel->index;
pcercuei 0:03b5121a232e 22793
pcercuei 0:03b5121a232e 22794 /*
pcercuei 0:03b5121a232e 22795 * Create/grow the array of key-sequences.
pcercuei 0:03b5121a232e 22796 */
pcercuei 0:03b5121a232e 22797 if (matcher->keySeqs == NULL) {
pcercuei 0:03b5121a232e 22798 if (pos > 9)
pcercuei 0:03b5121a232e 22799 matcher->sizeKeySeqs = pos * 2;
pcercuei 0:03b5121a232e 22800 else
pcercuei 0:03b5121a232e 22801 matcher->sizeKeySeqs = 10;
pcercuei 0:03b5121a232e 22802 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
pcercuei 0:03b5121a232e 22803 xmlMalloc(matcher->sizeKeySeqs *
pcercuei 0:03b5121a232e 22804 sizeof(xmlSchemaPSVIIDCKeyPtr *));
pcercuei 0:03b5121a232e 22805 if (matcher->keySeqs == NULL) {
pcercuei 0:03b5121a232e 22806 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 22807 "allocating an array of key-sequences",
pcercuei 0:03b5121a232e 22808 NULL);
pcercuei 0:03b5121a232e 22809 return(-1);
pcercuei 0:03b5121a232e 22810 }
pcercuei 0:03b5121a232e 22811 memset(matcher->keySeqs, 0,
pcercuei 0:03b5121a232e 22812 matcher->sizeKeySeqs *
pcercuei 0:03b5121a232e 22813 sizeof(xmlSchemaPSVIIDCKeyPtr *));
pcercuei 0:03b5121a232e 22814 } else if (pos >= matcher->sizeKeySeqs) {
pcercuei 0:03b5121a232e 22815 int i = matcher->sizeKeySeqs;
pcercuei 0:03b5121a232e 22816
pcercuei 0:03b5121a232e 22817 matcher->sizeKeySeqs *= 2;
pcercuei 0:03b5121a232e 22818 matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
pcercuei 0:03b5121a232e 22819 xmlRealloc(matcher->keySeqs,
pcercuei 0:03b5121a232e 22820 matcher->sizeKeySeqs *
pcercuei 0:03b5121a232e 22821 sizeof(xmlSchemaPSVIIDCKeyPtr *));
pcercuei 0:03b5121a232e 22822 if (matcher->keySeqs == NULL) {
pcercuei 0:03b5121a232e 22823 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 22824 "reallocating an array of key-sequences",
pcercuei 0:03b5121a232e 22825 NULL);
pcercuei 0:03b5121a232e 22826 return (-1);
pcercuei 0:03b5121a232e 22827 }
pcercuei 0:03b5121a232e 22828 /*
pcercuei 0:03b5121a232e 22829 * The array needs to be NULLed.
pcercuei 0:03b5121a232e 22830 * TODO: Use memset?
pcercuei 0:03b5121a232e 22831 */
pcercuei 0:03b5121a232e 22832 for (; i < matcher->sizeKeySeqs; i++)
pcercuei 0:03b5121a232e 22833 matcher->keySeqs[i] = NULL;
pcercuei 0:03b5121a232e 22834 }
pcercuei 0:03b5121a232e 22835
pcercuei 0:03b5121a232e 22836 /*
pcercuei 0:03b5121a232e 22837 * Get/create the key-sequence.
pcercuei 0:03b5121a232e 22838 */
pcercuei 0:03b5121a232e 22839 keySeq = matcher->keySeqs[pos];
pcercuei 0:03b5121a232e 22840 if (keySeq == NULL) {
pcercuei 0:03b5121a232e 22841 goto create_sequence;
pcercuei 0:03b5121a232e 22842 } else if (keySeq[idx] != NULL) {
pcercuei 0:03b5121a232e 22843 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 22844 /*
pcercuei 0:03b5121a232e 22845 * cvc-identity-constraint:
pcercuei 0:03b5121a232e 22846 * 3 For each node in the `target node set` all
pcercuei 0:03b5121a232e 22847 * of the {fields}, with that node as the context
pcercuei 0:03b5121a232e 22848 * node, evaluate to either an empty node-set or
pcercuei 0:03b5121a232e 22849 * a node-set with exactly one member, which must
pcercuei 0:03b5121a232e 22850 * have a simple type.
pcercuei 0:03b5121a232e 22851 *
pcercuei 0:03b5121a232e 22852 * The key was already set; report an error.
pcercuei 0:03b5121a232e 22853 */
pcercuei 0:03b5121a232e 22854 xmlSchemaCustomErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 22855 XML_SCHEMAV_CVC_IDC, NULL,
pcercuei 0:03b5121a232e 22856 WXS_BASIC_CAST matcher->aidc->def,
pcercuei 0:03b5121a232e 22857 "The XPath '%s' of a field of %s evaluates to a "
pcercuei 0:03b5121a232e 22858 "node-set with more than one member",
pcercuei 0:03b5121a232e 22859 sto->sel->xpath,
pcercuei 0:03b5121a232e 22860 xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
pcercuei 0:03b5121a232e 22861 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 22862 sto->nbHistory--;
pcercuei 0:03b5121a232e 22863 goto deregister_check;
pcercuei 0:03b5121a232e 22864 } else
pcercuei 0:03b5121a232e 22865 goto create_key;
pcercuei 0:03b5121a232e 22866
pcercuei 0:03b5121a232e 22867 create_sequence:
pcercuei 0:03b5121a232e 22868 /*
pcercuei 0:03b5121a232e 22869 * Create a key-sequence.
pcercuei 0:03b5121a232e 22870 */
pcercuei 0:03b5121a232e 22871 keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
pcercuei 0:03b5121a232e 22872 matcher->aidc->def->nbFields *
pcercuei 0:03b5121a232e 22873 sizeof(xmlSchemaPSVIIDCKeyPtr));
pcercuei 0:03b5121a232e 22874 if (keySeq == NULL) {
pcercuei 0:03b5121a232e 22875 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 22876 "allocating an IDC key-sequence", NULL);
pcercuei 0:03b5121a232e 22877 return(-1);
pcercuei 0:03b5121a232e 22878 }
pcercuei 0:03b5121a232e 22879 memset(keySeq, 0, matcher->aidc->def->nbFields *
pcercuei 0:03b5121a232e 22880 sizeof(xmlSchemaPSVIIDCKeyPtr));
pcercuei 0:03b5121a232e 22881 matcher->keySeqs[pos] = keySeq;
pcercuei 0:03b5121a232e 22882 create_key:
pcercuei 0:03b5121a232e 22883 /*
pcercuei 0:03b5121a232e 22884 * Create a key once per node only.
pcercuei 0:03b5121a232e 22885 */
pcercuei 0:03b5121a232e 22886 if (key == NULL) {
pcercuei 0:03b5121a232e 22887 key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
pcercuei 0:03b5121a232e 22888 sizeof(xmlSchemaPSVIIDCKey));
pcercuei 0:03b5121a232e 22889 if (key == NULL) {
pcercuei 0:03b5121a232e 22890 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 22891 "allocating a IDC key", NULL);
pcercuei 0:03b5121a232e 22892 xmlFree(keySeq);
pcercuei 0:03b5121a232e 22893 matcher->keySeqs[pos] = NULL;
pcercuei 0:03b5121a232e 22894 return(-1);
pcercuei 0:03b5121a232e 22895 }
pcercuei 0:03b5121a232e 22896 /*
pcercuei 0:03b5121a232e 22897 * Consume the compiled value.
pcercuei 0:03b5121a232e 22898 */
pcercuei 0:03b5121a232e 22899 key->type = simpleType;
pcercuei 0:03b5121a232e 22900 key->val = vctxt->inode->val;
pcercuei 0:03b5121a232e 22901 vctxt->inode->val = NULL;
pcercuei 0:03b5121a232e 22902 /*
pcercuei 0:03b5121a232e 22903 * Store the key in a global list.
pcercuei 0:03b5121a232e 22904 */
pcercuei 0:03b5121a232e 22905 if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
pcercuei 0:03b5121a232e 22906 xmlSchemaIDCFreeKey(key);
pcercuei 0:03b5121a232e 22907 return (-1);
pcercuei 0:03b5121a232e 22908 }
pcercuei 0:03b5121a232e 22909 }
pcercuei 0:03b5121a232e 22910 keySeq[idx] = key;
pcercuei 0:03b5121a232e 22911 }
pcercuei 0:03b5121a232e 22912 } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
pcercuei 0:03b5121a232e 22913
pcercuei 0:03b5121a232e 22914 xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
pcercuei 0:03b5121a232e 22915 /* xmlSchemaPSVIIDCBindingPtr bind; */
pcercuei 0:03b5121a232e 22916 xmlSchemaPSVIIDCNodePtr ntItem;
pcercuei 0:03b5121a232e 22917 xmlSchemaIDCMatcherPtr matcher;
pcercuei 0:03b5121a232e 22918 xmlSchemaIDCPtr idc;
pcercuei 0:03b5121a232e 22919 xmlSchemaItemListPtr targets;
pcercuei 0:03b5121a232e 22920 int pos, i, j, nbKeys;
pcercuei 0:03b5121a232e 22921 /*
pcercuei 0:03b5121a232e 22922 * Here we have the following scenario:
pcercuei 0:03b5121a232e 22923 * An IDC 'selector' state object resolved to a target node,
pcercuei 0:03b5121a232e 22924 * during the time this target node was in the
pcercuei 0:03b5121a232e 22925 * ancestor-or-self axis, the 'field' state object(s) looked
pcercuei 0:03b5121a232e 22926 * out for matching nodes to create a key-sequence for this
pcercuei 0:03b5121a232e 22927 * target node. Now we are back to this target node and need
pcercuei 0:03b5121a232e 22928 * to put the key-sequence, together with the target node
pcercuei 0:03b5121a232e 22929 * itself, into the node-table of the corresponding IDC
pcercuei 0:03b5121a232e 22930 * binding.
pcercuei 0:03b5121a232e 22931 */
pcercuei 0:03b5121a232e 22932 matcher = sto->matcher;
pcercuei 0:03b5121a232e 22933 idc = matcher->aidc->def;
pcercuei 0:03b5121a232e 22934 nbKeys = idc->nbFields;
pcercuei 0:03b5121a232e 22935 pos = depth - matcher->depth;
pcercuei 0:03b5121a232e 22936 /*
pcercuei 0:03b5121a232e 22937 * Check if the matcher has any key-sequences at all, plus
pcercuei 0:03b5121a232e 22938 * if it has a key-sequence for the current target node.
pcercuei 0:03b5121a232e 22939 */
pcercuei 0:03b5121a232e 22940 if ((matcher->keySeqs == NULL) ||
pcercuei 0:03b5121a232e 22941 (matcher->sizeKeySeqs <= pos)) {
pcercuei 0:03b5121a232e 22942 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
pcercuei 0:03b5121a232e 22943 goto selector_key_error;
pcercuei 0:03b5121a232e 22944 else
pcercuei 0:03b5121a232e 22945 goto selector_leave;
pcercuei 0:03b5121a232e 22946 }
pcercuei 0:03b5121a232e 22947
pcercuei 0:03b5121a232e 22948 keySeq = &(matcher->keySeqs[pos]);
pcercuei 0:03b5121a232e 22949 if (*keySeq == NULL) {
pcercuei 0:03b5121a232e 22950 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
pcercuei 0:03b5121a232e 22951 goto selector_key_error;
pcercuei 0:03b5121a232e 22952 else
pcercuei 0:03b5121a232e 22953 goto selector_leave;
pcercuei 0:03b5121a232e 22954 }
pcercuei 0:03b5121a232e 22955
pcercuei 0:03b5121a232e 22956 for (i = 0; i < nbKeys; i++) {
pcercuei 0:03b5121a232e 22957 if ((*keySeq)[i] == NULL) {
pcercuei 0:03b5121a232e 22958 /*
pcercuei 0:03b5121a232e 22959 * Not qualified, if not all fields did resolve.
pcercuei 0:03b5121a232e 22960 */
pcercuei 0:03b5121a232e 22961 if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
pcercuei 0:03b5121a232e 22962 /*
pcercuei 0:03b5121a232e 22963 * All fields of a "key" IDC must resolve.
pcercuei 0:03b5121a232e 22964 */
pcercuei 0:03b5121a232e 22965 goto selector_key_error;
pcercuei 0:03b5121a232e 22966 }
pcercuei 0:03b5121a232e 22967 goto selector_leave;
pcercuei 0:03b5121a232e 22968 }
pcercuei 0:03b5121a232e 22969 }
pcercuei 0:03b5121a232e 22970 /*
pcercuei 0:03b5121a232e 22971 * All fields did resolve.
pcercuei 0:03b5121a232e 22972 */
pcercuei 0:03b5121a232e 22973
pcercuei 0:03b5121a232e 22974 /*
pcercuei 0:03b5121a232e 22975 * 4.1 If the {identity-constraint category} is unique(/key),
pcercuei 0:03b5121a232e 22976 * then no two members of the `qualified node set` have
pcercuei 0:03b5121a232e 22977 * `key-sequences` whose members are pairwise equal, as
pcercuei 0:03b5121a232e 22978 * defined by Equal in [XML Schemas: Datatypes].
pcercuei 0:03b5121a232e 22979 *
pcercuei 0:03b5121a232e 22980 * Get the IDC binding from the matcher and check for
pcercuei 0:03b5121a232e 22981 * duplicate key-sequences.
pcercuei 0:03b5121a232e 22982 */
pcercuei 0:03b5121a232e 22983 #if 0
pcercuei 0:03b5121a232e 22984 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
pcercuei 0:03b5121a232e 22985 #endif
pcercuei 0:03b5121a232e 22986 targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
pcercuei 0:03b5121a232e 22987 if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
pcercuei 0:03b5121a232e 22988 (targets->nbItems != 0)) {
pcercuei 0:03b5121a232e 22989 xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
pcercuei 0:03b5121a232e 22990
pcercuei 0:03b5121a232e 22991 i = 0;
pcercuei 0:03b5121a232e 22992 res = 0;
pcercuei 0:03b5121a232e 22993 /*
pcercuei 0:03b5121a232e 22994 * Compare the key-sequences, key by key.
pcercuei 0:03b5121a232e 22995 */
pcercuei 0:03b5121a232e 22996 do {
pcercuei 0:03b5121a232e 22997 bkeySeq =
pcercuei 0:03b5121a232e 22998 ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
pcercuei 0:03b5121a232e 22999 for (j = 0; j < nbKeys; j++) {
pcercuei 0:03b5121a232e 23000 ckey = (*keySeq)[j];
pcercuei 0:03b5121a232e 23001 bkey = bkeySeq[j];
pcercuei 0:03b5121a232e 23002 res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
pcercuei 0:03b5121a232e 23003 if (res == -1) {
pcercuei 0:03b5121a232e 23004 return (-1);
pcercuei 0:03b5121a232e 23005 } else if (res == 0) {
pcercuei 0:03b5121a232e 23006 /*
pcercuei 0:03b5121a232e 23007 * One of the keys differs, so the key-sequence
pcercuei 0:03b5121a232e 23008 * won't be equal; get out.
pcercuei 0:03b5121a232e 23009 */
pcercuei 0:03b5121a232e 23010 break;
pcercuei 0:03b5121a232e 23011 }
pcercuei 0:03b5121a232e 23012 }
pcercuei 0:03b5121a232e 23013 if (res == 1) {
pcercuei 0:03b5121a232e 23014 /*
pcercuei 0:03b5121a232e 23015 * Duplicate key-sequence found.
pcercuei 0:03b5121a232e 23016 */
pcercuei 0:03b5121a232e 23017 break;
pcercuei 0:03b5121a232e 23018 }
pcercuei 0:03b5121a232e 23019 i++;
pcercuei 0:03b5121a232e 23020 } while (i < targets->nbItems);
pcercuei 0:03b5121a232e 23021 if (i != targets->nbItems) {
pcercuei 0:03b5121a232e 23022 xmlChar *str = NULL, *strB = NULL;
pcercuei 0:03b5121a232e 23023 /*
pcercuei 0:03b5121a232e 23024 * TODO: Try to report the key-sequence.
pcercuei 0:03b5121a232e 23025 */
pcercuei 0:03b5121a232e 23026 xmlSchemaCustomErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 23027 XML_SCHEMAV_CVC_IDC, NULL,
pcercuei 0:03b5121a232e 23028 WXS_BASIC_CAST idc,
pcercuei 0:03b5121a232e 23029 "Duplicate key-sequence %s in %s",
pcercuei 0:03b5121a232e 23030 xmlSchemaFormatIDCKeySequence(vctxt, &str,
pcercuei 0:03b5121a232e 23031 (*keySeq), nbKeys),
pcercuei 0:03b5121a232e 23032 xmlSchemaGetIDCDesignation(&strB, idc));
pcercuei 0:03b5121a232e 23033 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 23034 FREE_AND_NULL(strB);
pcercuei 0:03b5121a232e 23035 goto selector_leave;
pcercuei 0:03b5121a232e 23036 }
pcercuei 0:03b5121a232e 23037 }
pcercuei 0:03b5121a232e 23038 /*
pcercuei 0:03b5121a232e 23039 * Add a node-table item to the IDC binding.
pcercuei 0:03b5121a232e 23040 */
pcercuei 0:03b5121a232e 23041 ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
pcercuei 0:03b5121a232e 23042 sizeof(xmlSchemaPSVIIDCNode));
pcercuei 0:03b5121a232e 23043 if (ntItem == NULL) {
pcercuei 0:03b5121a232e 23044 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 23045 "allocating an IDC node-table item", NULL);
pcercuei 0:03b5121a232e 23046 xmlFree(*keySeq);
pcercuei 0:03b5121a232e 23047 *keySeq = NULL;
pcercuei 0:03b5121a232e 23048 return(-1);
pcercuei 0:03b5121a232e 23049 }
pcercuei 0:03b5121a232e 23050 memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
pcercuei 0:03b5121a232e 23051
pcercuei 0:03b5121a232e 23052 /*
pcercuei 0:03b5121a232e 23053 * Store the node-table item in a global list.
pcercuei 0:03b5121a232e 23054 */
pcercuei 0:03b5121a232e 23055 if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
pcercuei 0:03b5121a232e 23056 if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
pcercuei 0:03b5121a232e 23057 xmlFree(ntItem);
pcercuei 0:03b5121a232e 23058 xmlFree(*keySeq);
pcercuei 0:03b5121a232e 23059 *keySeq = NULL;
pcercuei 0:03b5121a232e 23060 return (-1);
pcercuei 0:03b5121a232e 23061 }
pcercuei 0:03b5121a232e 23062 ntItem->nodeQNameID = -1;
pcercuei 0:03b5121a232e 23063 } else {
pcercuei 0:03b5121a232e 23064 /*
pcercuei 0:03b5121a232e 23065 * Save a cached QName for this node on the IDC node, to be
pcercuei 0:03b5121a232e 23066 * able to report it, even if the node is not saved.
pcercuei 0:03b5121a232e 23067 */
pcercuei 0:03b5121a232e 23068 ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
pcercuei 0:03b5121a232e 23069 vctxt->inode->localName, vctxt->inode->nsName);
pcercuei 0:03b5121a232e 23070 if (ntItem->nodeQNameID == -1) {
pcercuei 0:03b5121a232e 23071 xmlFree(ntItem);
pcercuei 0:03b5121a232e 23072 xmlFree(*keySeq);
pcercuei 0:03b5121a232e 23073 *keySeq = NULL;
pcercuei 0:03b5121a232e 23074 return (-1);
pcercuei 0:03b5121a232e 23075 }
pcercuei 0:03b5121a232e 23076 }
pcercuei 0:03b5121a232e 23077 /*
pcercuei 0:03b5121a232e 23078 * Init the node-table item: Save the node, position and
pcercuei 0:03b5121a232e 23079 * consume the key-sequence.
pcercuei 0:03b5121a232e 23080 */
pcercuei 0:03b5121a232e 23081 ntItem->node = vctxt->node;
pcercuei 0:03b5121a232e 23082 ntItem->nodeLine = vctxt->inode->nodeLine;
pcercuei 0:03b5121a232e 23083 ntItem->keys = *keySeq;
pcercuei 0:03b5121a232e 23084 *keySeq = NULL;
pcercuei 0:03b5121a232e 23085 #if 0
pcercuei 0:03b5121a232e 23086 if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
pcercuei 0:03b5121a232e 23087 #endif
pcercuei 0:03b5121a232e 23088 if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
pcercuei 0:03b5121a232e 23089 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
pcercuei 0:03b5121a232e 23090 /*
pcercuei 0:03b5121a232e 23091 * Free the item, since keyref items won't be
pcercuei 0:03b5121a232e 23092 * put on a global list.
pcercuei 0:03b5121a232e 23093 */
pcercuei 0:03b5121a232e 23094 xmlFree(ntItem->keys);
pcercuei 0:03b5121a232e 23095 xmlFree(ntItem);
pcercuei 0:03b5121a232e 23096 }
pcercuei 0:03b5121a232e 23097 return (-1);
pcercuei 0:03b5121a232e 23098 }
pcercuei 0:03b5121a232e 23099
pcercuei 0:03b5121a232e 23100 goto selector_leave;
pcercuei 0:03b5121a232e 23101 selector_key_error:
pcercuei 0:03b5121a232e 23102 {
pcercuei 0:03b5121a232e 23103 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 23104 /*
pcercuei 0:03b5121a232e 23105 * 4.2.1 (KEY) The `target node set` and the
pcercuei 0:03b5121a232e 23106 * `qualified node set` are equal, that is, every
pcercuei 0:03b5121a232e 23107 * member of the `target node set` is also a member
pcercuei 0:03b5121a232e 23108 * of the `qualified node set` and vice versa.
pcercuei 0:03b5121a232e 23109 */
pcercuei 0:03b5121a232e 23110 xmlSchemaCustomErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 23111 XML_SCHEMAV_CVC_IDC, NULL,
pcercuei 0:03b5121a232e 23112 WXS_BASIC_CAST idc,
pcercuei 0:03b5121a232e 23113 "Not all fields of %s evaluate to a node",
pcercuei 0:03b5121a232e 23114 xmlSchemaGetIDCDesignation(&str, idc), NULL);
pcercuei 0:03b5121a232e 23115 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 23116 }
pcercuei 0:03b5121a232e 23117 selector_leave:
pcercuei 0:03b5121a232e 23118 /*
pcercuei 0:03b5121a232e 23119 * Free the key-sequence if not added to the IDC table.
pcercuei 0:03b5121a232e 23120 */
pcercuei 0:03b5121a232e 23121 if ((keySeq != NULL) && (*keySeq != NULL)) {
pcercuei 0:03b5121a232e 23122 xmlFree(*keySeq);
pcercuei 0:03b5121a232e 23123 *keySeq = NULL;
pcercuei 0:03b5121a232e 23124 }
pcercuei 0:03b5121a232e 23125 } /* if selector */
pcercuei 0:03b5121a232e 23126
pcercuei 0:03b5121a232e 23127 sto->nbHistory--;
pcercuei 0:03b5121a232e 23128
pcercuei 0:03b5121a232e 23129 deregister_check:
pcercuei 0:03b5121a232e 23130 /*
pcercuei 0:03b5121a232e 23131 * Deregister state objects if they reach the depth of creation.
pcercuei 0:03b5121a232e 23132 */
pcercuei 0:03b5121a232e 23133 if ((sto->nbHistory == 0) && (sto->depth == depth)) {
pcercuei 0:03b5121a232e 23134 #ifdef DEBUG_IDC
pcercuei 0:03b5121a232e 23135 xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n",
pcercuei 0:03b5121a232e 23136 sto->sel->xpath);
pcercuei 0:03b5121a232e 23137 #endif
pcercuei 0:03b5121a232e 23138 if (vctxt->xpathStates != sto) {
pcercuei 0:03b5121a232e 23139 VERROR_INT("xmlSchemaXPathProcessHistory",
pcercuei 0:03b5121a232e 23140 "The state object to be removed is not the first "
pcercuei 0:03b5121a232e 23141 "in the list");
pcercuei 0:03b5121a232e 23142 }
pcercuei 0:03b5121a232e 23143 nextsto = sto->next;
pcercuei 0:03b5121a232e 23144 /*
pcercuei 0:03b5121a232e 23145 * Unlink from the list of active XPath state objects.
pcercuei 0:03b5121a232e 23146 */
pcercuei 0:03b5121a232e 23147 vctxt->xpathStates = sto->next;
pcercuei 0:03b5121a232e 23148 sto->next = vctxt->xpathStatePool;
pcercuei 0:03b5121a232e 23149 /*
pcercuei 0:03b5121a232e 23150 * Link it to the pool of reusable state objects.
pcercuei 0:03b5121a232e 23151 */
pcercuei 0:03b5121a232e 23152 vctxt->xpathStatePool = sto;
pcercuei 0:03b5121a232e 23153 sto = nextsto;
pcercuei 0:03b5121a232e 23154 } else
pcercuei 0:03b5121a232e 23155 sto = sto->next;
pcercuei 0:03b5121a232e 23156 } /* while (sto != NULL) */
pcercuei 0:03b5121a232e 23157 return (0);
pcercuei 0:03b5121a232e 23158 }
pcercuei 0:03b5121a232e 23159
pcercuei 0:03b5121a232e 23160 /**
pcercuei 0:03b5121a232e 23161 * xmlSchemaIDCRegisterMatchers:
pcercuei 0:03b5121a232e 23162 * @vctxt: the WXS validation context
pcercuei 0:03b5121a232e 23163 * @elemDecl: the element declaration
pcercuei 0:03b5121a232e 23164 *
pcercuei 0:03b5121a232e 23165 * Creates helper objects to evaluate IDC selectors/fields
pcercuei 0:03b5121a232e 23166 * successively.
pcercuei 0:03b5121a232e 23167 *
pcercuei 0:03b5121a232e 23168 * Returns 0 if OK and -1 on internal errors.
pcercuei 0:03b5121a232e 23169 */
pcercuei 0:03b5121a232e 23170 static int
pcercuei 0:03b5121a232e 23171 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 23172 xmlSchemaElementPtr elemDecl)
pcercuei 0:03b5121a232e 23173 {
pcercuei 0:03b5121a232e 23174 xmlSchemaIDCMatcherPtr matcher, last = NULL;
pcercuei 0:03b5121a232e 23175 xmlSchemaIDCPtr idc, refIdc;
pcercuei 0:03b5121a232e 23176 xmlSchemaIDCAugPtr aidc;
pcercuei 0:03b5121a232e 23177
pcercuei 0:03b5121a232e 23178 idc = (xmlSchemaIDCPtr) elemDecl->idcs;
pcercuei 0:03b5121a232e 23179 if (idc == NULL)
pcercuei 0:03b5121a232e 23180 return (0);
pcercuei 0:03b5121a232e 23181
pcercuei 0:03b5121a232e 23182 #ifdef DEBUG_IDC
pcercuei 0:03b5121a232e 23183 {
pcercuei 0:03b5121a232e 23184 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 23185 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 23186 "IDC: REGISTER on %s, depth %d\n",
pcercuei 0:03b5121a232e 23187 (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
pcercuei 0:03b5121a232e 23188 vctxt->inode->localName), vctxt->depth);
pcercuei 0:03b5121a232e 23189 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 23190 }
pcercuei 0:03b5121a232e 23191 #endif
pcercuei 0:03b5121a232e 23192 if (vctxt->inode->idcMatchers != NULL) {
pcercuei 0:03b5121a232e 23193 VERROR_INT("xmlSchemaIDCRegisterMatchers",
pcercuei 0:03b5121a232e 23194 "The chain of IDC matchers is expected to be empty");
pcercuei 0:03b5121a232e 23195 return (-1);
pcercuei 0:03b5121a232e 23196 }
pcercuei 0:03b5121a232e 23197 do {
pcercuei 0:03b5121a232e 23198 if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
pcercuei 0:03b5121a232e 23199 /*
pcercuei 0:03b5121a232e 23200 * Since IDCs bubbles are expensive we need to know the
pcercuei 0:03b5121a232e 23201 * depth at which the bubbles should stop; this will be
pcercuei 0:03b5121a232e 23202 * the depth of the top-most keyref IDC. If no keyref
pcercuei 0:03b5121a232e 23203 * references a key/unique IDC, the keyrefDepth will
pcercuei 0:03b5121a232e 23204 * be -1, indicating that no bubbles are needed.
pcercuei 0:03b5121a232e 23205 */
pcercuei 0:03b5121a232e 23206 refIdc = (xmlSchemaIDCPtr) idc->ref->item;
pcercuei 0:03b5121a232e 23207 if (refIdc != NULL) {
pcercuei 0:03b5121a232e 23208 /*
pcercuei 0:03b5121a232e 23209 * Remember that we have keyrefs on this node.
pcercuei 0:03b5121a232e 23210 */
pcercuei 0:03b5121a232e 23211 vctxt->inode->hasKeyrefs = 1;
pcercuei 0:03b5121a232e 23212 /*
pcercuei 0:03b5121a232e 23213 * Lookup the referenced augmented IDC info.
pcercuei 0:03b5121a232e 23214 */
pcercuei 0:03b5121a232e 23215 aidc = vctxt->aidcs;
pcercuei 0:03b5121a232e 23216 while (aidc != NULL) {
pcercuei 0:03b5121a232e 23217 if (aidc->def == refIdc)
pcercuei 0:03b5121a232e 23218 break;
pcercuei 0:03b5121a232e 23219 aidc = aidc->next;
pcercuei 0:03b5121a232e 23220 }
pcercuei 0:03b5121a232e 23221 if (aidc == NULL) {
pcercuei 0:03b5121a232e 23222 VERROR_INT("xmlSchemaIDCRegisterMatchers",
pcercuei 0:03b5121a232e 23223 "Could not find an augmented IDC item for an IDC "
pcercuei 0:03b5121a232e 23224 "definition");
pcercuei 0:03b5121a232e 23225 return (-1);
pcercuei 0:03b5121a232e 23226 }
pcercuei 0:03b5121a232e 23227 if ((aidc->keyrefDepth == -1) ||
pcercuei 0:03b5121a232e 23228 (vctxt->depth < aidc->keyrefDepth))
pcercuei 0:03b5121a232e 23229 aidc->keyrefDepth = vctxt->depth;
pcercuei 0:03b5121a232e 23230 }
pcercuei 0:03b5121a232e 23231 }
pcercuei 0:03b5121a232e 23232 /*
pcercuei 0:03b5121a232e 23233 * Lookup the augmented IDC item for the IDC definition.
pcercuei 0:03b5121a232e 23234 */
pcercuei 0:03b5121a232e 23235 aidc = vctxt->aidcs;
pcercuei 0:03b5121a232e 23236 while (aidc != NULL) {
pcercuei 0:03b5121a232e 23237 if (aidc->def == idc)
pcercuei 0:03b5121a232e 23238 break;
pcercuei 0:03b5121a232e 23239 aidc = aidc->next;
pcercuei 0:03b5121a232e 23240 }
pcercuei 0:03b5121a232e 23241 if (aidc == NULL) {
pcercuei 0:03b5121a232e 23242 VERROR_INT("xmlSchemaIDCRegisterMatchers",
pcercuei 0:03b5121a232e 23243 "Could not find an augmented IDC item for an IDC definition");
pcercuei 0:03b5121a232e 23244 return (-1);
pcercuei 0:03b5121a232e 23245 }
pcercuei 0:03b5121a232e 23246 /*
pcercuei 0:03b5121a232e 23247 * Create an IDC matcher for every IDC definition.
pcercuei 0:03b5121a232e 23248 */
pcercuei 0:03b5121a232e 23249 if (vctxt->idcMatcherCache != NULL) {
pcercuei 0:03b5121a232e 23250 /*
pcercuei 0:03b5121a232e 23251 * Reuse a cached matcher.
pcercuei 0:03b5121a232e 23252 */
pcercuei 0:03b5121a232e 23253 matcher = vctxt->idcMatcherCache;
pcercuei 0:03b5121a232e 23254 vctxt->idcMatcherCache = matcher->nextCached;
pcercuei 0:03b5121a232e 23255 matcher->nextCached = NULL;
pcercuei 0:03b5121a232e 23256 } else {
pcercuei 0:03b5121a232e 23257 matcher = (xmlSchemaIDCMatcherPtr)
pcercuei 0:03b5121a232e 23258 xmlMalloc(sizeof(xmlSchemaIDCMatcher));
pcercuei 0:03b5121a232e 23259 if (matcher == NULL) {
pcercuei 0:03b5121a232e 23260 xmlSchemaVErrMemory(vctxt,
pcercuei 0:03b5121a232e 23261 "allocating an IDC matcher", NULL);
pcercuei 0:03b5121a232e 23262 return (-1);
pcercuei 0:03b5121a232e 23263 }
pcercuei 0:03b5121a232e 23264 memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
pcercuei 0:03b5121a232e 23265 }
pcercuei 0:03b5121a232e 23266 if (last == NULL)
pcercuei 0:03b5121a232e 23267 vctxt->inode->idcMatchers = matcher;
pcercuei 0:03b5121a232e 23268 else
pcercuei 0:03b5121a232e 23269 last->next = matcher;
pcercuei 0:03b5121a232e 23270 last = matcher;
pcercuei 0:03b5121a232e 23271
pcercuei 0:03b5121a232e 23272 matcher->type = IDC_MATCHER;
pcercuei 0:03b5121a232e 23273 matcher->depth = vctxt->depth;
pcercuei 0:03b5121a232e 23274 matcher->aidc = aidc;
pcercuei 0:03b5121a232e 23275 matcher->idcType = aidc->def->type;
pcercuei 0:03b5121a232e 23276 #ifdef DEBUG_IDC
pcercuei 0:03b5121a232e 23277 xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n");
pcercuei 0:03b5121a232e 23278 #endif
pcercuei 0:03b5121a232e 23279 /*
pcercuei 0:03b5121a232e 23280 * Init the automaton state object.
pcercuei 0:03b5121a232e 23281 */
pcercuei 0:03b5121a232e 23282 if (xmlSchemaIDCAddStateObject(vctxt, matcher,
pcercuei 0:03b5121a232e 23283 idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
pcercuei 0:03b5121a232e 23284 return (-1);
pcercuei 0:03b5121a232e 23285
pcercuei 0:03b5121a232e 23286 idc = idc->next;
pcercuei 0:03b5121a232e 23287 } while (idc != NULL);
pcercuei 0:03b5121a232e 23288 return (0);
pcercuei 0:03b5121a232e 23289 }
pcercuei 0:03b5121a232e 23290
pcercuei 0:03b5121a232e 23291 static int
pcercuei 0:03b5121a232e 23292 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 23293 xmlSchemaNodeInfoPtr ielem)
pcercuei 0:03b5121a232e 23294 {
pcercuei 0:03b5121a232e 23295 xmlSchemaPSVIIDCBindingPtr bind;
pcercuei 0:03b5121a232e 23296 int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
pcercuei 0:03b5121a232e 23297 xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
pcercuei 0:03b5121a232e 23298 xmlSchemaPSVIIDCNodePtr *targets, *dupls;
pcercuei 0:03b5121a232e 23299
pcercuei 0:03b5121a232e 23300 xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
pcercuei 0:03b5121a232e 23301 /* vctxt->createIDCNodeTables */
pcercuei 0:03b5121a232e 23302 while (matcher != NULL) {
pcercuei 0:03b5121a232e 23303 /*
pcercuei 0:03b5121a232e 23304 * Skip keyref IDCs and empty IDC target-lists.
pcercuei 0:03b5121a232e 23305 */
pcercuei 0:03b5121a232e 23306 if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
pcercuei 0:03b5121a232e 23307 WXS_ILIST_IS_EMPTY(matcher->targets))
pcercuei 0:03b5121a232e 23308 {
pcercuei 0:03b5121a232e 23309 matcher = matcher->next;
pcercuei 0:03b5121a232e 23310 continue;
pcercuei 0:03b5121a232e 23311 }
pcercuei 0:03b5121a232e 23312 /*
pcercuei 0:03b5121a232e 23313 * If we _want_ the IDC node-table to be created in any case
pcercuei 0:03b5121a232e 23314 * then do so. Otherwise create them only if keyrefs need them.
pcercuei 0:03b5121a232e 23315 */
pcercuei 0:03b5121a232e 23316 if ((! vctxt->createIDCNodeTables) &&
pcercuei 0:03b5121a232e 23317 ((matcher->aidc->keyrefDepth == -1) ||
pcercuei 0:03b5121a232e 23318 (matcher->aidc->keyrefDepth > vctxt->depth)))
pcercuei 0:03b5121a232e 23319 {
pcercuei 0:03b5121a232e 23320 matcher = matcher->next;
pcercuei 0:03b5121a232e 23321 continue;
pcercuei 0:03b5121a232e 23322 }
pcercuei 0:03b5121a232e 23323 /*
pcercuei 0:03b5121a232e 23324 * Get/create the IDC binding on this element for the IDC definition.
pcercuei 0:03b5121a232e 23325 */
pcercuei 0:03b5121a232e 23326 bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
pcercuei 0:03b5121a232e 23327
pcercuei 0:03b5121a232e 23328 if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
pcercuei 0:03b5121a232e 23329 dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
pcercuei 0:03b5121a232e 23330 nbDupls = bind->dupls->nbItems;
pcercuei 0:03b5121a232e 23331 } else {
pcercuei 0:03b5121a232e 23332 dupls = NULL;
pcercuei 0:03b5121a232e 23333 nbDupls = 0;
pcercuei 0:03b5121a232e 23334 }
pcercuei 0:03b5121a232e 23335 if (bind->nodeTable != NULL) {
pcercuei 0:03b5121a232e 23336 nbNodeTable = bind->nbNodes;
pcercuei 0:03b5121a232e 23337 } else {
pcercuei 0:03b5121a232e 23338 nbNodeTable = 0;
pcercuei 0:03b5121a232e 23339 }
pcercuei 0:03b5121a232e 23340
pcercuei 0:03b5121a232e 23341 if ((nbNodeTable == 0) && (nbDupls == 0)) {
pcercuei 0:03b5121a232e 23342 /*
pcercuei 0:03b5121a232e 23343 * Transfer all IDC target-nodes to the IDC node-table.
pcercuei 0:03b5121a232e 23344 */
pcercuei 0:03b5121a232e 23345 bind->nodeTable =
pcercuei 0:03b5121a232e 23346 (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
pcercuei 0:03b5121a232e 23347 bind->sizeNodes = matcher->targets->sizeItems;
pcercuei 0:03b5121a232e 23348 bind->nbNodes = matcher->targets->nbItems;
pcercuei 0:03b5121a232e 23349
pcercuei 0:03b5121a232e 23350 matcher->targets->items = NULL;
pcercuei 0:03b5121a232e 23351 matcher->targets->sizeItems = 0;
pcercuei 0:03b5121a232e 23352 matcher->targets->nbItems = 0;
pcercuei 0:03b5121a232e 23353 } else {
pcercuei 0:03b5121a232e 23354 /*
pcercuei 0:03b5121a232e 23355 * Compare the key-sequences and add to the IDC node-table.
pcercuei 0:03b5121a232e 23356 */
pcercuei 0:03b5121a232e 23357 nbTargets = matcher->targets->nbItems;
pcercuei 0:03b5121a232e 23358 targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
pcercuei 0:03b5121a232e 23359 nbFields = matcher->aidc->def->nbFields;
pcercuei 0:03b5121a232e 23360 i = 0;
pcercuei 0:03b5121a232e 23361 do {
pcercuei 0:03b5121a232e 23362 keys = targets[i]->keys;
pcercuei 0:03b5121a232e 23363 if (nbDupls) {
pcercuei 0:03b5121a232e 23364 /*
pcercuei 0:03b5121a232e 23365 * Search in already found duplicates first.
pcercuei 0:03b5121a232e 23366 */
pcercuei 0:03b5121a232e 23367 j = 0;
pcercuei 0:03b5121a232e 23368 do {
pcercuei 0:03b5121a232e 23369 if (nbFields == 1) {
pcercuei 0:03b5121a232e 23370 res = xmlSchemaAreValuesEqual(keys[0]->val,
pcercuei 0:03b5121a232e 23371 dupls[j]->keys[0]->val);
pcercuei 0:03b5121a232e 23372 if (res == -1)
pcercuei 0:03b5121a232e 23373 goto internal_error;
pcercuei 0:03b5121a232e 23374 if (res == 1) {
pcercuei 0:03b5121a232e 23375 /*
pcercuei 0:03b5121a232e 23376 * Equal key-sequence.
pcercuei 0:03b5121a232e 23377 */
pcercuei 0:03b5121a232e 23378 goto next_target;
pcercuei 0:03b5121a232e 23379 }
pcercuei 0:03b5121a232e 23380 } else {
pcercuei 0:03b5121a232e 23381 res = 0;
pcercuei 0:03b5121a232e 23382 ntkeys = dupls[j]->keys;
pcercuei 0:03b5121a232e 23383 for (k = 0; k < nbFields; k++) {
pcercuei 0:03b5121a232e 23384 res = xmlSchemaAreValuesEqual(keys[k]->val,
pcercuei 0:03b5121a232e 23385 ntkeys[k]->val);
pcercuei 0:03b5121a232e 23386 if (res == -1)
pcercuei 0:03b5121a232e 23387 goto internal_error;
pcercuei 0:03b5121a232e 23388 if (res == 0) {
pcercuei 0:03b5121a232e 23389 /*
pcercuei 0:03b5121a232e 23390 * One of the keys differs.
pcercuei 0:03b5121a232e 23391 */
pcercuei 0:03b5121a232e 23392 break;
pcercuei 0:03b5121a232e 23393 }
pcercuei 0:03b5121a232e 23394 }
pcercuei 0:03b5121a232e 23395 if (res == 1) {
pcercuei 0:03b5121a232e 23396 /*
pcercuei 0:03b5121a232e 23397 * Equal key-sequence found.
pcercuei 0:03b5121a232e 23398 */
pcercuei 0:03b5121a232e 23399 goto next_target;
pcercuei 0:03b5121a232e 23400 }
pcercuei 0:03b5121a232e 23401 }
pcercuei 0:03b5121a232e 23402 j++;
pcercuei 0:03b5121a232e 23403 } while (j < nbDupls);
pcercuei 0:03b5121a232e 23404 }
pcercuei 0:03b5121a232e 23405 if (nbNodeTable) {
pcercuei 0:03b5121a232e 23406 j = 0;
pcercuei 0:03b5121a232e 23407 do {
pcercuei 0:03b5121a232e 23408 if (nbFields == 1) {
pcercuei 0:03b5121a232e 23409 res = xmlSchemaAreValuesEqual(keys[0]->val,
pcercuei 0:03b5121a232e 23410 bind->nodeTable[j]->keys[0]->val);
pcercuei 0:03b5121a232e 23411 if (res == -1)
pcercuei 0:03b5121a232e 23412 goto internal_error;
pcercuei 0:03b5121a232e 23413 if (res == 0) {
pcercuei 0:03b5121a232e 23414 /*
pcercuei 0:03b5121a232e 23415 * The key-sequence differs.
pcercuei 0:03b5121a232e 23416 */
pcercuei 0:03b5121a232e 23417 goto next_node_table_entry;
pcercuei 0:03b5121a232e 23418 }
pcercuei 0:03b5121a232e 23419 } else {
pcercuei 0:03b5121a232e 23420 res = 0;
pcercuei 0:03b5121a232e 23421 ntkeys = bind->nodeTable[j]->keys;
pcercuei 0:03b5121a232e 23422 for (k = 0; k < nbFields; k++) {
pcercuei 0:03b5121a232e 23423 res = xmlSchemaAreValuesEqual(keys[k]->val,
pcercuei 0:03b5121a232e 23424 ntkeys[k]->val);
pcercuei 0:03b5121a232e 23425 if (res == -1)
pcercuei 0:03b5121a232e 23426 goto internal_error;
pcercuei 0:03b5121a232e 23427 if (res == 0) {
pcercuei 0:03b5121a232e 23428 /*
pcercuei 0:03b5121a232e 23429 * One of the keys differs.
pcercuei 0:03b5121a232e 23430 */
pcercuei 0:03b5121a232e 23431 goto next_node_table_entry;
pcercuei 0:03b5121a232e 23432 }
pcercuei 0:03b5121a232e 23433 }
pcercuei 0:03b5121a232e 23434 }
pcercuei 0:03b5121a232e 23435 /*
pcercuei 0:03b5121a232e 23436 * Add the duplicate to the list of duplicates.
pcercuei 0:03b5121a232e 23437 */
pcercuei 0:03b5121a232e 23438 if (bind->dupls == NULL) {
pcercuei 0:03b5121a232e 23439 bind->dupls = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 23440 if (bind->dupls == NULL)
pcercuei 0:03b5121a232e 23441 goto internal_error;
pcercuei 0:03b5121a232e 23442 }
pcercuei 0:03b5121a232e 23443 if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
pcercuei 0:03b5121a232e 23444 goto internal_error;
pcercuei 0:03b5121a232e 23445 /*
pcercuei 0:03b5121a232e 23446 * Remove the duplicate entry from the IDC node-table.
pcercuei 0:03b5121a232e 23447 */
pcercuei 0:03b5121a232e 23448 bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
pcercuei 0:03b5121a232e 23449 bind->nbNodes--;
pcercuei 0:03b5121a232e 23450
pcercuei 0:03b5121a232e 23451 goto next_target;
pcercuei 0:03b5121a232e 23452
pcercuei 0:03b5121a232e 23453 next_node_table_entry:
pcercuei 0:03b5121a232e 23454 j++;
pcercuei 0:03b5121a232e 23455 } while (j < nbNodeTable);
pcercuei 0:03b5121a232e 23456 }
pcercuei 0:03b5121a232e 23457 /*
pcercuei 0:03b5121a232e 23458 * If everything is fine, then add the IDC target-node to
pcercuei 0:03b5121a232e 23459 * the IDC node-table.
pcercuei 0:03b5121a232e 23460 */
pcercuei 0:03b5121a232e 23461 if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
pcercuei 0:03b5121a232e 23462 goto internal_error;
pcercuei 0:03b5121a232e 23463
pcercuei 0:03b5121a232e 23464 next_target:
pcercuei 0:03b5121a232e 23465 i++;
pcercuei 0:03b5121a232e 23466 } while (i < nbTargets);
pcercuei 0:03b5121a232e 23467 }
pcercuei 0:03b5121a232e 23468 matcher = matcher->next;
pcercuei 0:03b5121a232e 23469 }
pcercuei 0:03b5121a232e 23470 return(0);
pcercuei 0:03b5121a232e 23471
pcercuei 0:03b5121a232e 23472 internal_error:
pcercuei 0:03b5121a232e 23473 return(-1);
pcercuei 0:03b5121a232e 23474 }
pcercuei 0:03b5121a232e 23475
pcercuei 0:03b5121a232e 23476 /**
pcercuei 0:03b5121a232e 23477 * xmlSchemaBubbleIDCNodeTables:
pcercuei 0:03b5121a232e 23478 * @depth: the current tree depth
pcercuei 0:03b5121a232e 23479 *
pcercuei 0:03b5121a232e 23480 * Merges IDC bindings of an element at @depth into the corresponding IDC
pcercuei 0:03b5121a232e 23481 * bindings of its parent element. If a duplicate note-table entry is found,
pcercuei 0:03b5121a232e 23482 * both, the parent node-table entry and child entry are discarded from the
pcercuei 0:03b5121a232e 23483 * node-table of the parent.
pcercuei 0:03b5121a232e 23484 *
pcercuei 0:03b5121a232e 23485 * Returns 0 if OK and -1 on internal errors.
pcercuei 0:03b5121a232e 23486 */
pcercuei 0:03b5121a232e 23487 static int
pcercuei 0:03b5121a232e 23488 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 23489 {
pcercuei 0:03b5121a232e 23490 xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
pcercuei 0:03b5121a232e 23491 xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
pcercuei 0:03b5121a232e 23492 xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
pcercuei 0:03b5121a232e 23493 xmlSchemaIDCAugPtr aidc;
pcercuei 0:03b5121a232e 23494 int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
pcercuei 0:03b5121a232e 23495
pcercuei 0:03b5121a232e 23496 bind = vctxt->inode->idcTable;
pcercuei 0:03b5121a232e 23497 if (bind == NULL) {
pcercuei 0:03b5121a232e 23498 /* Fine, no table, no bubbles. */
pcercuei 0:03b5121a232e 23499 return (0);
pcercuei 0:03b5121a232e 23500 }
pcercuei 0:03b5121a232e 23501
pcercuei 0:03b5121a232e 23502 parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
pcercuei 0:03b5121a232e 23503 /*
pcercuei 0:03b5121a232e 23504 * Walk all bindings; create new or add to existing bindings.
pcercuei 0:03b5121a232e 23505 * Remove duplicate key-sequences.
pcercuei 0:03b5121a232e 23506 */
pcercuei 0:03b5121a232e 23507 while (bind != NULL) {
pcercuei 0:03b5121a232e 23508
pcercuei 0:03b5121a232e 23509 if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
pcercuei 0:03b5121a232e 23510 goto next_binding;
pcercuei 0:03b5121a232e 23511 /*
pcercuei 0:03b5121a232e 23512 * Check if the key/unique IDC table needs to be bubbled.
pcercuei 0:03b5121a232e 23513 */
pcercuei 0:03b5121a232e 23514 if (! vctxt->createIDCNodeTables) {
pcercuei 0:03b5121a232e 23515 aidc = vctxt->aidcs;
pcercuei 0:03b5121a232e 23516 do {
pcercuei 0:03b5121a232e 23517 if (aidc->def == bind->definition) {
pcercuei 0:03b5121a232e 23518 if ((aidc->keyrefDepth == -1) ||
pcercuei 0:03b5121a232e 23519 (aidc->keyrefDepth >= vctxt->depth)) {
pcercuei 0:03b5121a232e 23520 goto next_binding;
pcercuei 0:03b5121a232e 23521 }
pcercuei 0:03b5121a232e 23522 break;
pcercuei 0:03b5121a232e 23523 }
pcercuei 0:03b5121a232e 23524 aidc = aidc->next;
pcercuei 0:03b5121a232e 23525 } while (aidc != NULL);
pcercuei 0:03b5121a232e 23526 }
pcercuei 0:03b5121a232e 23527
pcercuei 0:03b5121a232e 23528 if (parTable != NULL)
pcercuei 0:03b5121a232e 23529 parBind = *parTable;
pcercuei 0:03b5121a232e 23530 /*
pcercuei 0:03b5121a232e 23531 * Search a matching parent binding for the
pcercuei 0:03b5121a232e 23532 * IDC definition.
pcercuei 0:03b5121a232e 23533 */
pcercuei 0:03b5121a232e 23534 while (parBind != NULL) {
pcercuei 0:03b5121a232e 23535 if (parBind->definition == bind->definition)
pcercuei 0:03b5121a232e 23536 break;
pcercuei 0:03b5121a232e 23537 parBind = parBind->next;
pcercuei 0:03b5121a232e 23538 }
pcercuei 0:03b5121a232e 23539
pcercuei 0:03b5121a232e 23540 if (parBind != NULL) {
pcercuei 0:03b5121a232e 23541 /*
pcercuei 0:03b5121a232e 23542 * Compare every node-table entry of the child node,
pcercuei 0:03b5121a232e 23543 * i.e. the key-sequence within, ...
pcercuei 0:03b5121a232e 23544 */
pcercuei 0:03b5121a232e 23545 oldNum = parBind->nbNodes; /* Skip newly added items. */
pcercuei 0:03b5121a232e 23546
pcercuei 0:03b5121a232e 23547 if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
pcercuei 0:03b5121a232e 23548 oldDupls = parBind->dupls->nbItems;
pcercuei 0:03b5121a232e 23549 dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
pcercuei 0:03b5121a232e 23550 } else {
pcercuei 0:03b5121a232e 23551 dupls = NULL;
pcercuei 0:03b5121a232e 23552 oldDupls = 0;
pcercuei 0:03b5121a232e 23553 }
pcercuei 0:03b5121a232e 23554
pcercuei 0:03b5121a232e 23555 parNodes = parBind->nodeTable;
pcercuei 0:03b5121a232e 23556 nbFields = bind->definition->nbFields;
pcercuei 0:03b5121a232e 23557
pcercuei 0:03b5121a232e 23558 for (i = 0; i < bind->nbNodes; i++) {
pcercuei 0:03b5121a232e 23559 node = bind->nodeTable[i];
pcercuei 0:03b5121a232e 23560 if (node == NULL)
pcercuei 0:03b5121a232e 23561 continue;
pcercuei 0:03b5121a232e 23562 /*
pcercuei 0:03b5121a232e 23563 * ...with every key-sequence of the parent node, already
pcercuei 0:03b5121a232e 23564 * evaluated to be a duplicate key-sequence.
pcercuei 0:03b5121a232e 23565 */
pcercuei 0:03b5121a232e 23566 if (oldDupls) {
pcercuei 0:03b5121a232e 23567 j = 0;
pcercuei 0:03b5121a232e 23568 while (j < oldDupls) {
pcercuei 0:03b5121a232e 23569 if (nbFields == 1) {
pcercuei 0:03b5121a232e 23570 ret = xmlSchemaAreValuesEqual(
pcercuei 0:03b5121a232e 23571 node->keys[0]->val,
pcercuei 0:03b5121a232e 23572 dupls[j]->keys[0]->val);
pcercuei 0:03b5121a232e 23573 if (ret == -1)
pcercuei 0:03b5121a232e 23574 goto internal_error;
pcercuei 0:03b5121a232e 23575 if (ret == 0) {
pcercuei 0:03b5121a232e 23576 j++;
pcercuei 0:03b5121a232e 23577 continue;
pcercuei 0:03b5121a232e 23578 }
pcercuei 0:03b5121a232e 23579 } else {
pcercuei 0:03b5121a232e 23580 parNode = dupls[j];
pcercuei 0:03b5121a232e 23581 for (k = 0; k < nbFields; k++) {
pcercuei 0:03b5121a232e 23582 ret = xmlSchemaAreValuesEqual(
pcercuei 0:03b5121a232e 23583 node->keys[k]->val,
pcercuei 0:03b5121a232e 23584 parNode->keys[k]->val);
pcercuei 0:03b5121a232e 23585 if (ret == -1)
pcercuei 0:03b5121a232e 23586 goto internal_error;
pcercuei 0:03b5121a232e 23587 if (ret == 0)
pcercuei 0:03b5121a232e 23588 break;
pcercuei 0:03b5121a232e 23589 }
pcercuei 0:03b5121a232e 23590 }
pcercuei 0:03b5121a232e 23591 if (ret == 1)
pcercuei 0:03b5121a232e 23592 /* Duplicate found. */
pcercuei 0:03b5121a232e 23593 break;
pcercuei 0:03b5121a232e 23594 j++;
pcercuei 0:03b5121a232e 23595 }
pcercuei 0:03b5121a232e 23596 if (j != oldDupls) {
pcercuei 0:03b5121a232e 23597 /* Duplicate found. Skip this entry. */
pcercuei 0:03b5121a232e 23598 continue;
pcercuei 0:03b5121a232e 23599 }
pcercuei 0:03b5121a232e 23600 }
pcercuei 0:03b5121a232e 23601 /*
pcercuei 0:03b5121a232e 23602 * ... and with every key-sequence of the parent node.
pcercuei 0:03b5121a232e 23603 */
pcercuei 0:03b5121a232e 23604 if (oldNum) {
pcercuei 0:03b5121a232e 23605 j = 0;
pcercuei 0:03b5121a232e 23606 while (j < oldNum) {
pcercuei 0:03b5121a232e 23607 parNode = parNodes[j];
pcercuei 0:03b5121a232e 23608 if (nbFields == 1) {
pcercuei 0:03b5121a232e 23609 ret = xmlSchemaAreValuesEqual(
pcercuei 0:03b5121a232e 23610 node->keys[0]->val,
pcercuei 0:03b5121a232e 23611 parNode->keys[0]->val);
pcercuei 0:03b5121a232e 23612 if (ret == -1)
pcercuei 0:03b5121a232e 23613 goto internal_error;
pcercuei 0:03b5121a232e 23614 if (ret == 0) {
pcercuei 0:03b5121a232e 23615 j++;
pcercuei 0:03b5121a232e 23616 continue;
pcercuei 0:03b5121a232e 23617 }
pcercuei 0:03b5121a232e 23618 } else {
pcercuei 0:03b5121a232e 23619 for (k = 0; k < nbFields; k++) {
pcercuei 0:03b5121a232e 23620 ret = xmlSchemaAreValuesEqual(
pcercuei 0:03b5121a232e 23621 node->keys[k]->val,
pcercuei 0:03b5121a232e 23622 parNode->keys[k]->val);
pcercuei 0:03b5121a232e 23623 if (ret == -1)
pcercuei 0:03b5121a232e 23624 goto internal_error;
pcercuei 0:03b5121a232e 23625 if (ret == 0)
pcercuei 0:03b5121a232e 23626 break;
pcercuei 0:03b5121a232e 23627 }
pcercuei 0:03b5121a232e 23628 }
pcercuei 0:03b5121a232e 23629 if (ret == 1)
pcercuei 0:03b5121a232e 23630 /* Duplicate found. */
pcercuei 0:03b5121a232e 23631 break;
pcercuei 0:03b5121a232e 23632 j++;
pcercuei 0:03b5121a232e 23633 }
pcercuei 0:03b5121a232e 23634 if (j != oldNum) {
pcercuei 0:03b5121a232e 23635 /*
pcercuei 0:03b5121a232e 23636 * Handle duplicates. Move the duplicate in
pcercuei 0:03b5121a232e 23637 * the parent's node-table to the list of
pcercuei 0:03b5121a232e 23638 * duplicates.
pcercuei 0:03b5121a232e 23639 */
pcercuei 0:03b5121a232e 23640 oldNum--;
pcercuei 0:03b5121a232e 23641 parBind->nbNodes--;
pcercuei 0:03b5121a232e 23642 /*
pcercuei 0:03b5121a232e 23643 * Move last old item to pos of duplicate.
pcercuei 0:03b5121a232e 23644 */
pcercuei 0:03b5121a232e 23645 parNodes[j] = parNodes[oldNum];
pcercuei 0:03b5121a232e 23646
pcercuei 0:03b5121a232e 23647 if (parBind->nbNodes != oldNum) {
pcercuei 0:03b5121a232e 23648 /*
pcercuei 0:03b5121a232e 23649 * If new items exist, move last new item to
pcercuei 0:03b5121a232e 23650 * last of old items.
pcercuei 0:03b5121a232e 23651 */
pcercuei 0:03b5121a232e 23652 parNodes[oldNum] =
pcercuei 0:03b5121a232e 23653 parNodes[parBind->nbNodes];
pcercuei 0:03b5121a232e 23654 }
pcercuei 0:03b5121a232e 23655 if (parBind->dupls == NULL) {
pcercuei 0:03b5121a232e 23656 parBind->dupls = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 23657 if (parBind->dupls == NULL)
pcercuei 0:03b5121a232e 23658 goto internal_error;
pcercuei 0:03b5121a232e 23659 }
pcercuei 0:03b5121a232e 23660 xmlSchemaItemListAdd(parBind->dupls, parNode);
pcercuei 0:03b5121a232e 23661 } else {
pcercuei 0:03b5121a232e 23662 /*
pcercuei 0:03b5121a232e 23663 * Add the node-table entry (node and key-sequence) of
pcercuei 0:03b5121a232e 23664 * the child node to the node table of the parent node.
pcercuei 0:03b5121a232e 23665 */
pcercuei 0:03b5121a232e 23666 if (parBind->nodeTable == NULL) {
pcercuei 0:03b5121a232e 23667 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
pcercuei 0:03b5121a232e 23668 xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
pcercuei 0:03b5121a232e 23669 if (parBind->nodeTable == NULL) {
pcercuei 0:03b5121a232e 23670 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 23671 "allocating IDC list of node-table items", NULL);
pcercuei 0:03b5121a232e 23672 goto internal_error;
pcercuei 0:03b5121a232e 23673 }
pcercuei 0:03b5121a232e 23674 parBind->sizeNodes = 1;
pcercuei 0:03b5121a232e 23675 } else if (parBind->nbNodes >= parBind->sizeNodes) {
pcercuei 0:03b5121a232e 23676 parBind->sizeNodes *= 2;
pcercuei 0:03b5121a232e 23677 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
pcercuei 0:03b5121a232e 23678 xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
pcercuei 0:03b5121a232e 23679 sizeof(xmlSchemaPSVIIDCNodePtr));
pcercuei 0:03b5121a232e 23680 if (parBind->nodeTable == NULL) {
pcercuei 0:03b5121a232e 23681 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 23682 "re-allocating IDC list of node-table items", NULL);
pcercuei 0:03b5121a232e 23683 goto internal_error;
pcercuei 0:03b5121a232e 23684 }
pcercuei 0:03b5121a232e 23685 }
pcercuei 0:03b5121a232e 23686 parNodes = parBind->nodeTable;
pcercuei 0:03b5121a232e 23687 /*
pcercuei 0:03b5121a232e 23688 * Append the new node-table entry to the 'new node-table
pcercuei 0:03b5121a232e 23689 * entries' section.
pcercuei 0:03b5121a232e 23690 */
pcercuei 0:03b5121a232e 23691 parNodes[parBind->nbNodes++] = node;
pcercuei 0:03b5121a232e 23692 }
pcercuei 0:03b5121a232e 23693
pcercuei 0:03b5121a232e 23694 }
pcercuei 0:03b5121a232e 23695
pcercuei 0:03b5121a232e 23696 }
pcercuei 0:03b5121a232e 23697 } else {
pcercuei 0:03b5121a232e 23698 /*
pcercuei 0:03b5121a232e 23699 * No binding for the IDC was found: create a new one and
pcercuei 0:03b5121a232e 23700 * copy all node-tables.
pcercuei 0:03b5121a232e 23701 */
pcercuei 0:03b5121a232e 23702 parBind = xmlSchemaIDCNewBinding(bind->definition);
pcercuei 0:03b5121a232e 23703 if (parBind == NULL)
pcercuei 0:03b5121a232e 23704 goto internal_error;
pcercuei 0:03b5121a232e 23705
pcercuei 0:03b5121a232e 23706 /*
pcercuei 0:03b5121a232e 23707 * TODO: Hmm, how to optimize the initial number of
pcercuei 0:03b5121a232e 23708 * allocated entries?
pcercuei 0:03b5121a232e 23709 */
pcercuei 0:03b5121a232e 23710 if (bind->nbNodes != 0) {
pcercuei 0:03b5121a232e 23711 /*
pcercuei 0:03b5121a232e 23712 * Add all IDC node-table entries.
pcercuei 0:03b5121a232e 23713 */
pcercuei 0:03b5121a232e 23714 if (! vctxt->psviExposeIDCNodeTables) {
pcercuei 0:03b5121a232e 23715 /*
pcercuei 0:03b5121a232e 23716 * Just move the entries.
pcercuei 0:03b5121a232e 23717 * NOTE: this is quite save here, since
pcercuei 0:03b5121a232e 23718 * all the keyref lookups have already been
pcercuei 0:03b5121a232e 23719 * performed.
pcercuei 0:03b5121a232e 23720 */
pcercuei 0:03b5121a232e 23721 parBind->nodeTable = bind->nodeTable;
pcercuei 0:03b5121a232e 23722 bind->nodeTable = NULL;
pcercuei 0:03b5121a232e 23723 parBind->sizeNodes = bind->sizeNodes;
pcercuei 0:03b5121a232e 23724 bind->sizeNodes = 0;
pcercuei 0:03b5121a232e 23725 parBind->nbNodes = bind->nbNodes;
pcercuei 0:03b5121a232e 23726 bind->nbNodes = 0;
pcercuei 0:03b5121a232e 23727 } else {
pcercuei 0:03b5121a232e 23728 /*
pcercuei 0:03b5121a232e 23729 * Copy the entries.
pcercuei 0:03b5121a232e 23730 */
pcercuei 0:03b5121a232e 23731 parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
pcercuei 0:03b5121a232e 23732 xmlMalloc(bind->nbNodes *
pcercuei 0:03b5121a232e 23733 sizeof(xmlSchemaPSVIIDCNodePtr));
pcercuei 0:03b5121a232e 23734 if (parBind->nodeTable == NULL) {
pcercuei 0:03b5121a232e 23735 xmlSchemaVErrMemory(NULL,
pcercuei 0:03b5121a232e 23736 "allocating an array of IDC node-table "
pcercuei 0:03b5121a232e 23737 "items", NULL);
pcercuei 0:03b5121a232e 23738 xmlSchemaIDCFreeBinding(parBind);
pcercuei 0:03b5121a232e 23739 goto internal_error;
pcercuei 0:03b5121a232e 23740 }
pcercuei 0:03b5121a232e 23741 parBind->sizeNodes = bind->nbNodes;
pcercuei 0:03b5121a232e 23742 parBind->nbNodes = bind->nbNodes;
pcercuei 0:03b5121a232e 23743 memcpy(parBind->nodeTable, bind->nodeTable,
pcercuei 0:03b5121a232e 23744 bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
pcercuei 0:03b5121a232e 23745 }
pcercuei 0:03b5121a232e 23746 }
pcercuei 0:03b5121a232e 23747 if (bind->dupls) {
pcercuei 0:03b5121a232e 23748 /*
pcercuei 0:03b5121a232e 23749 * Move the duplicates.
pcercuei 0:03b5121a232e 23750 */
pcercuei 0:03b5121a232e 23751 if (parBind->dupls != NULL)
pcercuei 0:03b5121a232e 23752 xmlSchemaItemListFree(parBind->dupls);
pcercuei 0:03b5121a232e 23753 parBind->dupls = bind->dupls;
pcercuei 0:03b5121a232e 23754 bind->dupls = NULL;
pcercuei 0:03b5121a232e 23755 }
pcercuei 0:03b5121a232e 23756 if (parTable != NULL) {
pcercuei 0:03b5121a232e 23757 if (*parTable == NULL)
pcercuei 0:03b5121a232e 23758 *parTable = parBind;
pcercuei 0:03b5121a232e 23759 else {
pcercuei 0:03b5121a232e 23760 parBind->next = *parTable;
pcercuei 0:03b5121a232e 23761 *parTable = parBind;
pcercuei 0:03b5121a232e 23762 }
pcercuei 0:03b5121a232e 23763 }
pcercuei 0:03b5121a232e 23764 }
pcercuei 0:03b5121a232e 23765
pcercuei 0:03b5121a232e 23766 next_binding:
pcercuei 0:03b5121a232e 23767 bind = bind->next;
pcercuei 0:03b5121a232e 23768 }
pcercuei 0:03b5121a232e 23769 return (0);
pcercuei 0:03b5121a232e 23770
pcercuei 0:03b5121a232e 23771 internal_error:
pcercuei 0:03b5121a232e 23772 return(-1);
pcercuei 0:03b5121a232e 23773 }
pcercuei 0:03b5121a232e 23774
pcercuei 0:03b5121a232e 23775 /**
pcercuei 0:03b5121a232e 23776 * xmlSchemaCheckCVCIDCKeyRef:
pcercuei 0:03b5121a232e 23777 * @vctxt: the WXS validation context
pcercuei 0:03b5121a232e 23778 * @elemDecl: the element declaration
pcercuei 0:03b5121a232e 23779 *
pcercuei 0:03b5121a232e 23780 * Check the cvc-idc-keyref constraints.
pcercuei 0:03b5121a232e 23781 */
pcercuei 0:03b5121a232e 23782 static int
pcercuei 0:03b5121a232e 23783 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 23784 {
pcercuei 0:03b5121a232e 23785 xmlSchemaIDCMatcherPtr matcher;
pcercuei 0:03b5121a232e 23786 xmlSchemaPSVIIDCBindingPtr bind;
pcercuei 0:03b5121a232e 23787
pcercuei 0:03b5121a232e 23788 matcher = vctxt->inode->idcMatchers;
pcercuei 0:03b5121a232e 23789 /*
pcercuei 0:03b5121a232e 23790 * Find a keyref.
pcercuei 0:03b5121a232e 23791 */
pcercuei 0:03b5121a232e 23792 while (matcher != NULL) {
pcercuei 0:03b5121a232e 23793 if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
pcercuei 0:03b5121a232e 23794 matcher->targets &&
pcercuei 0:03b5121a232e 23795 matcher->targets->nbItems)
pcercuei 0:03b5121a232e 23796 {
pcercuei 0:03b5121a232e 23797 int i, j, k, res, nbFields, hasDupls;
pcercuei 0:03b5121a232e 23798 xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
pcercuei 0:03b5121a232e 23799 xmlSchemaPSVIIDCNodePtr refNode = NULL;
pcercuei 0:03b5121a232e 23800
pcercuei 0:03b5121a232e 23801 nbFields = matcher->aidc->def->nbFields;
pcercuei 0:03b5121a232e 23802
pcercuei 0:03b5121a232e 23803 /*
pcercuei 0:03b5121a232e 23804 * Find the IDC node-table for the referenced IDC key/unique.
pcercuei 0:03b5121a232e 23805 */
pcercuei 0:03b5121a232e 23806 bind = vctxt->inode->idcTable;
pcercuei 0:03b5121a232e 23807 while (bind != NULL) {
pcercuei 0:03b5121a232e 23808 if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
pcercuei 0:03b5121a232e 23809 bind->definition)
pcercuei 0:03b5121a232e 23810 break;
pcercuei 0:03b5121a232e 23811 bind = bind->next;
pcercuei 0:03b5121a232e 23812 }
pcercuei 0:03b5121a232e 23813 hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
pcercuei 0:03b5121a232e 23814 /*
pcercuei 0:03b5121a232e 23815 * Search for a matching key-sequences.
pcercuei 0:03b5121a232e 23816 */
pcercuei 0:03b5121a232e 23817 for (i = 0; i < matcher->targets->nbItems; i++) {
pcercuei 0:03b5121a232e 23818 res = 0;
pcercuei 0:03b5121a232e 23819 refNode = matcher->targets->items[i];
pcercuei 0:03b5121a232e 23820 if (bind != NULL) {
pcercuei 0:03b5121a232e 23821 refKeys = refNode->keys;
pcercuei 0:03b5121a232e 23822 for (j = 0; j < bind->nbNodes; j++) {
pcercuei 0:03b5121a232e 23823 keys = bind->nodeTable[j]->keys;
pcercuei 0:03b5121a232e 23824 for (k = 0; k < nbFields; k++) {
pcercuei 0:03b5121a232e 23825 res = xmlSchemaAreValuesEqual(keys[k]->val,
pcercuei 0:03b5121a232e 23826 refKeys[k]->val);
pcercuei 0:03b5121a232e 23827 if (res == 0)
pcercuei 0:03b5121a232e 23828 break;
pcercuei 0:03b5121a232e 23829 else if (res == -1) {
pcercuei 0:03b5121a232e 23830 return (-1);
pcercuei 0:03b5121a232e 23831 }
pcercuei 0:03b5121a232e 23832 }
pcercuei 0:03b5121a232e 23833 if (res == 1) {
pcercuei 0:03b5121a232e 23834 /*
pcercuei 0:03b5121a232e 23835 * Match found.
pcercuei 0:03b5121a232e 23836 */
pcercuei 0:03b5121a232e 23837 break;
pcercuei 0:03b5121a232e 23838 }
pcercuei 0:03b5121a232e 23839 }
pcercuei 0:03b5121a232e 23840 if ((res == 0) && hasDupls) {
pcercuei 0:03b5121a232e 23841 /*
pcercuei 0:03b5121a232e 23842 * Search in duplicates
pcercuei 0:03b5121a232e 23843 */
pcercuei 0:03b5121a232e 23844 for (j = 0; j < bind->dupls->nbItems; j++) {
pcercuei 0:03b5121a232e 23845 keys = ((xmlSchemaPSVIIDCNodePtr)
pcercuei 0:03b5121a232e 23846 bind->dupls->items[j])->keys;
pcercuei 0:03b5121a232e 23847 for (k = 0; k < nbFields; k++) {
pcercuei 0:03b5121a232e 23848 res = xmlSchemaAreValuesEqual(keys[k]->val,
pcercuei 0:03b5121a232e 23849 refKeys[k]->val);
pcercuei 0:03b5121a232e 23850 if (res == 0)
pcercuei 0:03b5121a232e 23851 break;
pcercuei 0:03b5121a232e 23852 else if (res == -1) {
pcercuei 0:03b5121a232e 23853 return (-1);
pcercuei 0:03b5121a232e 23854 }
pcercuei 0:03b5121a232e 23855 }
pcercuei 0:03b5121a232e 23856 if (res == 1) {
pcercuei 0:03b5121a232e 23857 /*
pcercuei 0:03b5121a232e 23858 * Match in duplicates found.
pcercuei 0:03b5121a232e 23859 */
pcercuei 0:03b5121a232e 23860 xmlChar *str = NULL, *strB = NULL;
pcercuei 0:03b5121a232e 23861 xmlSchemaKeyrefErr(vctxt,
pcercuei 0:03b5121a232e 23862 XML_SCHEMAV_CVC_IDC, refNode,
pcercuei 0:03b5121a232e 23863 (xmlSchemaTypePtr) matcher->aidc->def,
pcercuei 0:03b5121a232e 23864 "More than one match found for "
pcercuei 0:03b5121a232e 23865 "key-sequence %s of keyref '%s'",
pcercuei 0:03b5121a232e 23866 xmlSchemaFormatIDCKeySequence(vctxt, &str,
pcercuei 0:03b5121a232e 23867 refNode->keys, nbFields),
pcercuei 0:03b5121a232e 23868 xmlSchemaGetComponentQName(&strB,
pcercuei 0:03b5121a232e 23869 matcher->aidc->def));
pcercuei 0:03b5121a232e 23870 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 23871 FREE_AND_NULL(strB);
pcercuei 0:03b5121a232e 23872 break;
pcercuei 0:03b5121a232e 23873 }
pcercuei 0:03b5121a232e 23874 }
pcercuei 0:03b5121a232e 23875 }
pcercuei 0:03b5121a232e 23876 }
pcercuei 0:03b5121a232e 23877
pcercuei 0:03b5121a232e 23878 if (res == 0) {
pcercuei 0:03b5121a232e 23879 xmlChar *str = NULL, *strB = NULL;
pcercuei 0:03b5121a232e 23880 xmlSchemaKeyrefErr(vctxt,
pcercuei 0:03b5121a232e 23881 XML_SCHEMAV_CVC_IDC, refNode,
pcercuei 0:03b5121a232e 23882 (xmlSchemaTypePtr) matcher->aidc->def,
pcercuei 0:03b5121a232e 23883 "No match found for key-sequence %s of keyref '%s'",
pcercuei 0:03b5121a232e 23884 xmlSchemaFormatIDCKeySequence(vctxt, &str,
pcercuei 0:03b5121a232e 23885 refNode->keys, nbFields),
pcercuei 0:03b5121a232e 23886 xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
pcercuei 0:03b5121a232e 23887 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 23888 FREE_AND_NULL(strB);
pcercuei 0:03b5121a232e 23889 }
pcercuei 0:03b5121a232e 23890 }
pcercuei 0:03b5121a232e 23891 }
pcercuei 0:03b5121a232e 23892 matcher = matcher->next;
pcercuei 0:03b5121a232e 23893 }
pcercuei 0:03b5121a232e 23894 /* TODO: Return an error if any error encountered. */
pcercuei 0:03b5121a232e 23895 return (0);
pcercuei 0:03b5121a232e 23896 }
pcercuei 0:03b5121a232e 23897
pcercuei 0:03b5121a232e 23898 /************************************************************************
pcercuei 0:03b5121a232e 23899 * *
pcercuei 0:03b5121a232e 23900 * XML Reader validation code *
pcercuei 0:03b5121a232e 23901 * *
pcercuei 0:03b5121a232e 23902 ************************************************************************/
pcercuei 0:03b5121a232e 23903
pcercuei 0:03b5121a232e 23904 static xmlSchemaAttrInfoPtr
pcercuei 0:03b5121a232e 23905 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 23906 {
pcercuei 0:03b5121a232e 23907 xmlSchemaAttrInfoPtr iattr;
pcercuei 0:03b5121a232e 23908 /*
pcercuei 0:03b5121a232e 23909 * Grow/create list of attribute infos.
pcercuei 0:03b5121a232e 23910 */
pcercuei 0:03b5121a232e 23911 if (vctxt->attrInfos == NULL) {
pcercuei 0:03b5121a232e 23912 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
pcercuei 0:03b5121a232e 23913 xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
pcercuei 0:03b5121a232e 23914 vctxt->sizeAttrInfos = 1;
pcercuei 0:03b5121a232e 23915 if (vctxt->attrInfos == NULL) {
pcercuei 0:03b5121a232e 23916 xmlSchemaVErrMemory(vctxt,
pcercuei 0:03b5121a232e 23917 "allocating attribute info list", NULL);
pcercuei 0:03b5121a232e 23918 return (NULL);
pcercuei 0:03b5121a232e 23919 }
pcercuei 0:03b5121a232e 23920 } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
pcercuei 0:03b5121a232e 23921 vctxt->sizeAttrInfos++;
pcercuei 0:03b5121a232e 23922 vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
pcercuei 0:03b5121a232e 23923 xmlRealloc(vctxt->attrInfos,
pcercuei 0:03b5121a232e 23924 vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
pcercuei 0:03b5121a232e 23925 if (vctxt->attrInfos == NULL) {
pcercuei 0:03b5121a232e 23926 xmlSchemaVErrMemory(vctxt,
pcercuei 0:03b5121a232e 23927 "re-allocating attribute info list", NULL);
pcercuei 0:03b5121a232e 23928 return (NULL);
pcercuei 0:03b5121a232e 23929 }
pcercuei 0:03b5121a232e 23930 } else {
pcercuei 0:03b5121a232e 23931 iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
pcercuei 0:03b5121a232e 23932 if (iattr->localName != NULL) {
pcercuei 0:03b5121a232e 23933 VERROR_INT("xmlSchemaGetFreshAttrInfo",
pcercuei 0:03b5121a232e 23934 "attr info not cleared");
pcercuei 0:03b5121a232e 23935 return (NULL);
pcercuei 0:03b5121a232e 23936 }
pcercuei 0:03b5121a232e 23937 iattr->nodeType = XML_ATTRIBUTE_NODE;
pcercuei 0:03b5121a232e 23938 return (iattr);
pcercuei 0:03b5121a232e 23939 }
pcercuei 0:03b5121a232e 23940 /*
pcercuei 0:03b5121a232e 23941 * Create an attribute info.
pcercuei 0:03b5121a232e 23942 */
pcercuei 0:03b5121a232e 23943 iattr = (xmlSchemaAttrInfoPtr)
pcercuei 0:03b5121a232e 23944 xmlMalloc(sizeof(xmlSchemaAttrInfo));
pcercuei 0:03b5121a232e 23945 if (iattr == NULL) {
pcercuei 0:03b5121a232e 23946 xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
pcercuei 0:03b5121a232e 23947 return (NULL);
pcercuei 0:03b5121a232e 23948 }
pcercuei 0:03b5121a232e 23949 memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
pcercuei 0:03b5121a232e 23950 iattr->nodeType = XML_ATTRIBUTE_NODE;
pcercuei 0:03b5121a232e 23951 vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
pcercuei 0:03b5121a232e 23952
pcercuei 0:03b5121a232e 23953 return (iattr);
pcercuei 0:03b5121a232e 23954 }
pcercuei 0:03b5121a232e 23955
pcercuei 0:03b5121a232e 23956 static int
pcercuei 0:03b5121a232e 23957 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 23958 xmlNodePtr attrNode,
pcercuei 0:03b5121a232e 23959 int nodeLine,
pcercuei 0:03b5121a232e 23960 const xmlChar *localName,
pcercuei 0:03b5121a232e 23961 const xmlChar *nsName,
pcercuei 0:03b5121a232e 23962 int ownedNames,
pcercuei 0:03b5121a232e 23963 xmlChar *value,
pcercuei 0:03b5121a232e 23964 int ownedValue)
pcercuei 0:03b5121a232e 23965 {
pcercuei 0:03b5121a232e 23966 xmlSchemaAttrInfoPtr attr;
pcercuei 0:03b5121a232e 23967
pcercuei 0:03b5121a232e 23968 attr = xmlSchemaGetFreshAttrInfo(vctxt);
pcercuei 0:03b5121a232e 23969 if (attr == NULL) {
pcercuei 0:03b5121a232e 23970 VERROR_INT("xmlSchemaPushAttribute",
pcercuei 0:03b5121a232e 23971 "calling xmlSchemaGetFreshAttrInfo()");
pcercuei 0:03b5121a232e 23972 return (-1);
pcercuei 0:03b5121a232e 23973 }
pcercuei 0:03b5121a232e 23974 attr->node = attrNode;
pcercuei 0:03b5121a232e 23975 attr->nodeLine = nodeLine;
pcercuei 0:03b5121a232e 23976 attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
pcercuei 0:03b5121a232e 23977 attr->localName = localName;
pcercuei 0:03b5121a232e 23978 attr->nsName = nsName;
pcercuei 0:03b5121a232e 23979 if (ownedNames)
pcercuei 0:03b5121a232e 23980 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
pcercuei 0:03b5121a232e 23981 /*
pcercuei 0:03b5121a232e 23982 * Evaluate if it's an XSI attribute.
pcercuei 0:03b5121a232e 23983 */
pcercuei 0:03b5121a232e 23984 if (nsName != NULL) {
pcercuei 0:03b5121a232e 23985 if (xmlStrEqual(localName, BAD_CAST "nil")) {
pcercuei 0:03b5121a232e 23986 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
pcercuei 0:03b5121a232e 23987 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
pcercuei 0:03b5121a232e 23988 }
pcercuei 0:03b5121a232e 23989 } else if (xmlStrEqual(localName, BAD_CAST "type")) {
pcercuei 0:03b5121a232e 23990 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
pcercuei 0:03b5121a232e 23991 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
pcercuei 0:03b5121a232e 23992 }
pcercuei 0:03b5121a232e 23993 } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
pcercuei 0:03b5121a232e 23994 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
pcercuei 0:03b5121a232e 23995 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
pcercuei 0:03b5121a232e 23996 }
pcercuei 0:03b5121a232e 23997 } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
pcercuei 0:03b5121a232e 23998 if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
pcercuei 0:03b5121a232e 23999 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
pcercuei 0:03b5121a232e 24000 }
pcercuei 0:03b5121a232e 24001 } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
pcercuei 0:03b5121a232e 24002 attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
pcercuei 0:03b5121a232e 24003 }
pcercuei 0:03b5121a232e 24004 }
pcercuei 0:03b5121a232e 24005 attr->value = value;
pcercuei 0:03b5121a232e 24006 if (ownedValue)
pcercuei 0:03b5121a232e 24007 attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
pcercuei 0:03b5121a232e 24008 if (attr->metaType != 0)
pcercuei 0:03b5121a232e 24009 attr->state = XML_SCHEMAS_ATTR_META;
pcercuei 0:03b5121a232e 24010 return (0);
pcercuei 0:03b5121a232e 24011 }
pcercuei 0:03b5121a232e 24012
pcercuei 0:03b5121a232e 24013 /**
pcercuei 0:03b5121a232e 24014 * xmlSchemaClearElemInfo:
pcercuei 0:03b5121a232e 24015 * @vctxt: the WXS validation context
pcercuei 0:03b5121a232e 24016 * @ielem: the element information item
pcercuei 0:03b5121a232e 24017 */
pcercuei 0:03b5121a232e 24018 static void
pcercuei 0:03b5121a232e 24019 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 24020 xmlSchemaNodeInfoPtr ielem)
pcercuei 0:03b5121a232e 24021 {
pcercuei 0:03b5121a232e 24022 ielem->hasKeyrefs = 0;
pcercuei 0:03b5121a232e 24023 ielem->appliedXPath = 0;
pcercuei 0:03b5121a232e 24024 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
pcercuei 0:03b5121a232e 24025 FREE_AND_NULL(ielem->localName);
pcercuei 0:03b5121a232e 24026 FREE_AND_NULL(ielem->nsName);
pcercuei 0:03b5121a232e 24027 } else {
pcercuei 0:03b5121a232e 24028 ielem->localName = NULL;
pcercuei 0:03b5121a232e 24029 ielem->nsName = NULL;
pcercuei 0:03b5121a232e 24030 }
pcercuei 0:03b5121a232e 24031 if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
pcercuei 0:03b5121a232e 24032 FREE_AND_NULL(ielem->value);
pcercuei 0:03b5121a232e 24033 } else {
pcercuei 0:03b5121a232e 24034 ielem->value = NULL;
pcercuei 0:03b5121a232e 24035 }
pcercuei 0:03b5121a232e 24036 if (ielem->val != NULL) {
pcercuei 0:03b5121a232e 24037 /*
pcercuei 0:03b5121a232e 24038 * PSVI TODO: Be careful not to free it when the value is
pcercuei 0:03b5121a232e 24039 * exposed via PSVI.
pcercuei 0:03b5121a232e 24040 */
pcercuei 0:03b5121a232e 24041 xmlSchemaFreeValue(ielem->val);
pcercuei 0:03b5121a232e 24042 ielem->val = NULL;
pcercuei 0:03b5121a232e 24043 }
pcercuei 0:03b5121a232e 24044 if (ielem->idcMatchers != NULL) {
pcercuei 0:03b5121a232e 24045 /*
pcercuei 0:03b5121a232e 24046 * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
pcercuei 0:03b5121a232e 24047 * Does it work?
pcercuei 0:03b5121a232e 24048 */
pcercuei 0:03b5121a232e 24049 xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
pcercuei 0:03b5121a232e 24050 #if 0
pcercuei 0:03b5121a232e 24051 xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
pcercuei 0:03b5121a232e 24052 #endif
pcercuei 0:03b5121a232e 24053 ielem->idcMatchers = NULL;
pcercuei 0:03b5121a232e 24054 }
pcercuei 0:03b5121a232e 24055 if (ielem->idcTable != NULL) {
pcercuei 0:03b5121a232e 24056 /*
pcercuei 0:03b5121a232e 24057 * OPTIMIZE TODO: Use a pool of IDC tables??.
pcercuei 0:03b5121a232e 24058 */
pcercuei 0:03b5121a232e 24059 xmlSchemaIDCFreeIDCTable(ielem->idcTable);
pcercuei 0:03b5121a232e 24060 ielem->idcTable = NULL;
pcercuei 0:03b5121a232e 24061 }
pcercuei 0:03b5121a232e 24062 if (ielem->regexCtxt != NULL) {
pcercuei 0:03b5121a232e 24063 xmlRegFreeExecCtxt(ielem->regexCtxt);
pcercuei 0:03b5121a232e 24064 ielem->regexCtxt = NULL;
pcercuei 0:03b5121a232e 24065 }
pcercuei 0:03b5121a232e 24066 if (ielem->nsBindings != NULL) {
pcercuei 0:03b5121a232e 24067 xmlFree((xmlChar **)ielem->nsBindings);
pcercuei 0:03b5121a232e 24068 ielem->nsBindings = NULL;
pcercuei 0:03b5121a232e 24069 ielem->nbNsBindings = 0;
pcercuei 0:03b5121a232e 24070 ielem->sizeNsBindings = 0;
pcercuei 0:03b5121a232e 24071 }
pcercuei 0:03b5121a232e 24072 }
pcercuei 0:03b5121a232e 24073
pcercuei 0:03b5121a232e 24074 /**
pcercuei 0:03b5121a232e 24075 * xmlSchemaGetFreshElemInfo:
pcercuei 0:03b5121a232e 24076 * @vctxt: the schema validation context
pcercuei 0:03b5121a232e 24077 *
pcercuei 0:03b5121a232e 24078 * Creates/reuses and initializes the element info item for
pcercuei 0:03b5121a232e 24079 * the currect tree depth.
pcercuei 0:03b5121a232e 24080 *
pcercuei 0:03b5121a232e 24081 * Returns the element info item or NULL on API or internal errors.
pcercuei 0:03b5121a232e 24082 */
pcercuei 0:03b5121a232e 24083 static xmlSchemaNodeInfoPtr
pcercuei 0:03b5121a232e 24084 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 24085 {
pcercuei 0:03b5121a232e 24086 xmlSchemaNodeInfoPtr info = NULL;
pcercuei 0:03b5121a232e 24087
pcercuei 0:03b5121a232e 24088 if (vctxt->depth > vctxt->sizeElemInfos) {
pcercuei 0:03b5121a232e 24089 VERROR_INT("xmlSchemaGetFreshElemInfo",
pcercuei 0:03b5121a232e 24090 "inconsistent depth encountered");
pcercuei 0:03b5121a232e 24091 return (NULL);
pcercuei 0:03b5121a232e 24092 }
pcercuei 0:03b5121a232e 24093 if (vctxt->elemInfos == NULL) {
pcercuei 0:03b5121a232e 24094 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
pcercuei 0:03b5121a232e 24095 xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
pcercuei 0:03b5121a232e 24096 if (vctxt->elemInfos == NULL) {
pcercuei 0:03b5121a232e 24097 xmlSchemaVErrMemory(vctxt,
pcercuei 0:03b5121a232e 24098 "allocating the element info array", NULL);
pcercuei 0:03b5121a232e 24099 return (NULL);
pcercuei 0:03b5121a232e 24100 }
pcercuei 0:03b5121a232e 24101 memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
pcercuei 0:03b5121a232e 24102 vctxt->sizeElemInfos = 10;
pcercuei 0:03b5121a232e 24103 } else if (vctxt->sizeElemInfos <= vctxt->depth) {
pcercuei 0:03b5121a232e 24104 int i = vctxt->sizeElemInfos;
pcercuei 0:03b5121a232e 24105
pcercuei 0:03b5121a232e 24106 vctxt->sizeElemInfos *= 2;
pcercuei 0:03b5121a232e 24107 vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
pcercuei 0:03b5121a232e 24108 xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
pcercuei 0:03b5121a232e 24109 sizeof(xmlSchemaNodeInfoPtr));
pcercuei 0:03b5121a232e 24110 if (vctxt->elemInfos == NULL) {
pcercuei 0:03b5121a232e 24111 xmlSchemaVErrMemory(vctxt,
pcercuei 0:03b5121a232e 24112 "re-allocating the element info array", NULL);
pcercuei 0:03b5121a232e 24113 return (NULL);
pcercuei 0:03b5121a232e 24114 }
pcercuei 0:03b5121a232e 24115 /*
pcercuei 0:03b5121a232e 24116 * We need the new memory to be NULLed.
pcercuei 0:03b5121a232e 24117 * TODO: Use memset instead?
pcercuei 0:03b5121a232e 24118 */
pcercuei 0:03b5121a232e 24119 for (; i < vctxt->sizeElemInfos; i++)
pcercuei 0:03b5121a232e 24120 vctxt->elemInfos[i] = NULL;
pcercuei 0:03b5121a232e 24121 } else
pcercuei 0:03b5121a232e 24122 info = vctxt->elemInfos[vctxt->depth];
pcercuei 0:03b5121a232e 24123
pcercuei 0:03b5121a232e 24124 if (info == NULL) {
pcercuei 0:03b5121a232e 24125 info = (xmlSchemaNodeInfoPtr)
pcercuei 0:03b5121a232e 24126 xmlMalloc(sizeof(xmlSchemaNodeInfo));
pcercuei 0:03b5121a232e 24127 if (info == NULL) {
pcercuei 0:03b5121a232e 24128 xmlSchemaVErrMemory(vctxt,
pcercuei 0:03b5121a232e 24129 "allocating an element info", NULL);
pcercuei 0:03b5121a232e 24130 return (NULL);
pcercuei 0:03b5121a232e 24131 }
pcercuei 0:03b5121a232e 24132 vctxt->elemInfos[vctxt->depth] = info;
pcercuei 0:03b5121a232e 24133 } else {
pcercuei 0:03b5121a232e 24134 if (info->localName != NULL) {
pcercuei 0:03b5121a232e 24135 VERROR_INT("xmlSchemaGetFreshElemInfo",
pcercuei 0:03b5121a232e 24136 "elem info has not been cleared");
pcercuei 0:03b5121a232e 24137 return (NULL);
pcercuei 0:03b5121a232e 24138 }
pcercuei 0:03b5121a232e 24139 }
pcercuei 0:03b5121a232e 24140 memset(info, 0, sizeof(xmlSchemaNodeInfo));
pcercuei 0:03b5121a232e 24141 info->nodeType = XML_ELEMENT_NODE;
pcercuei 0:03b5121a232e 24142 info->depth = vctxt->depth;
pcercuei 0:03b5121a232e 24143
pcercuei 0:03b5121a232e 24144 return (info);
pcercuei 0:03b5121a232e 24145 }
pcercuei 0:03b5121a232e 24146
pcercuei 0:03b5121a232e 24147 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
pcercuei 0:03b5121a232e 24148 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
pcercuei 0:03b5121a232e 24149 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
pcercuei 0:03b5121a232e 24150
pcercuei 0:03b5121a232e 24151 static int
pcercuei 0:03b5121a232e 24152 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 24153 xmlNodePtr node,
pcercuei 0:03b5121a232e 24154 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 24155 xmlSchemaValType valType,
pcercuei 0:03b5121a232e 24156 const xmlChar * value,
pcercuei 0:03b5121a232e 24157 xmlSchemaValPtr val,
pcercuei 0:03b5121a232e 24158 unsigned long length,
pcercuei 0:03b5121a232e 24159 int fireErrors)
pcercuei 0:03b5121a232e 24160 {
pcercuei 0:03b5121a232e 24161 int ret, error = 0;
pcercuei 0:03b5121a232e 24162
pcercuei 0:03b5121a232e 24163 xmlSchemaTypePtr tmpType;
pcercuei 0:03b5121a232e 24164 xmlSchemaFacetLinkPtr facetLink;
pcercuei 0:03b5121a232e 24165 xmlSchemaFacetPtr facet;
pcercuei 0:03b5121a232e 24166 unsigned long len = 0;
pcercuei 0:03b5121a232e 24167 xmlSchemaWhitespaceValueType ws;
pcercuei 0:03b5121a232e 24168
pcercuei 0:03b5121a232e 24169 /*
pcercuei 0:03b5121a232e 24170 * In Libxml2, derived built-in types have currently no explicit facets.
pcercuei 0:03b5121a232e 24171 */
pcercuei 0:03b5121a232e 24172 if (type->type == XML_SCHEMA_TYPE_BASIC)
pcercuei 0:03b5121a232e 24173 return (0);
pcercuei 0:03b5121a232e 24174
pcercuei 0:03b5121a232e 24175 /*
pcercuei 0:03b5121a232e 24176 * NOTE: Do not jump away, if the facetSet of the given type is
pcercuei 0:03b5121a232e 24177 * empty: until now, "pattern" and "enumeration" facets of the
pcercuei 0:03b5121a232e 24178 * *base types* need to be checked as well.
pcercuei 0:03b5121a232e 24179 */
pcercuei 0:03b5121a232e 24180 if (type->facetSet == NULL)
pcercuei 0:03b5121a232e 24181 goto pattern_and_enum;
pcercuei 0:03b5121a232e 24182
pcercuei 0:03b5121a232e 24183 if (! WXS_IS_ATOMIC(type)) {
pcercuei 0:03b5121a232e 24184 if (WXS_IS_LIST(type))
pcercuei 0:03b5121a232e 24185 goto WXS_IS_LIST;
pcercuei 0:03b5121a232e 24186 else
pcercuei 0:03b5121a232e 24187 goto pattern_and_enum;
pcercuei 0:03b5121a232e 24188 }
pcercuei 0:03b5121a232e 24189
pcercuei 0:03b5121a232e 24190 /*
pcercuei 0:03b5121a232e 24191 * Whitespace handling is only of importance for string-based
pcercuei 0:03b5121a232e 24192 * types.
pcercuei 0:03b5121a232e 24193 */
pcercuei 0:03b5121a232e 24194 tmpType = xmlSchemaGetPrimitiveType(type);
pcercuei 0:03b5121a232e 24195 if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
pcercuei 0:03b5121a232e 24196 WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
pcercuei 0:03b5121a232e 24197 ws = xmlSchemaGetWhiteSpaceFacetValue(type);
pcercuei 0:03b5121a232e 24198 } else
pcercuei 0:03b5121a232e 24199 ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
pcercuei 0:03b5121a232e 24200
pcercuei 0:03b5121a232e 24201 /*
pcercuei 0:03b5121a232e 24202 * If the value was not computed (for string or
pcercuei 0:03b5121a232e 24203 * anySimpleType based types), then use the provided
pcercuei 0:03b5121a232e 24204 * type.
pcercuei 0:03b5121a232e 24205 */
pcercuei 0:03b5121a232e 24206 if (val != NULL)
pcercuei 0:03b5121a232e 24207 valType = xmlSchemaGetValType(val);
pcercuei 0:03b5121a232e 24208
pcercuei 0:03b5121a232e 24209 ret = 0;
pcercuei 0:03b5121a232e 24210 for (facetLink = type->facetSet; facetLink != NULL;
pcercuei 0:03b5121a232e 24211 facetLink = facetLink->next) {
pcercuei 0:03b5121a232e 24212 /*
pcercuei 0:03b5121a232e 24213 * Skip the pattern "whiteSpace": it is used to
pcercuei 0:03b5121a232e 24214 * format the character content beforehand.
pcercuei 0:03b5121a232e 24215 */
pcercuei 0:03b5121a232e 24216 switch (facetLink->facet->type) {
pcercuei 0:03b5121a232e 24217 case XML_SCHEMA_FACET_WHITESPACE:
pcercuei 0:03b5121a232e 24218 case XML_SCHEMA_FACET_PATTERN:
pcercuei 0:03b5121a232e 24219 case XML_SCHEMA_FACET_ENUMERATION:
pcercuei 0:03b5121a232e 24220 continue;
pcercuei 0:03b5121a232e 24221 case XML_SCHEMA_FACET_LENGTH:
pcercuei 0:03b5121a232e 24222 case XML_SCHEMA_FACET_MINLENGTH:
pcercuei 0:03b5121a232e 24223 case XML_SCHEMA_FACET_MAXLENGTH:
pcercuei 0:03b5121a232e 24224 ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
pcercuei 0:03b5121a232e 24225 valType, value, val, &len, ws);
pcercuei 0:03b5121a232e 24226 break;
pcercuei 0:03b5121a232e 24227 default:
pcercuei 0:03b5121a232e 24228 ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
pcercuei 0:03b5121a232e 24229 valType, value, val, ws);
pcercuei 0:03b5121a232e 24230 break;
pcercuei 0:03b5121a232e 24231 }
pcercuei 0:03b5121a232e 24232 if (ret < 0) {
pcercuei 0:03b5121a232e 24233 AERROR_INT("xmlSchemaValidateFacets",
pcercuei 0:03b5121a232e 24234 "validating against a atomic type facet");
pcercuei 0:03b5121a232e 24235 return (-1);
pcercuei 0:03b5121a232e 24236 } else if (ret > 0) {
pcercuei 0:03b5121a232e 24237 if (fireErrors)
pcercuei 0:03b5121a232e 24238 xmlSchemaFacetErr(actxt, ret, node,
pcercuei 0:03b5121a232e 24239 value, len, type, facetLink->facet, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 24240 else
pcercuei 0:03b5121a232e 24241 return (ret);
pcercuei 0:03b5121a232e 24242 if (error == 0)
pcercuei 0:03b5121a232e 24243 error = ret;
pcercuei 0:03b5121a232e 24244 }
pcercuei 0:03b5121a232e 24245 ret = 0;
pcercuei 0:03b5121a232e 24246 }
pcercuei 0:03b5121a232e 24247
pcercuei 0:03b5121a232e 24248 WXS_IS_LIST:
pcercuei 0:03b5121a232e 24249 if (! WXS_IS_LIST(type))
pcercuei 0:03b5121a232e 24250 goto pattern_and_enum;
pcercuei 0:03b5121a232e 24251 /*
pcercuei 0:03b5121a232e 24252 * "length", "minLength" and "maxLength" of list types.
pcercuei 0:03b5121a232e 24253 */
pcercuei 0:03b5121a232e 24254 ret = 0;
pcercuei 0:03b5121a232e 24255 for (facetLink = type->facetSet; facetLink != NULL;
pcercuei 0:03b5121a232e 24256 facetLink = facetLink->next) {
pcercuei 0:03b5121a232e 24257
pcercuei 0:03b5121a232e 24258 switch (facetLink->facet->type) {
pcercuei 0:03b5121a232e 24259 case XML_SCHEMA_FACET_LENGTH:
pcercuei 0:03b5121a232e 24260 case XML_SCHEMA_FACET_MINLENGTH:
pcercuei 0:03b5121a232e 24261 case XML_SCHEMA_FACET_MAXLENGTH:
pcercuei 0:03b5121a232e 24262 ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
pcercuei 0:03b5121a232e 24263 value, length, NULL);
pcercuei 0:03b5121a232e 24264 break;
pcercuei 0:03b5121a232e 24265 default:
pcercuei 0:03b5121a232e 24266 continue;
pcercuei 0:03b5121a232e 24267 }
pcercuei 0:03b5121a232e 24268 if (ret < 0) {
pcercuei 0:03b5121a232e 24269 AERROR_INT("xmlSchemaValidateFacets",
pcercuei 0:03b5121a232e 24270 "validating against a list type facet");
pcercuei 0:03b5121a232e 24271 return (-1);
pcercuei 0:03b5121a232e 24272 } else if (ret > 0) {
pcercuei 0:03b5121a232e 24273 if (fireErrors)
pcercuei 0:03b5121a232e 24274 xmlSchemaFacetErr(actxt, ret, node,
pcercuei 0:03b5121a232e 24275 value, length, type, facetLink->facet, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 24276 else
pcercuei 0:03b5121a232e 24277 return (ret);
pcercuei 0:03b5121a232e 24278 if (error == 0)
pcercuei 0:03b5121a232e 24279 error = ret;
pcercuei 0:03b5121a232e 24280 }
pcercuei 0:03b5121a232e 24281 ret = 0;
pcercuei 0:03b5121a232e 24282 }
pcercuei 0:03b5121a232e 24283
pcercuei 0:03b5121a232e 24284 pattern_and_enum:
pcercuei 0:03b5121a232e 24285 if (error >= 0) {
pcercuei 0:03b5121a232e 24286 int found = 0;
pcercuei 0:03b5121a232e 24287 /*
pcercuei 0:03b5121a232e 24288 * Process enumerations. Facet values are in the value space
pcercuei 0:03b5121a232e 24289 * of the defining type's base type. This seems to be a bug in the
pcercuei 0:03b5121a232e 24290 * XML Schema 1.0 spec. Use the whitespace type of the base type.
pcercuei 0:03b5121a232e 24291 * Only the first set of enumerations in the ancestor-or-self axis
pcercuei 0:03b5121a232e 24292 * is used for validation.
pcercuei 0:03b5121a232e 24293 */
pcercuei 0:03b5121a232e 24294 ret = 0;
pcercuei 0:03b5121a232e 24295 tmpType = type;
pcercuei 0:03b5121a232e 24296 do {
pcercuei 0:03b5121a232e 24297 for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
pcercuei 0:03b5121a232e 24298 if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
pcercuei 0:03b5121a232e 24299 continue;
pcercuei 0:03b5121a232e 24300 found = 1;
pcercuei 0:03b5121a232e 24301 ret = xmlSchemaAreValuesEqual(facet->val, val);
pcercuei 0:03b5121a232e 24302 if (ret == 1)
pcercuei 0:03b5121a232e 24303 break;
pcercuei 0:03b5121a232e 24304 else if (ret < 0) {
pcercuei 0:03b5121a232e 24305 AERROR_INT("xmlSchemaValidateFacets",
pcercuei 0:03b5121a232e 24306 "validating against an enumeration facet");
pcercuei 0:03b5121a232e 24307 return (-1);
pcercuei 0:03b5121a232e 24308 }
pcercuei 0:03b5121a232e 24309 }
pcercuei 0:03b5121a232e 24310 if (ret != 0)
pcercuei 0:03b5121a232e 24311 break;
pcercuei 0:03b5121a232e 24312 /*
pcercuei 0:03b5121a232e 24313 * Break on the first set of enumerations. Any additional
pcercuei 0:03b5121a232e 24314 * enumerations which might be existent on the ancestors
pcercuei 0:03b5121a232e 24315 * of the current type are restricted by this set; thus
pcercuei 0:03b5121a232e 24316 * *must* *not* be taken into account.
pcercuei 0:03b5121a232e 24317 */
pcercuei 0:03b5121a232e 24318 if (found)
pcercuei 0:03b5121a232e 24319 break;
pcercuei 0:03b5121a232e 24320 tmpType = tmpType->baseType;
pcercuei 0:03b5121a232e 24321 } while ((tmpType != NULL) &&
pcercuei 0:03b5121a232e 24322 (tmpType->type != XML_SCHEMA_TYPE_BASIC));
pcercuei 0:03b5121a232e 24323 if (found && (ret == 0)) {
pcercuei 0:03b5121a232e 24324 ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
pcercuei 0:03b5121a232e 24325 if (fireErrors) {
pcercuei 0:03b5121a232e 24326 xmlSchemaFacetErr(actxt, ret, node,
pcercuei 0:03b5121a232e 24327 value, 0, type, NULL, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 24328 } else
pcercuei 0:03b5121a232e 24329 return (ret);
pcercuei 0:03b5121a232e 24330 if (error == 0)
pcercuei 0:03b5121a232e 24331 error = ret;
pcercuei 0:03b5121a232e 24332 }
pcercuei 0:03b5121a232e 24333 }
pcercuei 0:03b5121a232e 24334
pcercuei 0:03b5121a232e 24335 if (error >= 0) {
pcercuei 0:03b5121a232e 24336 int found;
pcercuei 0:03b5121a232e 24337 /*
pcercuei 0:03b5121a232e 24338 * Process patters. Pattern facets are ORed at type level
pcercuei 0:03b5121a232e 24339 * and ANDed if derived. Walk the base type axis.
pcercuei 0:03b5121a232e 24340 */
pcercuei 0:03b5121a232e 24341 tmpType = type;
pcercuei 0:03b5121a232e 24342 facet = NULL;
pcercuei 0:03b5121a232e 24343 do {
pcercuei 0:03b5121a232e 24344 found = 0;
pcercuei 0:03b5121a232e 24345 for (facetLink = tmpType->facetSet; facetLink != NULL;
pcercuei 0:03b5121a232e 24346 facetLink = facetLink->next) {
pcercuei 0:03b5121a232e 24347 if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
pcercuei 0:03b5121a232e 24348 continue;
pcercuei 0:03b5121a232e 24349 found = 1;
pcercuei 0:03b5121a232e 24350 /*
pcercuei 0:03b5121a232e 24351 * NOTE that for patterns, @value needs to be the
pcercuei 0:03b5121a232e 24352 * normalized vaule.
pcercuei 0:03b5121a232e 24353 */
pcercuei 0:03b5121a232e 24354 ret = xmlRegexpExec(facetLink->facet->regexp, value);
pcercuei 0:03b5121a232e 24355 if (ret == 1)
pcercuei 0:03b5121a232e 24356 break;
pcercuei 0:03b5121a232e 24357 else if (ret < 0) {
pcercuei 0:03b5121a232e 24358 AERROR_INT("xmlSchemaValidateFacets",
pcercuei 0:03b5121a232e 24359 "validating against a pattern facet");
pcercuei 0:03b5121a232e 24360 return (-1);
pcercuei 0:03b5121a232e 24361 } else {
pcercuei 0:03b5121a232e 24362 /*
pcercuei 0:03b5121a232e 24363 * Save the last non-validating facet.
pcercuei 0:03b5121a232e 24364 */
pcercuei 0:03b5121a232e 24365 facet = facetLink->facet;
pcercuei 0:03b5121a232e 24366 }
pcercuei 0:03b5121a232e 24367 }
pcercuei 0:03b5121a232e 24368 if (found && (ret != 1)) {
pcercuei 0:03b5121a232e 24369 ret = XML_SCHEMAV_CVC_PATTERN_VALID;
pcercuei 0:03b5121a232e 24370 if (fireErrors) {
pcercuei 0:03b5121a232e 24371 xmlSchemaFacetErr(actxt, ret, node,
pcercuei 0:03b5121a232e 24372 value, 0, type, facet, NULL, NULL, NULL);
pcercuei 0:03b5121a232e 24373 } else
pcercuei 0:03b5121a232e 24374 return (ret);
pcercuei 0:03b5121a232e 24375 if (error == 0)
pcercuei 0:03b5121a232e 24376 error = ret;
pcercuei 0:03b5121a232e 24377 break;
pcercuei 0:03b5121a232e 24378 }
pcercuei 0:03b5121a232e 24379 tmpType = tmpType->baseType;
pcercuei 0:03b5121a232e 24380 } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
pcercuei 0:03b5121a232e 24381 }
pcercuei 0:03b5121a232e 24382
pcercuei 0:03b5121a232e 24383 return (error);
pcercuei 0:03b5121a232e 24384 }
pcercuei 0:03b5121a232e 24385
pcercuei 0:03b5121a232e 24386 static xmlChar *
pcercuei 0:03b5121a232e 24387 xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 24388 const xmlChar *value)
pcercuei 0:03b5121a232e 24389 {
pcercuei 0:03b5121a232e 24390 switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
pcercuei 0:03b5121a232e 24391 case XML_SCHEMA_WHITESPACE_COLLAPSE:
pcercuei 0:03b5121a232e 24392 return (xmlSchemaCollapseString(value));
pcercuei 0:03b5121a232e 24393 case XML_SCHEMA_WHITESPACE_REPLACE:
pcercuei 0:03b5121a232e 24394 return (xmlSchemaWhiteSpaceReplace(value));
pcercuei 0:03b5121a232e 24395 default:
pcercuei 0:03b5121a232e 24396 return (NULL);
pcercuei 0:03b5121a232e 24397 }
pcercuei 0:03b5121a232e 24398 }
pcercuei 0:03b5121a232e 24399
pcercuei 0:03b5121a232e 24400 static int
pcercuei 0:03b5121a232e 24401 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 24402 const xmlChar *value,
pcercuei 0:03b5121a232e 24403 xmlSchemaValPtr *val,
pcercuei 0:03b5121a232e 24404 int valNeeded)
pcercuei 0:03b5121a232e 24405 {
pcercuei 0:03b5121a232e 24406 int ret;
pcercuei 0:03b5121a232e 24407 const xmlChar *nsName;
pcercuei 0:03b5121a232e 24408 xmlChar *local, *prefix = NULL;
pcercuei 0:03b5121a232e 24409
pcercuei 0:03b5121a232e 24410 ret = xmlValidateQName(value, 1);
pcercuei 0:03b5121a232e 24411 if (ret != 0) {
pcercuei 0:03b5121a232e 24412 if (ret == -1) {
pcercuei 0:03b5121a232e 24413 VERROR_INT("xmlSchemaValidateQName",
pcercuei 0:03b5121a232e 24414 "calling xmlValidateQName()");
pcercuei 0:03b5121a232e 24415 return (-1);
pcercuei 0:03b5121a232e 24416 }
pcercuei 0:03b5121a232e 24417 return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
pcercuei 0:03b5121a232e 24418 }
pcercuei 0:03b5121a232e 24419 /*
pcercuei 0:03b5121a232e 24420 * NOTE: xmlSplitQName2 will always return a duplicated
pcercuei 0:03b5121a232e 24421 * strings.
pcercuei 0:03b5121a232e 24422 */
pcercuei 0:03b5121a232e 24423 local = xmlSplitQName2(value, &prefix);
pcercuei 0:03b5121a232e 24424 if (local == NULL)
pcercuei 0:03b5121a232e 24425 local = xmlStrdup(value);
pcercuei 0:03b5121a232e 24426 /*
pcercuei 0:03b5121a232e 24427 * OPTIMIZE TODO: Use flags for:
pcercuei 0:03b5121a232e 24428 * - is there any namespace binding?
pcercuei 0:03b5121a232e 24429 * - is there a default namespace?
pcercuei 0:03b5121a232e 24430 */
pcercuei 0:03b5121a232e 24431 nsName = xmlSchemaLookupNamespace(vctxt, prefix);
pcercuei 0:03b5121a232e 24432
pcercuei 0:03b5121a232e 24433 if (prefix != NULL) {
pcercuei 0:03b5121a232e 24434 xmlFree(prefix);
pcercuei 0:03b5121a232e 24435 /*
pcercuei 0:03b5121a232e 24436 * A namespace must be found if the prefix is
pcercuei 0:03b5121a232e 24437 * NOT NULL.
pcercuei 0:03b5121a232e 24438 */
pcercuei 0:03b5121a232e 24439 if (nsName == NULL) {
pcercuei 0:03b5121a232e 24440 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
pcercuei 0:03b5121a232e 24441 xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
pcercuei 0:03b5121a232e 24442 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
pcercuei 0:03b5121a232e 24443 "The QName value '%s' has no "
pcercuei 0:03b5121a232e 24444 "corresponding namespace declaration in "
pcercuei 0:03b5121a232e 24445 "scope", value, NULL);
pcercuei 0:03b5121a232e 24446 if (local != NULL)
pcercuei 0:03b5121a232e 24447 xmlFree(local);
pcercuei 0:03b5121a232e 24448 return (ret);
pcercuei 0:03b5121a232e 24449 }
pcercuei 0:03b5121a232e 24450 }
pcercuei 0:03b5121a232e 24451 if (valNeeded && val) {
pcercuei 0:03b5121a232e 24452 if (nsName != NULL)
pcercuei 0:03b5121a232e 24453 *val = xmlSchemaNewQNameValue(
pcercuei 0:03b5121a232e 24454 BAD_CAST xmlStrdup(nsName), BAD_CAST local);
pcercuei 0:03b5121a232e 24455 else
pcercuei 0:03b5121a232e 24456 *val = xmlSchemaNewQNameValue(NULL,
pcercuei 0:03b5121a232e 24457 BAD_CAST local);
pcercuei 0:03b5121a232e 24458 } else
pcercuei 0:03b5121a232e 24459 xmlFree(local);
pcercuei 0:03b5121a232e 24460 return (0);
pcercuei 0:03b5121a232e 24461 }
pcercuei 0:03b5121a232e 24462
pcercuei 0:03b5121a232e 24463 /*
pcercuei 0:03b5121a232e 24464 * cvc-simple-type
pcercuei 0:03b5121a232e 24465 */
pcercuei 0:03b5121a232e 24466 static int
pcercuei 0:03b5121a232e 24467 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
pcercuei 0:03b5121a232e 24468 xmlNodePtr node,
pcercuei 0:03b5121a232e 24469 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 24470 const xmlChar *value,
pcercuei 0:03b5121a232e 24471 xmlSchemaValPtr *retVal,
pcercuei 0:03b5121a232e 24472 int fireErrors,
pcercuei 0:03b5121a232e 24473 int normalize,
pcercuei 0:03b5121a232e 24474 int isNormalized)
pcercuei 0:03b5121a232e 24475 {
pcercuei 0:03b5121a232e 24476 int ret = 0, valNeeded = (retVal) ? 1 : 0;
pcercuei 0:03b5121a232e 24477 xmlSchemaValPtr val = NULL;
pcercuei 0:03b5121a232e 24478 /* xmlSchemaWhitespaceValueType ws; */
pcercuei 0:03b5121a232e 24479 xmlChar *normValue = NULL;
pcercuei 0:03b5121a232e 24480
pcercuei 0:03b5121a232e 24481 #define NORMALIZE(atype) \
pcercuei 0:03b5121a232e 24482 if ((! isNormalized) && \
pcercuei 0:03b5121a232e 24483 (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
pcercuei 0:03b5121a232e 24484 normValue = xmlSchemaNormalizeValue(atype, value); \
pcercuei 0:03b5121a232e 24485 if (normValue != NULL) \
pcercuei 0:03b5121a232e 24486 value = normValue; \
pcercuei 0:03b5121a232e 24487 isNormalized = 1; \
pcercuei 0:03b5121a232e 24488 }
pcercuei 0:03b5121a232e 24489
pcercuei 0:03b5121a232e 24490 if ((retVal != NULL) && (*retVal != NULL)) {
pcercuei 0:03b5121a232e 24491 xmlSchemaFreeValue(*retVal);
pcercuei 0:03b5121a232e 24492 *retVal = NULL;
pcercuei 0:03b5121a232e 24493 }
pcercuei 0:03b5121a232e 24494 /*
pcercuei 0:03b5121a232e 24495 * 3.14.4 Simple Type Definition Validation Rules
pcercuei 0:03b5121a232e 24496 * Validation Rule: String Valid
pcercuei 0:03b5121a232e 24497 */
pcercuei 0:03b5121a232e 24498 /*
pcercuei 0:03b5121a232e 24499 * 1 It is schema-valid with respect to that definition as defined
pcercuei 0:03b5121a232e 24500 * by Datatype Valid in [XML Schemas: Datatypes].
pcercuei 0:03b5121a232e 24501 */
pcercuei 0:03b5121a232e 24502 /*
pcercuei 0:03b5121a232e 24503 * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
pcercuei 0:03b5121a232e 24504 * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
pcercuei 0:03b5121a232e 24505 * the string must be a `declared entity name`.
pcercuei 0:03b5121a232e 24506 */
pcercuei 0:03b5121a232e 24507 /*
pcercuei 0:03b5121a232e 24508 * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
pcercuei 0:03b5121a232e 24509 * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
pcercuei 0:03b5121a232e 24510 * then every whitespace-delimited substring of the string must be a `declared
pcercuei 0:03b5121a232e 24511 * entity name`.
pcercuei 0:03b5121a232e 24512 */
pcercuei 0:03b5121a232e 24513 /*
pcercuei 0:03b5121a232e 24514 * 2.3 otherwise no further condition applies.
pcercuei 0:03b5121a232e 24515 */
pcercuei 0:03b5121a232e 24516 if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
pcercuei 0:03b5121a232e 24517 valNeeded = 1;
pcercuei 0:03b5121a232e 24518 if (value == NULL)
pcercuei 0:03b5121a232e 24519 value = BAD_CAST "";
pcercuei 0:03b5121a232e 24520 if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
pcercuei 0:03b5121a232e 24521 xmlSchemaTypePtr biType; /* The built-in type. */
pcercuei 0:03b5121a232e 24522 /*
pcercuei 0:03b5121a232e 24523 * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
pcercuei 0:03b5121a232e 24524 * a literal in the `lexical space` of {base type definition}"
pcercuei 0:03b5121a232e 24525 */
pcercuei 0:03b5121a232e 24526 /*
pcercuei 0:03b5121a232e 24527 * Whitespace-normalize.
pcercuei 0:03b5121a232e 24528 */
pcercuei 0:03b5121a232e 24529 NORMALIZE(type);
pcercuei 0:03b5121a232e 24530 if (type->type != XML_SCHEMA_TYPE_BASIC) {
pcercuei 0:03b5121a232e 24531 /*
pcercuei 0:03b5121a232e 24532 * Get the built-in type.
pcercuei 0:03b5121a232e 24533 */
pcercuei 0:03b5121a232e 24534 biType = type->baseType;
pcercuei 0:03b5121a232e 24535 while ((biType != NULL) &&
pcercuei 0:03b5121a232e 24536 (biType->type != XML_SCHEMA_TYPE_BASIC))
pcercuei 0:03b5121a232e 24537 biType = biType->baseType;
pcercuei 0:03b5121a232e 24538
pcercuei 0:03b5121a232e 24539 if (biType == NULL) {
pcercuei 0:03b5121a232e 24540 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
pcercuei 0:03b5121a232e 24541 "could not get the built-in type");
pcercuei 0:03b5121a232e 24542 goto internal_error;
pcercuei 0:03b5121a232e 24543 }
pcercuei 0:03b5121a232e 24544 } else
pcercuei 0:03b5121a232e 24545 biType = type;
pcercuei 0:03b5121a232e 24546 /*
pcercuei 0:03b5121a232e 24547 * NOTATIONs need to be processed here, since they need
pcercuei 0:03b5121a232e 24548 * to lookup in the hashtable of NOTATION declarations of the schema.
pcercuei 0:03b5121a232e 24549 */
pcercuei 0:03b5121a232e 24550 if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
pcercuei 0:03b5121a232e 24551 switch (biType->builtInType) {
pcercuei 0:03b5121a232e 24552 case XML_SCHEMAS_NOTATION:
pcercuei 0:03b5121a232e 24553 ret = xmlSchemaValidateNotation(
pcercuei 0:03b5121a232e 24554 (xmlSchemaValidCtxtPtr) actxt,
pcercuei 0:03b5121a232e 24555 ((xmlSchemaValidCtxtPtr) actxt)->schema,
pcercuei 0:03b5121a232e 24556 NULL, value, &val, valNeeded);
pcercuei 0:03b5121a232e 24557 break;
pcercuei 0:03b5121a232e 24558 case XML_SCHEMAS_QNAME:
pcercuei 0:03b5121a232e 24559 ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
pcercuei 0:03b5121a232e 24560 value, &val, valNeeded);
pcercuei 0:03b5121a232e 24561 break;
pcercuei 0:03b5121a232e 24562 default:
pcercuei 0:03b5121a232e 24563 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
pcercuei 0:03b5121a232e 24564 if (valNeeded)
pcercuei 0:03b5121a232e 24565 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
pcercuei 0:03b5121a232e 24566 value, &val, node);
pcercuei 0:03b5121a232e 24567 else
pcercuei 0:03b5121a232e 24568 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
pcercuei 0:03b5121a232e 24569 value, NULL, node);
pcercuei 0:03b5121a232e 24570 break;
pcercuei 0:03b5121a232e 24571 }
pcercuei 0:03b5121a232e 24572 } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
pcercuei 0:03b5121a232e 24573 switch (biType->builtInType) {
pcercuei 0:03b5121a232e 24574 case XML_SCHEMAS_NOTATION:
pcercuei 0:03b5121a232e 24575 ret = xmlSchemaValidateNotation(NULL,
pcercuei 0:03b5121a232e 24576 ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
pcercuei 0:03b5121a232e 24577 value, &val, valNeeded);
pcercuei 0:03b5121a232e 24578 break;
pcercuei 0:03b5121a232e 24579 default:
pcercuei 0:03b5121a232e 24580 /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
pcercuei 0:03b5121a232e 24581 if (valNeeded)
pcercuei 0:03b5121a232e 24582 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
pcercuei 0:03b5121a232e 24583 value, &val, node);
pcercuei 0:03b5121a232e 24584 else
pcercuei 0:03b5121a232e 24585 ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
pcercuei 0:03b5121a232e 24586 value, NULL, node);
pcercuei 0:03b5121a232e 24587 break;
pcercuei 0:03b5121a232e 24588 }
pcercuei 0:03b5121a232e 24589 } else {
pcercuei 0:03b5121a232e 24590 /*
pcercuei 0:03b5121a232e 24591 * Validation via a public API is not implemented yet.
pcercuei 0:03b5121a232e 24592 */
pcercuei 0:03b5121a232e 24593 TODO
pcercuei 0:03b5121a232e 24594 goto internal_error;
pcercuei 0:03b5121a232e 24595 }
pcercuei 0:03b5121a232e 24596 if (ret != 0) {
pcercuei 0:03b5121a232e 24597 if (ret < 0) {
pcercuei 0:03b5121a232e 24598 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
pcercuei 0:03b5121a232e 24599 "validating against a built-in type");
pcercuei 0:03b5121a232e 24600 goto internal_error;
pcercuei 0:03b5121a232e 24601 }
pcercuei 0:03b5121a232e 24602 if (WXS_IS_LIST(type))
pcercuei 0:03b5121a232e 24603 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
pcercuei 0:03b5121a232e 24604 else
pcercuei 0:03b5121a232e 24605 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
pcercuei 0:03b5121a232e 24606 }
pcercuei 0:03b5121a232e 24607 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
pcercuei 0:03b5121a232e 24608 /*
pcercuei 0:03b5121a232e 24609 * Check facets.
pcercuei 0:03b5121a232e 24610 */
pcercuei 0:03b5121a232e 24611 ret = xmlSchemaValidateFacets(actxt, node, type,
pcercuei 0:03b5121a232e 24612 (xmlSchemaValType) biType->builtInType, value, val,
pcercuei 0:03b5121a232e 24613 0, fireErrors);
pcercuei 0:03b5121a232e 24614 if (ret != 0) {
pcercuei 0:03b5121a232e 24615 if (ret < 0) {
pcercuei 0:03b5121a232e 24616 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
pcercuei 0:03b5121a232e 24617 "validating facets of atomic simple type");
pcercuei 0:03b5121a232e 24618 goto internal_error;
pcercuei 0:03b5121a232e 24619 }
pcercuei 0:03b5121a232e 24620 if (WXS_IS_LIST(type))
pcercuei 0:03b5121a232e 24621 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
pcercuei 0:03b5121a232e 24622 else
pcercuei 0:03b5121a232e 24623 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
pcercuei 0:03b5121a232e 24624 }
pcercuei 0:03b5121a232e 24625 }
pcercuei 0:03b5121a232e 24626 if (fireErrors && (ret > 0))
pcercuei 0:03b5121a232e 24627 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
pcercuei 0:03b5121a232e 24628 } else if (WXS_IS_LIST(type)) {
pcercuei 0:03b5121a232e 24629
pcercuei 0:03b5121a232e 24630 xmlSchemaTypePtr itemType;
pcercuei 0:03b5121a232e 24631 const xmlChar *cur, *end;
pcercuei 0:03b5121a232e 24632 xmlChar *tmpValue = NULL;
pcercuei 0:03b5121a232e 24633 unsigned long len = 0;
pcercuei 0:03b5121a232e 24634 xmlSchemaValPtr prevVal = NULL, curVal = NULL;
pcercuei 0:03b5121a232e 24635 /* 1.2.2 if {variety} is `list` then the string must be a sequence
pcercuei 0:03b5121a232e 24636 * of white space separated tokens, each of which `match`es a literal
pcercuei 0:03b5121a232e 24637 * in the `lexical space` of {item type definition}
pcercuei 0:03b5121a232e 24638 */
pcercuei 0:03b5121a232e 24639 /*
pcercuei 0:03b5121a232e 24640 * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
pcercuei 0:03b5121a232e 24641 * the list type has an enum or pattern facet.
pcercuei 0:03b5121a232e 24642 */
pcercuei 0:03b5121a232e 24643 NORMALIZE(type);
pcercuei 0:03b5121a232e 24644 /*
pcercuei 0:03b5121a232e 24645 * VAL TODO: Optimize validation of empty values.
pcercuei 0:03b5121a232e 24646 * VAL TODO: We do not have computed values for lists.
pcercuei 0:03b5121a232e 24647 */
pcercuei 0:03b5121a232e 24648 itemType = WXS_LIST_ITEMTYPE(type);
pcercuei 0:03b5121a232e 24649 cur = value;
pcercuei 0:03b5121a232e 24650 do {
pcercuei 0:03b5121a232e 24651 while (IS_BLANK_CH(*cur))
pcercuei 0:03b5121a232e 24652 cur++;
pcercuei 0:03b5121a232e 24653 end = cur;
pcercuei 0:03b5121a232e 24654 while ((*end != 0) && (!(IS_BLANK_CH(*end))))
pcercuei 0:03b5121a232e 24655 end++;
pcercuei 0:03b5121a232e 24656 if (end == cur)
pcercuei 0:03b5121a232e 24657 break;
pcercuei 0:03b5121a232e 24658 tmpValue = xmlStrndup(cur, end - cur);
pcercuei 0:03b5121a232e 24659 len++;
pcercuei 0:03b5121a232e 24660
pcercuei 0:03b5121a232e 24661 if (valNeeded)
pcercuei 0:03b5121a232e 24662 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
pcercuei 0:03b5121a232e 24663 tmpValue, &curVal, fireErrors, 0, 1);
pcercuei 0:03b5121a232e 24664 else
pcercuei 0:03b5121a232e 24665 ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
pcercuei 0:03b5121a232e 24666 tmpValue, NULL, fireErrors, 0, 1);
pcercuei 0:03b5121a232e 24667 FREE_AND_NULL(tmpValue);
pcercuei 0:03b5121a232e 24668 if (curVal != NULL) {
pcercuei 0:03b5121a232e 24669 /*
pcercuei 0:03b5121a232e 24670 * Add to list of computed values.
pcercuei 0:03b5121a232e 24671 */
pcercuei 0:03b5121a232e 24672 if (val == NULL)
pcercuei 0:03b5121a232e 24673 val = curVal;
pcercuei 0:03b5121a232e 24674 else
pcercuei 0:03b5121a232e 24675 xmlSchemaValueAppend(prevVal, curVal);
pcercuei 0:03b5121a232e 24676 prevVal = curVal;
pcercuei 0:03b5121a232e 24677 curVal = NULL;
pcercuei 0:03b5121a232e 24678 }
pcercuei 0:03b5121a232e 24679 if (ret != 0) {
pcercuei 0:03b5121a232e 24680 if (ret < 0) {
pcercuei 0:03b5121a232e 24681 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
pcercuei 0:03b5121a232e 24682 "validating an item of list simple type");
pcercuei 0:03b5121a232e 24683 goto internal_error;
pcercuei 0:03b5121a232e 24684 }
pcercuei 0:03b5121a232e 24685 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
pcercuei 0:03b5121a232e 24686 break;
pcercuei 0:03b5121a232e 24687 }
pcercuei 0:03b5121a232e 24688 cur = end;
pcercuei 0:03b5121a232e 24689 } while (*cur != 0);
pcercuei 0:03b5121a232e 24690 FREE_AND_NULL(tmpValue);
pcercuei 0:03b5121a232e 24691 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
pcercuei 0:03b5121a232e 24692 /*
pcercuei 0:03b5121a232e 24693 * Apply facets (pattern, enumeration).
pcercuei 0:03b5121a232e 24694 */
pcercuei 0:03b5121a232e 24695 ret = xmlSchemaValidateFacets(actxt, node, type,
pcercuei 0:03b5121a232e 24696 XML_SCHEMAS_UNKNOWN, value, val,
pcercuei 0:03b5121a232e 24697 len, fireErrors);
pcercuei 0:03b5121a232e 24698 if (ret != 0) {
pcercuei 0:03b5121a232e 24699 if (ret < 0) {
pcercuei 0:03b5121a232e 24700 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
pcercuei 0:03b5121a232e 24701 "validating facets of list simple type");
pcercuei 0:03b5121a232e 24702 goto internal_error;
pcercuei 0:03b5121a232e 24703 }
pcercuei 0:03b5121a232e 24704 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
pcercuei 0:03b5121a232e 24705 }
pcercuei 0:03b5121a232e 24706 }
pcercuei 0:03b5121a232e 24707 if (fireErrors && (ret > 0)) {
pcercuei 0:03b5121a232e 24708 /*
pcercuei 0:03b5121a232e 24709 * Report the normalized value.
pcercuei 0:03b5121a232e 24710 */
pcercuei 0:03b5121a232e 24711 normalize = 1;
pcercuei 0:03b5121a232e 24712 NORMALIZE(type);
pcercuei 0:03b5121a232e 24713 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
pcercuei 0:03b5121a232e 24714 }
pcercuei 0:03b5121a232e 24715 } else if (WXS_IS_UNION(type)) {
pcercuei 0:03b5121a232e 24716 xmlSchemaTypeLinkPtr memberLink;
pcercuei 0:03b5121a232e 24717 /*
pcercuei 0:03b5121a232e 24718 * TODO: For all datatypes `derived` by `union` whiteSpace does
pcercuei 0:03b5121a232e 24719 * not apply directly; however, the normalization behavior of `union`
pcercuei 0:03b5121a232e 24720 * types is controlled by the value of whiteSpace on that one of the
pcercuei 0:03b5121a232e 24721 * `memberTypes` against which the `union` is successfully validated.
pcercuei 0:03b5121a232e 24722 *
pcercuei 0:03b5121a232e 24723 * This means that the value is normalized by the first validating
pcercuei 0:03b5121a232e 24724 * member type, then the facets of the union type are applied. This
pcercuei 0:03b5121a232e 24725 * needs changing of the value!
pcercuei 0:03b5121a232e 24726 */
pcercuei 0:03b5121a232e 24727
pcercuei 0:03b5121a232e 24728 /*
pcercuei 0:03b5121a232e 24729 * 1.2.3 if {variety} is `union` then the string must `match` a
pcercuei 0:03b5121a232e 24730 * literal in the `lexical space` of at least one member of
pcercuei 0:03b5121a232e 24731 * {member type definitions}
pcercuei 0:03b5121a232e 24732 */
pcercuei 0:03b5121a232e 24733 memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
pcercuei 0:03b5121a232e 24734 if (memberLink == NULL) {
pcercuei 0:03b5121a232e 24735 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
pcercuei 0:03b5121a232e 24736 "union simple type has no member types");
pcercuei 0:03b5121a232e 24737 goto internal_error;
pcercuei 0:03b5121a232e 24738 }
pcercuei 0:03b5121a232e 24739 /*
pcercuei 0:03b5121a232e 24740 * Always normalize union type values, since we currently
pcercuei 0:03b5121a232e 24741 * cannot store the whitespace information with the value
pcercuei 0:03b5121a232e 24742 * itself; otherwise a later value-comparison would be
pcercuei 0:03b5121a232e 24743 * not possible.
pcercuei 0:03b5121a232e 24744 */
pcercuei 0:03b5121a232e 24745 while (memberLink != NULL) {
pcercuei 0:03b5121a232e 24746 if (valNeeded)
pcercuei 0:03b5121a232e 24747 ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
pcercuei 0:03b5121a232e 24748 memberLink->type, value, &val, 0, 1, 0);
pcercuei 0:03b5121a232e 24749 else
pcercuei 0:03b5121a232e 24750 ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
pcercuei 0:03b5121a232e 24751 memberLink->type, value, NULL, 0, 1, 0);
pcercuei 0:03b5121a232e 24752 if (ret <= 0)
pcercuei 0:03b5121a232e 24753 break;
pcercuei 0:03b5121a232e 24754 memberLink = memberLink->next;
pcercuei 0:03b5121a232e 24755 }
pcercuei 0:03b5121a232e 24756 if (ret != 0) {
pcercuei 0:03b5121a232e 24757 if (ret < 0) {
pcercuei 0:03b5121a232e 24758 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
pcercuei 0:03b5121a232e 24759 "validating members of union simple type");
pcercuei 0:03b5121a232e 24760 goto internal_error;
pcercuei 0:03b5121a232e 24761 }
pcercuei 0:03b5121a232e 24762 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
pcercuei 0:03b5121a232e 24763 }
pcercuei 0:03b5121a232e 24764 /*
pcercuei 0:03b5121a232e 24765 * Apply facets (pattern, enumeration).
pcercuei 0:03b5121a232e 24766 */
pcercuei 0:03b5121a232e 24767 if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
pcercuei 0:03b5121a232e 24768 /*
pcercuei 0:03b5121a232e 24769 * The normalization behavior of `union` types is controlled by
pcercuei 0:03b5121a232e 24770 * the value of whiteSpace on that one of the `memberTypes`
pcercuei 0:03b5121a232e 24771 * against which the `union` is successfully validated.
pcercuei 0:03b5121a232e 24772 */
pcercuei 0:03b5121a232e 24773 NORMALIZE(memberLink->type);
pcercuei 0:03b5121a232e 24774 ret = xmlSchemaValidateFacets(actxt, node, type,
pcercuei 0:03b5121a232e 24775 XML_SCHEMAS_UNKNOWN, value, val,
pcercuei 0:03b5121a232e 24776 0, fireErrors);
pcercuei 0:03b5121a232e 24777 if (ret != 0) {
pcercuei 0:03b5121a232e 24778 if (ret < 0) {
pcercuei 0:03b5121a232e 24779 AERROR_INT("xmlSchemaVCheckCVCSimpleType",
pcercuei 0:03b5121a232e 24780 "validating facets of union simple type");
pcercuei 0:03b5121a232e 24781 goto internal_error;
pcercuei 0:03b5121a232e 24782 }
pcercuei 0:03b5121a232e 24783 ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
pcercuei 0:03b5121a232e 24784 }
pcercuei 0:03b5121a232e 24785 }
pcercuei 0:03b5121a232e 24786 if (fireErrors && (ret > 0))
pcercuei 0:03b5121a232e 24787 xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
pcercuei 0:03b5121a232e 24788 }
pcercuei 0:03b5121a232e 24789
pcercuei 0:03b5121a232e 24790 if (normValue != NULL)
pcercuei 0:03b5121a232e 24791 xmlFree(normValue);
pcercuei 0:03b5121a232e 24792 if (ret == 0) {
pcercuei 0:03b5121a232e 24793 if (retVal != NULL)
pcercuei 0:03b5121a232e 24794 *retVal = val;
pcercuei 0:03b5121a232e 24795 else if (val != NULL)
pcercuei 0:03b5121a232e 24796 xmlSchemaFreeValue(val);
pcercuei 0:03b5121a232e 24797 } else if (val != NULL)
pcercuei 0:03b5121a232e 24798 xmlSchemaFreeValue(val);
pcercuei 0:03b5121a232e 24799 return (ret);
pcercuei 0:03b5121a232e 24800 internal_error:
pcercuei 0:03b5121a232e 24801 if (normValue != NULL)
pcercuei 0:03b5121a232e 24802 xmlFree(normValue);
pcercuei 0:03b5121a232e 24803 if (val != NULL)
pcercuei 0:03b5121a232e 24804 xmlSchemaFreeValue(val);
pcercuei 0:03b5121a232e 24805 return (-1);
pcercuei 0:03b5121a232e 24806 }
pcercuei 0:03b5121a232e 24807
pcercuei 0:03b5121a232e 24808 static int
pcercuei 0:03b5121a232e 24809 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 24810 const xmlChar *value,
pcercuei 0:03b5121a232e 24811 const xmlChar **nsName,
pcercuei 0:03b5121a232e 24812 const xmlChar **localName)
pcercuei 0:03b5121a232e 24813 {
pcercuei 0:03b5121a232e 24814 int ret = 0;
pcercuei 0:03b5121a232e 24815
pcercuei 0:03b5121a232e 24816 if ((nsName == NULL) || (localName == NULL))
pcercuei 0:03b5121a232e 24817 return (-1);
pcercuei 0:03b5121a232e 24818 *nsName = NULL;
pcercuei 0:03b5121a232e 24819 *localName = NULL;
pcercuei 0:03b5121a232e 24820
pcercuei 0:03b5121a232e 24821 ret = xmlValidateQName(value, 1);
pcercuei 0:03b5121a232e 24822 if (ret == -1)
pcercuei 0:03b5121a232e 24823 return (-1);
pcercuei 0:03b5121a232e 24824 if (ret > 0) {
pcercuei 0:03b5121a232e 24825 xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 24826 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
pcercuei 0:03b5121a232e 24827 value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
pcercuei 0:03b5121a232e 24828 return (1);
pcercuei 0:03b5121a232e 24829 }
pcercuei 0:03b5121a232e 24830 {
pcercuei 0:03b5121a232e 24831 xmlChar *local = NULL;
pcercuei 0:03b5121a232e 24832 xmlChar *prefix;
pcercuei 0:03b5121a232e 24833
pcercuei 0:03b5121a232e 24834 /*
pcercuei 0:03b5121a232e 24835 * NOTE: xmlSplitQName2 will return a duplicated
pcercuei 0:03b5121a232e 24836 * string.
pcercuei 0:03b5121a232e 24837 */
pcercuei 0:03b5121a232e 24838 local = xmlSplitQName2(value, &prefix);
pcercuei 0:03b5121a232e 24839 if (local == NULL)
pcercuei 0:03b5121a232e 24840 *localName = xmlDictLookup(vctxt->dict, value, -1);
pcercuei 0:03b5121a232e 24841 else {
pcercuei 0:03b5121a232e 24842 *localName = xmlDictLookup(vctxt->dict, local, -1);
pcercuei 0:03b5121a232e 24843 xmlFree(local);
pcercuei 0:03b5121a232e 24844 }
pcercuei 0:03b5121a232e 24845
pcercuei 0:03b5121a232e 24846 *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
pcercuei 0:03b5121a232e 24847
pcercuei 0:03b5121a232e 24848 if (prefix != NULL) {
pcercuei 0:03b5121a232e 24849 xmlFree(prefix);
pcercuei 0:03b5121a232e 24850 /*
pcercuei 0:03b5121a232e 24851 * A namespace must be found if the prefix is NOT NULL.
pcercuei 0:03b5121a232e 24852 */
pcercuei 0:03b5121a232e 24853 if (*nsName == NULL) {
pcercuei 0:03b5121a232e 24854 xmlSchemaCustomErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 24855 XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
pcercuei 0:03b5121a232e 24856 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
pcercuei 0:03b5121a232e 24857 "The QName value '%s' has no "
pcercuei 0:03b5121a232e 24858 "corresponding namespace declaration in scope",
pcercuei 0:03b5121a232e 24859 value, NULL);
pcercuei 0:03b5121a232e 24860 return (2);
pcercuei 0:03b5121a232e 24861 }
pcercuei 0:03b5121a232e 24862 }
pcercuei 0:03b5121a232e 24863 }
pcercuei 0:03b5121a232e 24864 return (0);
pcercuei 0:03b5121a232e 24865 }
pcercuei 0:03b5121a232e 24866
pcercuei 0:03b5121a232e 24867 static int
pcercuei 0:03b5121a232e 24868 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 24869 xmlSchemaAttrInfoPtr iattr,
pcercuei 0:03b5121a232e 24870 xmlSchemaTypePtr *localType,
pcercuei 0:03b5121a232e 24871 xmlSchemaElementPtr elemDecl)
pcercuei 0:03b5121a232e 24872 {
pcercuei 0:03b5121a232e 24873 int ret = 0;
pcercuei 0:03b5121a232e 24874 /*
pcercuei 0:03b5121a232e 24875 * cvc-elt (3.3.4) : (4)
pcercuei 0:03b5121a232e 24876 * AND
pcercuei 0:03b5121a232e 24877 * Schema-Validity Assessment (Element) (cvc-assess-elt)
pcercuei 0:03b5121a232e 24878 * (1.2.1.2.1) - (1.2.1.2.4)
pcercuei 0:03b5121a232e 24879 * Handle 'xsi:type'.
pcercuei 0:03b5121a232e 24880 */
pcercuei 0:03b5121a232e 24881 if (localType == NULL)
pcercuei 0:03b5121a232e 24882 return (-1);
pcercuei 0:03b5121a232e 24883 *localType = NULL;
pcercuei 0:03b5121a232e 24884 if (iattr == NULL)
pcercuei 0:03b5121a232e 24885 return (0);
pcercuei 0:03b5121a232e 24886 else {
pcercuei 0:03b5121a232e 24887 const xmlChar *nsName = NULL, *local = NULL;
pcercuei 0:03b5121a232e 24888 /*
pcercuei 0:03b5121a232e 24889 * TODO: We should report a *warning* that the type was overriden
pcercuei 0:03b5121a232e 24890 * by the instance.
pcercuei 0:03b5121a232e 24891 */
pcercuei 0:03b5121a232e 24892 ACTIVATE_ATTRIBUTE(iattr);
pcercuei 0:03b5121a232e 24893 /*
pcercuei 0:03b5121a232e 24894 * (cvc-elt) (3.3.4) : (4.1)
pcercuei 0:03b5121a232e 24895 * (cvc-assess-elt) (1.2.1.2.2)
pcercuei 0:03b5121a232e 24896 */
pcercuei 0:03b5121a232e 24897 ret = xmlSchemaVExpandQName(vctxt, iattr->value,
pcercuei 0:03b5121a232e 24898 &nsName, &local);
pcercuei 0:03b5121a232e 24899 if (ret != 0) {
pcercuei 0:03b5121a232e 24900 if (ret < 0) {
pcercuei 0:03b5121a232e 24901 VERROR_INT("xmlSchemaValidateElementByDeclaration",
pcercuei 0:03b5121a232e 24902 "calling xmlSchemaQNameExpand() to validate the "
pcercuei 0:03b5121a232e 24903 "attribute 'xsi:type'");
pcercuei 0:03b5121a232e 24904 goto internal_error;
pcercuei 0:03b5121a232e 24905 }
pcercuei 0:03b5121a232e 24906 goto exit;
pcercuei 0:03b5121a232e 24907 }
pcercuei 0:03b5121a232e 24908 /*
pcercuei 0:03b5121a232e 24909 * (cvc-elt) (3.3.4) : (4.2)
pcercuei 0:03b5121a232e 24910 * (cvc-assess-elt) (1.2.1.2.3)
pcercuei 0:03b5121a232e 24911 */
pcercuei 0:03b5121a232e 24912 *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
pcercuei 0:03b5121a232e 24913 if (*localType == NULL) {
pcercuei 0:03b5121a232e 24914 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 24915
pcercuei 0:03b5121a232e 24916 xmlSchemaCustomErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 24917 XML_SCHEMAV_CVC_ELT_4_2, NULL,
pcercuei 0:03b5121a232e 24918 WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
pcercuei 0:03b5121a232e 24919 "The QName value '%s' of the xsi:type attribute does not "
pcercuei 0:03b5121a232e 24920 "resolve to a type definition",
pcercuei 0:03b5121a232e 24921 xmlSchemaFormatQName(&str, nsName, local), NULL);
pcercuei 0:03b5121a232e 24922 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 24923 ret = vctxt->err;
pcercuei 0:03b5121a232e 24924 goto exit;
pcercuei 0:03b5121a232e 24925 }
pcercuei 0:03b5121a232e 24926 if (elemDecl != NULL) {
pcercuei 0:03b5121a232e 24927 int set = 0;
pcercuei 0:03b5121a232e 24928
pcercuei 0:03b5121a232e 24929 /*
pcercuei 0:03b5121a232e 24930 * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
pcercuei 0:03b5121a232e 24931 * "The `local type definition` must be validly
pcercuei 0:03b5121a232e 24932 * derived from the {type definition} given the union of
pcercuei 0:03b5121a232e 24933 * the {disallowed substitutions} and the {type definition}'s
pcercuei 0:03b5121a232e 24934 * {prohibited substitutions}, as defined in
pcercuei 0:03b5121a232e 24935 * Type Derivation OK (Complex) ($3.4.6)
pcercuei 0:03b5121a232e 24936 * (if it is a complex type definition),
pcercuei 0:03b5121a232e 24937 * or given {disallowed substitutions} as defined in Type
pcercuei 0:03b5121a232e 24938 * Derivation OK (Simple) ($3.14.6) (if it is a simple type
pcercuei 0:03b5121a232e 24939 * definition)."
pcercuei 0:03b5121a232e 24940 *
pcercuei 0:03b5121a232e 24941 * {disallowed substitutions}: the "block" on the element decl.
pcercuei 0:03b5121a232e 24942 * {prohibited substitutions}: the "block" on the type def.
pcercuei 0:03b5121a232e 24943 */
pcercuei 0:03b5121a232e 24944 /*
pcercuei 0:03b5121a232e 24945 * OPTIMIZE TODO: We could map types already evaluated
pcercuei 0:03b5121a232e 24946 * to be validly derived from other types to avoid checking
pcercuei 0:03b5121a232e 24947 * this over and over for the same types.
pcercuei 0:03b5121a232e 24948 */
pcercuei 0:03b5121a232e 24949 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
pcercuei 0:03b5121a232e 24950 (elemDecl->subtypes->flags &
pcercuei 0:03b5121a232e 24951 XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
pcercuei 0:03b5121a232e 24952 set |= SUBSET_EXTENSION;
pcercuei 0:03b5121a232e 24953
pcercuei 0:03b5121a232e 24954 if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
pcercuei 0:03b5121a232e 24955 (elemDecl->subtypes->flags &
pcercuei 0:03b5121a232e 24956 XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
pcercuei 0:03b5121a232e 24957 set |= SUBSET_RESTRICTION;
pcercuei 0:03b5121a232e 24958
pcercuei 0:03b5121a232e 24959 /*
pcercuei 0:03b5121a232e 24960 * REMOVED and CHANGED since this produced a parser context
pcercuei 0:03b5121a232e 24961 * which adds to the string dict of the schema. So this would
pcercuei 0:03b5121a232e 24962 * change the schema and we don't want this. We don't need
pcercuei 0:03b5121a232e 24963 * the parser context anymore.
pcercuei 0:03b5121a232e 24964 *
pcercuei 0:03b5121a232e 24965 * if ((vctxt->pctxt == NULL) &&
pcercuei 0:03b5121a232e 24966 * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
pcercuei 0:03b5121a232e 24967 * return (-1);
pcercuei 0:03b5121a232e 24968 */
pcercuei 0:03b5121a232e 24969
pcercuei 0:03b5121a232e 24970 if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
pcercuei 0:03b5121a232e 24971 elemDecl->subtypes, set) != 0) {
pcercuei 0:03b5121a232e 24972 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 24973
pcercuei 0:03b5121a232e 24974 xmlSchemaCustomErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 24975 XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
pcercuei 0:03b5121a232e 24976 "The type definition '%s', specified by xsi:type, is "
pcercuei 0:03b5121a232e 24977 "blocked or not validly derived from the type definition "
pcercuei 0:03b5121a232e 24978 "of the element declaration",
pcercuei 0:03b5121a232e 24979 xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 24980 (*localType)->targetNamespace,
pcercuei 0:03b5121a232e 24981 (*localType)->name),
pcercuei 0:03b5121a232e 24982 NULL);
pcercuei 0:03b5121a232e 24983 FREE_AND_NULL(str);
pcercuei 0:03b5121a232e 24984 ret = vctxt->err;
pcercuei 0:03b5121a232e 24985 *localType = NULL;
pcercuei 0:03b5121a232e 24986 }
pcercuei 0:03b5121a232e 24987 }
pcercuei 0:03b5121a232e 24988 }
pcercuei 0:03b5121a232e 24989 exit:
pcercuei 0:03b5121a232e 24990 ACTIVATE_ELEM;
pcercuei 0:03b5121a232e 24991 return (ret);
pcercuei 0:03b5121a232e 24992 internal_error:
pcercuei 0:03b5121a232e 24993 ACTIVATE_ELEM;
pcercuei 0:03b5121a232e 24994 return (-1);
pcercuei 0:03b5121a232e 24995 }
pcercuei 0:03b5121a232e 24996
pcercuei 0:03b5121a232e 24997 static int
pcercuei 0:03b5121a232e 24998 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 24999 {
pcercuei 0:03b5121a232e 25000 xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
pcercuei 0:03b5121a232e 25001 xmlSchemaTypePtr actualType;
pcercuei 0:03b5121a232e 25002
pcercuei 0:03b5121a232e 25003 /*
pcercuei 0:03b5121a232e 25004 * cvc-elt (3.3.4) : 1
pcercuei 0:03b5121a232e 25005 */
pcercuei 0:03b5121a232e 25006 if (elemDecl == NULL) {
pcercuei 0:03b5121a232e 25007 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
pcercuei 0:03b5121a232e 25008 "No matching declaration available");
pcercuei 0:03b5121a232e 25009 return (vctxt->err);
pcercuei 0:03b5121a232e 25010 }
pcercuei 0:03b5121a232e 25011 actualType = WXS_ELEM_TYPEDEF(elemDecl);
pcercuei 0:03b5121a232e 25012 /*
pcercuei 0:03b5121a232e 25013 * cvc-elt (3.3.4) : 2
pcercuei 0:03b5121a232e 25014 */
pcercuei 0:03b5121a232e 25015 if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
pcercuei 0:03b5121a232e 25016 VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
pcercuei 0:03b5121a232e 25017 "The element declaration is abstract");
pcercuei 0:03b5121a232e 25018 return (vctxt->err);
pcercuei 0:03b5121a232e 25019 }
pcercuei 0:03b5121a232e 25020 if (actualType == NULL) {
pcercuei 0:03b5121a232e 25021 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
pcercuei 0:03b5121a232e 25022 "The type definition is absent");
pcercuei 0:03b5121a232e 25023 return (XML_SCHEMAV_CVC_TYPE_1);
pcercuei 0:03b5121a232e 25024 }
pcercuei 0:03b5121a232e 25025 if (vctxt->nbAttrInfos != 0) {
pcercuei 0:03b5121a232e 25026 int ret;
pcercuei 0:03b5121a232e 25027 xmlSchemaAttrInfoPtr iattr;
pcercuei 0:03b5121a232e 25028 /*
pcercuei 0:03b5121a232e 25029 * cvc-elt (3.3.4) : 3
pcercuei 0:03b5121a232e 25030 * Handle 'xsi:nil'.
pcercuei 0:03b5121a232e 25031 */
pcercuei 0:03b5121a232e 25032 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
pcercuei 0:03b5121a232e 25033 XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
pcercuei 0:03b5121a232e 25034 if (iattr) {
pcercuei 0:03b5121a232e 25035 ACTIVATE_ATTRIBUTE(iattr);
pcercuei 0:03b5121a232e 25036 /*
pcercuei 0:03b5121a232e 25037 * Validate the value.
pcercuei 0:03b5121a232e 25038 */
pcercuei 0:03b5121a232e 25039 ret = xmlSchemaVCheckCVCSimpleType(
pcercuei 0:03b5121a232e 25040 ACTXT_CAST vctxt, NULL,
pcercuei 0:03b5121a232e 25041 xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
pcercuei 0:03b5121a232e 25042 iattr->value, &(iattr->val), 1, 0, 0);
pcercuei 0:03b5121a232e 25043 ACTIVATE_ELEM;
pcercuei 0:03b5121a232e 25044 if (ret < 0) {
pcercuei 0:03b5121a232e 25045 VERROR_INT("xmlSchemaValidateElemDecl",
pcercuei 0:03b5121a232e 25046 "calling xmlSchemaVCheckCVCSimpleType() to "
pcercuei 0:03b5121a232e 25047 "validate the attribute 'xsi:nil'");
pcercuei 0:03b5121a232e 25048 return (-1);
pcercuei 0:03b5121a232e 25049 }
pcercuei 0:03b5121a232e 25050 if (ret == 0) {
pcercuei 0:03b5121a232e 25051 if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
pcercuei 0:03b5121a232e 25052 /*
pcercuei 0:03b5121a232e 25053 * cvc-elt (3.3.4) : 3.1
pcercuei 0:03b5121a232e 25054 */
pcercuei 0:03b5121a232e 25055 VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
pcercuei 0:03b5121a232e 25056 "The element is not 'nillable'");
pcercuei 0:03b5121a232e 25057 /* Does not return an error on purpose. */
pcercuei 0:03b5121a232e 25058 } else {
pcercuei 0:03b5121a232e 25059 if (xmlSchemaValueGetAsBoolean(iattr->val)) {
pcercuei 0:03b5121a232e 25060 /*
pcercuei 0:03b5121a232e 25061 * cvc-elt (3.3.4) : 3.2.2
pcercuei 0:03b5121a232e 25062 */
pcercuei 0:03b5121a232e 25063 if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
pcercuei 0:03b5121a232e 25064 (elemDecl->value != NULL)) {
pcercuei 0:03b5121a232e 25065 VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
pcercuei 0:03b5121a232e 25066 "The element cannot be 'nilled' because "
pcercuei 0:03b5121a232e 25067 "there is a fixed value constraint defined "
pcercuei 0:03b5121a232e 25068 "for it");
pcercuei 0:03b5121a232e 25069 /* Does not return an error on purpose. */
pcercuei 0:03b5121a232e 25070 } else
pcercuei 0:03b5121a232e 25071 vctxt->inode->flags |=
pcercuei 0:03b5121a232e 25072 XML_SCHEMA_ELEM_INFO_NILLED;
pcercuei 0:03b5121a232e 25073 }
pcercuei 0:03b5121a232e 25074 }
pcercuei 0:03b5121a232e 25075 }
pcercuei 0:03b5121a232e 25076 }
pcercuei 0:03b5121a232e 25077 /*
pcercuei 0:03b5121a232e 25078 * cvc-elt (3.3.4) : 4
pcercuei 0:03b5121a232e 25079 * Handle 'xsi:type'.
pcercuei 0:03b5121a232e 25080 */
pcercuei 0:03b5121a232e 25081 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
pcercuei 0:03b5121a232e 25082 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
pcercuei 0:03b5121a232e 25083 if (iattr) {
pcercuei 0:03b5121a232e 25084 xmlSchemaTypePtr localType = NULL;
pcercuei 0:03b5121a232e 25085
pcercuei 0:03b5121a232e 25086 ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
pcercuei 0:03b5121a232e 25087 elemDecl);
pcercuei 0:03b5121a232e 25088 if (ret != 0) {
pcercuei 0:03b5121a232e 25089 if (ret == -1) {
pcercuei 0:03b5121a232e 25090 VERROR_INT("xmlSchemaValidateElemDecl",
pcercuei 0:03b5121a232e 25091 "calling xmlSchemaProcessXSIType() to "
pcercuei 0:03b5121a232e 25092 "process the attribute 'xsi:type'");
pcercuei 0:03b5121a232e 25093 return (-1);
pcercuei 0:03b5121a232e 25094 }
pcercuei 0:03b5121a232e 25095 /* Does not return an error on purpose. */
pcercuei 0:03b5121a232e 25096 }
pcercuei 0:03b5121a232e 25097 if (localType != NULL) {
pcercuei 0:03b5121a232e 25098 vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
pcercuei 0:03b5121a232e 25099 actualType = localType;
pcercuei 0:03b5121a232e 25100 }
pcercuei 0:03b5121a232e 25101 }
pcercuei 0:03b5121a232e 25102 }
pcercuei 0:03b5121a232e 25103 /*
pcercuei 0:03b5121a232e 25104 * IDC: Register identity-constraint XPath matchers.
pcercuei 0:03b5121a232e 25105 */
pcercuei 0:03b5121a232e 25106 if ((elemDecl->idcs != NULL) &&
pcercuei 0:03b5121a232e 25107 (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
pcercuei 0:03b5121a232e 25108 return (-1);
pcercuei 0:03b5121a232e 25109 /*
pcercuei 0:03b5121a232e 25110 * No actual type definition.
pcercuei 0:03b5121a232e 25111 */
pcercuei 0:03b5121a232e 25112 if (actualType == NULL) {
pcercuei 0:03b5121a232e 25113 VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
pcercuei 0:03b5121a232e 25114 "The type definition is absent");
pcercuei 0:03b5121a232e 25115 return (XML_SCHEMAV_CVC_TYPE_1);
pcercuei 0:03b5121a232e 25116 }
pcercuei 0:03b5121a232e 25117 /*
pcercuei 0:03b5121a232e 25118 * Remember the actual type definition.
pcercuei 0:03b5121a232e 25119 */
pcercuei 0:03b5121a232e 25120 vctxt->inode->typeDef = actualType;
pcercuei 0:03b5121a232e 25121
pcercuei 0:03b5121a232e 25122 return (0);
pcercuei 0:03b5121a232e 25123 }
pcercuei 0:03b5121a232e 25124
pcercuei 0:03b5121a232e 25125 static int
pcercuei 0:03b5121a232e 25126 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 25127 {
pcercuei 0:03b5121a232e 25128 xmlSchemaAttrInfoPtr iattr;
pcercuei 0:03b5121a232e 25129 int ret = 0, i;
pcercuei 0:03b5121a232e 25130
pcercuei 0:03b5121a232e 25131 /*
pcercuei 0:03b5121a232e 25132 * SPEC cvc-type (3.1.1)
pcercuei 0:03b5121a232e 25133 * "The attributes of must be empty, excepting those whose namespace
pcercuei 0:03b5121a232e 25134 * name is identical to http://www.w3.org/2001/XMLSchema-instance and
pcercuei 0:03b5121a232e 25135 * whose local name is one of type, nil, schemaLocation or
pcercuei 0:03b5121a232e 25136 * noNamespaceSchemaLocation."
pcercuei 0:03b5121a232e 25137 */
pcercuei 0:03b5121a232e 25138 if (vctxt->nbAttrInfos == 0)
pcercuei 0:03b5121a232e 25139 return (0);
pcercuei 0:03b5121a232e 25140 for (i = 0; i < vctxt->nbAttrInfos; i++) {
pcercuei 0:03b5121a232e 25141 iattr = vctxt->attrInfos[i];
pcercuei 0:03b5121a232e 25142 if (! iattr->metaType) {
pcercuei 0:03b5121a232e 25143 ACTIVATE_ATTRIBUTE(iattr)
pcercuei 0:03b5121a232e 25144 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 25145 XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
pcercuei 0:03b5121a232e 25146 ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
pcercuei 0:03b5121a232e 25147 }
pcercuei 0:03b5121a232e 25148 }
pcercuei 0:03b5121a232e 25149 ACTIVATE_ELEM
pcercuei 0:03b5121a232e 25150 return (ret);
pcercuei 0:03b5121a232e 25151 }
pcercuei 0:03b5121a232e 25152
pcercuei 0:03b5121a232e 25153 /*
pcercuei 0:03b5121a232e 25154 * Cleanup currently used attribute infos.
pcercuei 0:03b5121a232e 25155 */
pcercuei 0:03b5121a232e 25156 static void
pcercuei 0:03b5121a232e 25157 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 25158 {
pcercuei 0:03b5121a232e 25159 int i;
pcercuei 0:03b5121a232e 25160 xmlSchemaAttrInfoPtr attr;
pcercuei 0:03b5121a232e 25161
pcercuei 0:03b5121a232e 25162 if (vctxt->nbAttrInfos == 0)
pcercuei 0:03b5121a232e 25163 return;
pcercuei 0:03b5121a232e 25164 for (i = 0; i < vctxt->nbAttrInfos; i++) {
pcercuei 0:03b5121a232e 25165 attr = vctxt->attrInfos[i];
pcercuei 0:03b5121a232e 25166 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
pcercuei 0:03b5121a232e 25167 if (attr->localName != NULL)
pcercuei 0:03b5121a232e 25168 xmlFree((xmlChar *) attr->localName);
pcercuei 0:03b5121a232e 25169 if (attr->nsName != NULL)
pcercuei 0:03b5121a232e 25170 xmlFree((xmlChar *) attr->nsName);
pcercuei 0:03b5121a232e 25171 }
pcercuei 0:03b5121a232e 25172 if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
pcercuei 0:03b5121a232e 25173 if (attr->value != NULL)
pcercuei 0:03b5121a232e 25174 xmlFree((xmlChar *) attr->value);
pcercuei 0:03b5121a232e 25175 }
pcercuei 0:03b5121a232e 25176 if (attr->val != NULL) {
pcercuei 0:03b5121a232e 25177 xmlSchemaFreeValue(attr->val);
pcercuei 0:03b5121a232e 25178 attr->val = NULL;
pcercuei 0:03b5121a232e 25179 }
pcercuei 0:03b5121a232e 25180 memset(attr, 0, sizeof(xmlSchemaAttrInfo));
pcercuei 0:03b5121a232e 25181 }
pcercuei 0:03b5121a232e 25182 vctxt->nbAttrInfos = 0;
pcercuei 0:03b5121a232e 25183 }
pcercuei 0:03b5121a232e 25184
pcercuei 0:03b5121a232e 25185 /*
pcercuei 0:03b5121a232e 25186 * 3.4.4 Complex Type Definition Validation Rules
pcercuei 0:03b5121a232e 25187 * Element Locally Valid (Complex Type) (cvc-complex-type)
pcercuei 0:03b5121a232e 25188 * 3.2.4 Attribute Declaration Validation Rules
pcercuei 0:03b5121a232e 25189 * Validation Rule: Attribute Locally Valid (cvc-attribute)
pcercuei 0:03b5121a232e 25190 * Attribute Locally Valid (Use) (cvc-au)
pcercuei 0:03b5121a232e 25191 *
pcercuei 0:03b5121a232e 25192 * Only "assessed" attribute information items will be visible to
pcercuei 0:03b5121a232e 25193 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
pcercuei 0:03b5121a232e 25194 */
pcercuei 0:03b5121a232e 25195 static int
pcercuei 0:03b5121a232e 25196 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 25197 {
pcercuei 0:03b5121a232e 25198 xmlSchemaTypePtr type = vctxt->inode->typeDef;
pcercuei 0:03b5121a232e 25199 xmlSchemaItemListPtr attrUseList;
pcercuei 0:03b5121a232e 25200 xmlSchemaAttributeUsePtr attrUse = NULL;
pcercuei 0:03b5121a232e 25201 xmlSchemaAttributePtr attrDecl = NULL;
pcercuei 0:03b5121a232e 25202 xmlSchemaAttrInfoPtr iattr, tmpiattr;
pcercuei 0:03b5121a232e 25203 int i, j, found, nbAttrs, nbUses;
pcercuei 0:03b5121a232e 25204 int xpathRes = 0, res, wildIDs = 0, fixed;
pcercuei 0:03b5121a232e 25205 xmlNodePtr defAttrOwnerElem = NULL;
pcercuei 0:03b5121a232e 25206
pcercuei 0:03b5121a232e 25207 /*
pcercuei 0:03b5121a232e 25208 * SPEC (cvc-attribute)
pcercuei 0:03b5121a232e 25209 * (1) "The declaration must not be `absent` (see Missing
pcercuei 0:03b5121a232e 25210 * Sub-components ($5.3) for how this can fail to be
pcercuei 0:03b5121a232e 25211 * the case)."
pcercuei 0:03b5121a232e 25212 * (2) "Its {type definition} must not be absent."
pcercuei 0:03b5121a232e 25213 *
pcercuei 0:03b5121a232e 25214 * NOTE (1) + (2): This is not handled here, since we currently do not
pcercuei 0:03b5121a232e 25215 * allow validation against schemas which have missing sub-components.
pcercuei 0:03b5121a232e 25216 *
pcercuei 0:03b5121a232e 25217 * SPEC (cvc-complex-type)
pcercuei 0:03b5121a232e 25218 * (3) "For each attribute information item in the element information
pcercuei 0:03b5121a232e 25219 * item's [attributes] excepting those whose [namespace name] is
pcercuei 0:03b5121a232e 25220 * identical to http://www.w3.org/2001/XMLSchema-instance and whose
pcercuei 0:03b5121a232e 25221 * [local name] is one of type, nil, schemaLocation or
pcercuei 0:03b5121a232e 25222 * noNamespaceSchemaLocation, the appropriate case among the following
pcercuei 0:03b5121a232e 25223 * must be true:
pcercuei 0:03b5121a232e 25224 *
pcercuei 0:03b5121a232e 25225 */
pcercuei 0:03b5121a232e 25226 attrUseList = (xmlSchemaItemListPtr) type->attrUses;
pcercuei 0:03b5121a232e 25227 /*
pcercuei 0:03b5121a232e 25228 * @nbAttrs is the number of attributes present in the instance.
pcercuei 0:03b5121a232e 25229 */
pcercuei 0:03b5121a232e 25230 nbAttrs = vctxt->nbAttrInfos;
pcercuei 0:03b5121a232e 25231 if (attrUseList != NULL)
pcercuei 0:03b5121a232e 25232 nbUses = attrUseList->nbItems;
pcercuei 0:03b5121a232e 25233 else
pcercuei 0:03b5121a232e 25234 nbUses = 0;
pcercuei 0:03b5121a232e 25235 for (i = 0; i < nbUses; i++) {
pcercuei 0:03b5121a232e 25236 found = 0;
pcercuei 0:03b5121a232e 25237 attrUse = attrUseList->items[i];
pcercuei 0:03b5121a232e 25238 attrDecl = WXS_ATTRUSE_DECL(attrUse);
pcercuei 0:03b5121a232e 25239 for (j = 0; j < nbAttrs; j++) {
pcercuei 0:03b5121a232e 25240 iattr = vctxt->attrInfos[j];
pcercuei 0:03b5121a232e 25241 /*
pcercuei 0:03b5121a232e 25242 * SPEC (cvc-complex-type) (3)
pcercuei 0:03b5121a232e 25243 * Skip meta attributes.
pcercuei 0:03b5121a232e 25244 */
pcercuei 0:03b5121a232e 25245 if (iattr->metaType)
pcercuei 0:03b5121a232e 25246 continue;
pcercuei 0:03b5121a232e 25247 if (iattr->localName[0] != attrDecl->name[0])
pcercuei 0:03b5121a232e 25248 continue;
pcercuei 0:03b5121a232e 25249 if (!xmlStrEqual(iattr->localName, attrDecl->name))
pcercuei 0:03b5121a232e 25250 continue;
pcercuei 0:03b5121a232e 25251 if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
pcercuei 0:03b5121a232e 25252 continue;
pcercuei 0:03b5121a232e 25253 found = 1;
pcercuei 0:03b5121a232e 25254 /*
pcercuei 0:03b5121a232e 25255 * SPEC (cvc-complex-type)
pcercuei 0:03b5121a232e 25256 * (3.1) "If there is among the {attribute uses} an attribute
pcercuei 0:03b5121a232e 25257 * use with an {attribute declaration} whose {name} matches
pcercuei 0:03b5121a232e 25258 * the attribute information item's [local name] and whose
pcercuei 0:03b5121a232e 25259 * {target namespace} is identical to the attribute information
pcercuei 0:03b5121a232e 25260 * item's [namespace name] (where an `absent` {target namespace}
pcercuei 0:03b5121a232e 25261 * is taken to be identical to a [namespace name] with no value),
pcercuei 0:03b5121a232e 25262 * then the attribute information must be `valid` with respect
pcercuei 0:03b5121a232e 25263 * to that attribute use as per Attribute Locally Valid (Use)
pcercuei 0:03b5121a232e 25264 * ($3.5.4). In this case the {attribute declaration} of that
pcercuei 0:03b5121a232e 25265 * attribute use is the `context-determined declaration` for the
pcercuei 0:03b5121a232e 25266 * attribute information item with respect to Schema-Validity
pcercuei 0:03b5121a232e 25267 * Assessment (Attribute) ($3.2.4) and
pcercuei 0:03b5121a232e 25268 * Assessment Outcome (Attribute) ($3.2.5).
pcercuei 0:03b5121a232e 25269 */
pcercuei 0:03b5121a232e 25270 iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
pcercuei 0:03b5121a232e 25271 iattr->use = attrUse;
pcercuei 0:03b5121a232e 25272 /*
pcercuei 0:03b5121a232e 25273 * Context-determined declaration.
pcercuei 0:03b5121a232e 25274 */
pcercuei 0:03b5121a232e 25275 iattr->decl = attrDecl;
pcercuei 0:03b5121a232e 25276 iattr->typeDef = attrDecl->subtypes;
pcercuei 0:03b5121a232e 25277 break;
pcercuei 0:03b5121a232e 25278 }
pcercuei 0:03b5121a232e 25279
pcercuei 0:03b5121a232e 25280 if (found)
pcercuei 0:03b5121a232e 25281 continue;
pcercuei 0:03b5121a232e 25282
pcercuei 0:03b5121a232e 25283 if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
pcercuei 0:03b5121a232e 25284 /*
pcercuei 0:03b5121a232e 25285 * Handle non-existent, required attributes.
pcercuei 0:03b5121a232e 25286 *
pcercuei 0:03b5121a232e 25287 * SPEC (cvc-complex-type)
pcercuei 0:03b5121a232e 25288 * (4) "The {attribute declaration} of each attribute use in
pcercuei 0:03b5121a232e 25289 * the {attribute uses} whose {required} is true matches one
pcercuei 0:03b5121a232e 25290 * of the attribute information items in the element information
pcercuei 0:03b5121a232e 25291 * item's [attributes] as per clause 3.1 above."
pcercuei 0:03b5121a232e 25292 */
pcercuei 0:03b5121a232e 25293 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
pcercuei 0:03b5121a232e 25294 if (tmpiattr == NULL) {
pcercuei 0:03b5121a232e 25295 VERROR_INT(
pcercuei 0:03b5121a232e 25296 "xmlSchemaVAttributesComplex",
pcercuei 0:03b5121a232e 25297 "calling xmlSchemaGetFreshAttrInfo()");
pcercuei 0:03b5121a232e 25298 return (-1);
pcercuei 0:03b5121a232e 25299 }
pcercuei 0:03b5121a232e 25300 tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
pcercuei 0:03b5121a232e 25301 tmpiattr->use = attrUse;
pcercuei 0:03b5121a232e 25302 tmpiattr->decl = attrDecl;
pcercuei 0:03b5121a232e 25303 } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
pcercuei 0:03b5121a232e 25304 ((attrUse->defValue != NULL) ||
pcercuei 0:03b5121a232e 25305 (attrDecl->defValue != NULL))) {
pcercuei 0:03b5121a232e 25306 /*
pcercuei 0:03b5121a232e 25307 * Handle non-existent, optional, default/fixed attributes.
pcercuei 0:03b5121a232e 25308 */
pcercuei 0:03b5121a232e 25309 tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
pcercuei 0:03b5121a232e 25310 if (tmpiattr == NULL) {
pcercuei 0:03b5121a232e 25311 VERROR_INT(
pcercuei 0:03b5121a232e 25312 "xmlSchemaVAttributesComplex",
pcercuei 0:03b5121a232e 25313 "calling xmlSchemaGetFreshAttrInfo()");
pcercuei 0:03b5121a232e 25314 return (-1);
pcercuei 0:03b5121a232e 25315 }
pcercuei 0:03b5121a232e 25316 tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
pcercuei 0:03b5121a232e 25317 tmpiattr->use = attrUse;
pcercuei 0:03b5121a232e 25318 tmpiattr->decl = attrDecl;
pcercuei 0:03b5121a232e 25319 tmpiattr->typeDef = attrDecl->subtypes;
pcercuei 0:03b5121a232e 25320 tmpiattr->localName = attrDecl->name;
pcercuei 0:03b5121a232e 25321 tmpiattr->nsName = attrDecl->targetNamespace;
pcercuei 0:03b5121a232e 25322 }
pcercuei 0:03b5121a232e 25323 }
pcercuei 0:03b5121a232e 25324
pcercuei 0:03b5121a232e 25325 if (vctxt->nbAttrInfos == 0)
pcercuei 0:03b5121a232e 25326 return (0);
pcercuei 0:03b5121a232e 25327 /*
pcercuei 0:03b5121a232e 25328 * Validate against the wildcard.
pcercuei 0:03b5121a232e 25329 */
pcercuei 0:03b5121a232e 25330 if (type->attributeWildcard != NULL) {
pcercuei 0:03b5121a232e 25331 /*
pcercuei 0:03b5121a232e 25332 * SPEC (cvc-complex-type)
pcercuei 0:03b5121a232e 25333 * (3.2.1) "There must be an {attribute wildcard}."
pcercuei 0:03b5121a232e 25334 */
pcercuei 0:03b5121a232e 25335 for (i = 0; i < nbAttrs; i++) {
pcercuei 0:03b5121a232e 25336 iattr = vctxt->attrInfos[i];
pcercuei 0:03b5121a232e 25337 /*
pcercuei 0:03b5121a232e 25338 * SPEC (cvc-complex-type) (3)
pcercuei 0:03b5121a232e 25339 * Skip meta attributes.
pcercuei 0:03b5121a232e 25340 */
pcercuei 0:03b5121a232e 25341 if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
pcercuei 0:03b5121a232e 25342 continue;
pcercuei 0:03b5121a232e 25343 /*
pcercuei 0:03b5121a232e 25344 * SPEC (cvc-complex-type)
pcercuei 0:03b5121a232e 25345 * (3.2.2) "The attribute information item must be `valid` with
pcercuei 0:03b5121a232e 25346 * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
pcercuei 0:03b5121a232e 25347 *
pcercuei 0:03b5121a232e 25348 * SPEC Item Valid (Wildcard) (cvc-wildcard)
pcercuei 0:03b5121a232e 25349 * "... its [namespace name] must be `valid` with respect to
pcercuei 0:03b5121a232e 25350 * the wildcard constraint, as defined in Wildcard allows
pcercuei 0:03b5121a232e 25351 * Namespace Name ($3.10.4)."
pcercuei 0:03b5121a232e 25352 */
pcercuei 0:03b5121a232e 25353 if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
pcercuei 0:03b5121a232e 25354 iattr->nsName) == 0) {
pcercuei 0:03b5121a232e 25355 /*
pcercuei 0:03b5121a232e 25356 * Handle processContents.
pcercuei 0:03b5121a232e 25357 *
pcercuei 0:03b5121a232e 25358 * SPEC (cvc-wildcard):
pcercuei 0:03b5121a232e 25359 * processContents | context-determined declaration:
pcercuei 0:03b5121a232e 25360 * "strict" "mustFind"
pcercuei 0:03b5121a232e 25361 * "lax" "none"
pcercuei 0:03b5121a232e 25362 * "skip" "skip"
pcercuei 0:03b5121a232e 25363 */
pcercuei 0:03b5121a232e 25364 if (type->attributeWildcard->processContents ==
pcercuei 0:03b5121a232e 25365 XML_SCHEMAS_ANY_SKIP) {
pcercuei 0:03b5121a232e 25366 /*
pcercuei 0:03b5121a232e 25367 * context-determined declaration = "skip"
pcercuei 0:03b5121a232e 25368 *
pcercuei 0:03b5121a232e 25369 * SPEC PSVI Assessment Outcome (Attribute)
pcercuei 0:03b5121a232e 25370 * [validity] = "notKnown"
pcercuei 0:03b5121a232e 25371 * [validation attempted] = "none"
pcercuei 0:03b5121a232e 25372 */
pcercuei 0:03b5121a232e 25373 iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
pcercuei 0:03b5121a232e 25374 continue;
pcercuei 0:03b5121a232e 25375 }
pcercuei 0:03b5121a232e 25376 /*
pcercuei 0:03b5121a232e 25377 * Find an attribute declaration.
pcercuei 0:03b5121a232e 25378 */
pcercuei 0:03b5121a232e 25379 iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
pcercuei 0:03b5121a232e 25380 iattr->localName, iattr->nsName);
pcercuei 0:03b5121a232e 25381 if (iattr->decl != NULL) {
pcercuei 0:03b5121a232e 25382 iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
pcercuei 0:03b5121a232e 25383 /*
pcercuei 0:03b5121a232e 25384 * SPEC (cvc-complex-type)
pcercuei 0:03b5121a232e 25385 * (5) "Let [Definition:] the wild IDs be the set of
pcercuei 0:03b5121a232e 25386 * all attribute information item to which clause 3.2
pcercuei 0:03b5121a232e 25387 * applied and whose `validation` resulted in a
pcercuei 0:03b5121a232e 25388 * `context-determined declaration` of mustFind or no
pcercuei 0:03b5121a232e 25389 * `context-determined declaration` at all, and whose
pcercuei 0:03b5121a232e 25390 * [local name] and [namespace name] resolve (as
pcercuei 0:03b5121a232e 25391 * defined by QName resolution (Instance) ($3.15.4)) to
pcercuei 0:03b5121a232e 25392 * an attribute declaration whose {type definition} is
pcercuei 0:03b5121a232e 25393 * or is derived from ID. Then all of the following
pcercuei 0:03b5121a232e 25394 * must be true:"
pcercuei 0:03b5121a232e 25395 */
pcercuei 0:03b5121a232e 25396 iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
pcercuei 0:03b5121a232e 25397 if (xmlSchemaIsDerivedFromBuiltInType(
pcercuei 0:03b5121a232e 25398 iattr->typeDef, XML_SCHEMAS_ID)) {
pcercuei 0:03b5121a232e 25399 /*
pcercuei 0:03b5121a232e 25400 * SPEC (5.1) "There must be no more than one
pcercuei 0:03b5121a232e 25401 * item in `wild IDs`."
pcercuei 0:03b5121a232e 25402 */
pcercuei 0:03b5121a232e 25403 if (wildIDs != 0) {
pcercuei 0:03b5121a232e 25404 /* VAL TODO */
pcercuei 0:03b5121a232e 25405 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
pcercuei 0:03b5121a232e 25406 TODO
pcercuei 0:03b5121a232e 25407 continue;
pcercuei 0:03b5121a232e 25408 }
pcercuei 0:03b5121a232e 25409 wildIDs++;
pcercuei 0:03b5121a232e 25410 /*
pcercuei 0:03b5121a232e 25411 * SPEC (cvc-complex-type)
pcercuei 0:03b5121a232e 25412 * (5.2) "If `wild IDs` is non-empty, there must not
pcercuei 0:03b5121a232e 25413 * be any attribute uses among the {attribute uses}
pcercuei 0:03b5121a232e 25414 * whose {attribute declaration}'s {type definition}
pcercuei 0:03b5121a232e 25415 * is or is derived from ID."
pcercuei 0:03b5121a232e 25416 */
pcercuei 0:03b5121a232e 25417 if (attrUseList != NULL) {
pcercuei 0:03b5121a232e 25418 for (j = 0; j < attrUseList->nbItems; j++) {
pcercuei 0:03b5121a232e 25419 if (xmlSchemaIsDerivedFromBuiltInType(
pcercuei 0:03b5121a232e 25420 WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
pcercuei 0:03b5121a232e 25421 XML_SCHEMAS_ID)) {
pcercuei 0:03b5121a232e 25422 /* URGENT VAL TODO: implement */
pcercuei 0:03b5121a232e 25423 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
pcercuei 0:03b5121a232e 25424 TODO
pcercuei 0:03b5121a232e 25425 break;
pcercuei 0:03b5121a232e 25426 }
pcercuei 0:03b5121a232e 25427 }
pcercuei 0:03b5121a232e 25428 }
pcercuei 0:03b5121a232e 25429 }
pcercuei 0:03b5121a232e 25430 } else if (type->attributeWildcard->processContents ==
pcercuei 0:03b5121a232e 25431 XML_SCHEMAS_ANY_LAX) {
pcercuei 0:03b5121a232e 25432 iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
pcercuei 0:03b5121a232e 25433 /*
pcercuei 0:03b5121a232e 25434 * SPEC PSVI Assessment Outcome (Attribute)
pcercuei 0:03b5121a232e 25435 * [validity] = "notKnown"
pcercuei 0:03b5121a232e 25436 * [validation attempted] = "none"
pcercuei 0:03b5121a232e 25437 */
pcercuei 0:03b5121a232e 25438 } else {
pcercuei 0:03b5121a232e 25439 iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
pcercuei 0:03b5121a232e 25440 }
pcercuei 0:03b5121a232e 25441 }
pcercuei 0:03b5121a232e 25442 }
pcercuei 0:03b5121a232e 25443 }
pcercuei 0:03b5121a232e 25444
pcercuei 0:03b5121a232e 25445 if (vctxt->nbAttrInfos == 0)
pcercuei 0:03b5121a232e 25446 return (0);
pcercuei 0:03b5121a232e 25447
pcercuei 0:03b5121a232e 25448 /*
pcercuei 0:03b5121a232e 25449 * Get the owner element; needed for creation of default attributes.
pcercuei 0:03b5121a232e 25450 * This fixes bug #341337, reported by David Grohmann.
pcercuei 0:03b5121a232e 25451 */
pcercuei 0:03b5121a232e 25452 if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
pcercuei 0:03b5121a232e 25453 xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
pcercuei 0:03b5121a232e 25454 if (ielem && ielem->node && ielem->node->doc)
pcercuei 0:03b5121a232e 25455 defAttrOwnerElem = ielem->node;
pcercuei 0:03b5121a232e 25456 }
pcercuei 0:03b5121a232e 25457 /*
pcercuei 0:03b5121a232e 25458 * Validate values, create default attributes, evaluate IDCs.
pcercuei 0:03b5121a232e 25459 */
pcercuei 0:03b5121a232e 25460 for (i = 0; i < vctxt->nbAttrInfos; i++) {
pcercuei 0:03b5121a232e 25461 iattr = vctxt->attrInfos[i];
pcercuei 0:03b5121a232e 25462 /*
pcercuei 0:03b5121a232e 25463 * VAL TODO: Note that we won't try to resolve IDCs to
pcercuei 0:03b5121a232e 25464 * "lax" and "skip" validated attributes. Check what to
pcercuei 0:03b5121a232e 25465 * do in this case.
pcercuei 0:03b5121a232e 25466 */
pcercuei 0:03b5121a232e 25467 if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
pcercuei 0:03b5121a232e 25468 (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
pcercuei 0:03b5121a232e 25469 continue;
pcercuei 0:03b5121a232e 25470 /*
pcercuei 0:03b5121a232e 25471 * VAL TODO: What to do if the type definition is missing?
pcercuei 0:03b5121a232e 25472 */
pcercuei 0:03b5121a232e 25473 if (iattr->typeDef == NULL) {
pcercuei 0:03b5121a232e 25474 iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
pcercuei 0:03b5121a232e 25475 continue;
pcercuei 0:03b5121a232e 25476 }
pcercuei 0:03b5121a232e 25477
pcercuei 0:03b5121a232e 25478 ACTIVATE_ATTRIBUTE(iattr);
pcercuei 0:03b5121a232e 25479 fixed = 0;
pcercuei 0:03b5121a232e 25480 xpathRes = 0;
pcercuei 0:03b5121a232e 25481
pcercuei 0:03b5121a232e 25482 if (vctxt->xpathStates != NULL) {
pcercuei 0:03b5121a232e 25483 /*
pcercuei 0:03b5121a232e 25484 * Evaluate IDCs.
pcercuei 0:03b5121a232e 25485 */
pcercuei 0:03b5121a232e 25486 xpathRes = xmlSchemaXPathEvaluate(vctxt,
pcercuei 0:03b5121a232e 25487 XML_ATTRIBUTE_NODE);
pcercuei 0:03b5121a232e 25488 if (xpathRes == -1) {
pcercuei 0:03b5121a232e 25489 VERROR_INT("xmlSchemaVAttributesComplex",
pcercuei 0:03b5121a232e 25490 "calling xmlSchemaXPathEvaluate()");
pcercuei 0:03b5121a232e 25491 goto internal_error;
pcercuei 0:03b5121a232e 25492 }
pcercuei 0:03b5121a232e 25493 }
pcercuei 0:03b5121a232e 25494
pcercuei 0:03b5121a232e 25495 if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
pcercuei 0:03b5121a232e 25496 /*
pcercuei 0:03b5121a232e 25497 * Default/fixed attributes.
pcercuei 0:03b5121a232e 25498 * We need the value only if we need to resolve IDCs or
pcercuei 0:03b5121a232e 25499 * will create default attributes.
pcercuei 0:03b5121a232e 25500 */
pcercuei 0:03b5121a232e 25501 if ((xpathRes) || (defAttrOwnerElem)) {
pcercuei 0:03b5121a232e 25502 if (iattr->use->defValue != NULL) {
pcercuei 0:03b5121a232e 25503 iattr->value = (xmlChar *) iattr->use->defValue;
pcercuei 0:03b5121a232e 25504 iattr->val = iattr->use->defVal;
pcercuei 0:03b5121a232e 25505 } else {
pcercuei 0:03b5121a232e 25506 iattr->value = (xmlChar *) iattr->decl->defValue;
pcercuei 0:03b5121a232e 25507 iattr->val = iattr->decl->defVal;
pcercuei 0:03b5121a232e 25508 }
pcercuei 0:03b5121a232e 25509 /*
pcercuei 0:03b5121a232e 25510 * IDCs will consume the precomputed default value,
pcercuei 0:03b5121a232e 25511 * so we need to clone it.
pcercuei 0:03b5121a232e 25512 */
pcercuei 0:03b5121a232e 25513 if (iattr->val == NULL) {
pcercuei 0:03b5121a232e 25514 VERROR_INT("xmlSchemaVAttributesComplex",
pcercuei 0:03b5121a232e 25515 "default/fixed value on an attribute use was "
pcercuei 0:03b5121a232e 25516 "not precomputed");
pcercuei 0:03b5121a232e 25517 goto internal_error;
pcercuei 0:03b5121a232e 25518 }
pcercuei 0:03b5121a232e 25519 iattr->val = xmlSchemaCopyValue(iattr->val);
pcercuei 0:03b5121a232e 25520 if (iattr->val == NULL) {
pcercuei 0:03b5121a232e 25521 VERROR_INT("xmlSchemaVAttributesComplex",
pcercuei 0:03b5121a232e 25522 "calling xmlSchemaCopyValue()");
pcercuei 0:03b5121a232e 25523 goto internal_error;
pcercuei 0:03b5121a232e 25524 }
pcercuei 0:03b5121a232e 25525 }
pcercuei 0:03b5121a232e 25526 /*
pcercuei 0:03b5121a232e 25527 * PSVI: Add the default attribute to the current element.
pcercuei 0:03b5121a232e 25528 * VAL TODO: Should we use the *normalized* value? This currently
pcercuei 0:03b5121a232e 25529 * uses the *initial* value.
pcercuei 0:03b5121a232e 25530 */
pcercuei 0:03b5121a232e 25531
pcercuei 0:03b5121a232e 25532 if (defAttrOwnerElem) {
pcercuei 0:03b5121a232e 25533 xmlChar *normValue;
pcercuei 0:03b5121a232e 25534 const xmlChar *value;
pcercuei 0:03b5121a232e 25535
pcercuei 0:03b5121a232e 25536 value = iattr->value;
pcercuei 0:03b5121a232e 25537 /*
pcercuei 0:03b5121a232e 25538 * Normalize the value.
pcercuei 0:03b5121a232e 25539 */
pcercuei 0:03b5121a232e 25540 normValue = xmlSchemaNormalizeValue(iattr->typeDef,
pcercuei 0:03b5121a232e 25541 iattr->value);
pcercuei 0:03b5121a232e 25542 if (normValue != NULL)
pcercuei 0:03b5121a232e 25543 value = BAD_CAST normValue;
pcercuei 0:03b5121a232e 25544
pcercuei 0:03b5121a232e 25545 if (iattr->nsName == NULL) {
pcercuei 0:03b5121a232e 25546 if (xmlNewProp(defAttrOwnerElem,
pcercuei 0:03b5121a232e 25547 iattr->localName, value) == NULL) {
pcercuei 0:03b5121a232e 25548 VERROR_INT("xmlSchemaVAttributesComplex",
pcercuei 0:03b5121a232e 25549 "calling xmlNewProp()");
pcercuei 0:03b5121a232e 25550 if (normValue != NULL)
pcercuei 0:03b5121a232e 25551 xmlFree(normValue);
pcercuei 0:03b5121a232e 25552 goto internal_error;
pcercuei 0:03b5121a232e 25553 }
pcercuei 0:03b5121a232e 25554 } else {
pcercuei 0:03b5121a232e 25555 xmlNsPtr ns;
pcercuei 0:03b5121a232e 25556
pcercuei 0:03b5121a232e 25557 ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
pcercuei 0:03b5121a232e 25558 defAttrOwnerElem, iattr->nsName);
pcercuei 0:03b5121a232e 25559 if (ns == NULL) {
pcercuei 0:03b5121a232e 25560 xmlChar prefix[12];
pcercuei 0:03b5121a232e 25561 int counter = 0;
pcercuei 0:03b5121a232e 25562
pcercuei 0:03b5121a232e 25563 /*
pcercuei 0:03b5121a232e 25564 * Create a namespace declaration on the validation
pcercuei 0:03b5121a232e 25565 * root node if no namespace declaration is in scope.
pcercuei 0:03b5121a232e 25566 */
pcercuei 0:03b5121a232e 25567 do {
pcercuei 0:03b5121a232e 25568 snprintf((char *) prefix, 12, "p%d", counter++);
pcercuei 0:03b5121a232e 25569 ns = xmlSearchNs(defAttrOwnerElem->doc,
pcercuei 0:03b5121a232e 25570 defAttrOwnerElem, BAD_CAST prefix);
pcercuei 0:03b5121a232e 25571 if (counter > 1000) {
pcercuei 0:03b5121a232e 25572 VERROR_INT(
pcercuei 0:03b5121a232e 25573 "xmlSchemaVAttributesComplex",
pcercuei 0:03b5121a232e 25574 "could not compute a ns prefix for a "
pcercuei 0:03b5121a232e 25575 "default/fixed attribute");
pcercuei 0:03b5121a232e 25576 if (normValue != NULL)
pcercuei 0:03b5121a232e 25577 xmlFree(normValue);
pcercuei 0:03b5121a232e 25578 goto internal_error;
pcercuei 0:03b5121a232e 25579 }
pcercuei 0:03b5121a232e 25580 } while (ns != NULL);
pcercuei 0:03b5121a232e 25581 ns = xmlNewNs(vctxt->validationRoot,
pcercuei 0:03b5121a232e 25582 iattr->nsName, BAD_CAST prefix);
pcercuei 0:03b5121a232e 25583 }
pcercuei 0:03b5121a232e 25584 /*
pcercuei 0:03b5121a232e 25585 * TODO:
pcercuei 0:03b5121a232e 25586 * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
pcercuei 0:03b5121a232e 25587 * If we have QNames: do we need to ensure there's a
pcercuei 0:03b5121a232e 25588 * prefix defined for the QName?
pcercuei 0:03b5121a232e 25589 */
pcercuei 0:03b5121a232e 25590 xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
pcercuei 0:03b5121a232e 25591 }
pcercuei 0:03b5121a232e 25592 if (normValue != NULL)
pcercuei 0:03b5121a232e 25593 xmlFree(normValue);
pcercuei 0:03b5121a232e 25594 }
pcercuei 0:03b5121a232e 25595 /*
pcercuei 0:03b5121a232e 25596 * Go directly to IDC evaluation.
pcercuei 0:03b5121a232e 25597 */
pcercuei 0:03b5121a232e 25598 goto eval_idcs;
pcercuei 0:03b5121a232e 25599 }
pcercuei 0:03b5121a232e 25600 /*
pcercuei 0:03b5121a232e 25601 * Validate the value.
pcercuei 0:03b5121a232e 25602 */
pcercuei 0:03b5121a232e 25603 if (vctxt->value != NULL) {
pcercuei 0:03b5121a232e 25604 /*
pcercuei 0:03b5121a232e 25605 * Free last computed value; just for safety reasons.
pcercuei 0:03b5121a232e 25606 */
pcercuei 0:03b5121a232e 25607 xmlSchemaFreeValue(vctxt->value);
pcercuei 0:03b5121a232e 25608 vctxt->value = NULL;
pcercuei 0:03b5121a232e 25609 }
pcercuei 0:03b5121a232e 25610 /*
pcercuei 0:03b5121a232e 25611 * Note that the attribute *use* can be unavailable, if
pcercuei 0:03b5121a232e 25612 * the attribute was a wild attribute.
pcercuei 0:03b5121a232e 25613 */
pcercuei 0:03b5121a232e 25614 if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
pcercuei 0:03b5121a232e 25615 ((iattr->use != NULL) &&
pcercuei 0:03b5121a232e 25616 (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
pcercuei 0:03b5121a232e 25617 fixed = 1;
pcercuei 0:03b5121a232e 25618 else
pcercuei 0:03b5121a232e 25619 fixed = 0;
pcercuei 0:03b5121a232e 25620 /*
pcercuei 0:03b5121a232e 25621 * SPEC (cvc-attribute)
pcercuei 0:03b5121a232e 25622 * (3) "The item's `normalized value` must be locally `valid`
pcercuei 0:03b5121a232e 25623 * with respect to that {type definition} as per
pcercuei 0:03b5121a232e 25624 * String Valid ($3.14.4)."
pcercuei 0:03b5121a232e 25625 *
pcercuei 0:03b5121a232e 25626 * VAL TODO: Do we already have the
pcercuei 0:03b5121a232e 25627 * "normalized attribute value" here?
pcercuei 0:03b5121a232e 25628 */
pcercuei 0:03b5121a232e 25629 if (xpathRes || fixed) {
pcercuei 0:03b5121a232e 25630 iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
pcercuei 0:03b5121a232e 25631 /*
pcercuei 0:03b5121a232e 25632 * Request a computed value.
pcercuei 0:03b5121a232e 25633 */
pcercuei 0:03b5121a232e 25634 res = xmlSchemaVCheckCVCSimpleType(
pcercuei 0:03b5121a232e 25635 ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 25636 iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
pcercuei 0:03b5121a232e 25637 1, 1, 0);
pcercuei 0:03b5121a232e 25638 } else {
pcercuei 0:03b5121a232e 25639 res = xmlSchemaVCheckCVCSimpleType(
pcercuei 0:03b5121a232e 25640 ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 25641 iattr->node, iattr->typeDef, iattr->value, NULL,
pcercuei 0:03b5121a232e 25642 1, 0, 0);
pcercuei 0:03b5121a232e 25643 }
pcercuei 0:03b5121a232e 25644
pcercuei 0:03b5121a232e 25645 if (res != 0) {
pcercuei 0:03b5121a232e 25646 if (res == -1) {
pcercuei 0:03b5121a232e 25647 VERROR_INT("xmlSchemaVAttributesComplex",
pcercuei 0:03b5121a232e 25648 "calling xmlSchemaStreamValidateSimpleTypeValue()");
pcercuei 0:03b5121a232e 25649 goto internal_error;
pcercuei 0:03b5121a232e 25650 }
pcercuei 0:03b5121a232e 25651 iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
pcercuei 0:03b5121a232e 25652 /*
pcercuei 0:03b5121a232e 25653 * SPEC PSVI Assessment Outcome (Attribute)
pcercuei 0:03b5121a232e 25654 * [validity] = "invalid"
pcercuei 0:03b5121a232e 25655 */
pcercuei 0:03b5121a232e 25656 goto eval_idcs;
pcercuei 0:03b5121a232e 25657 }
pcercuei 0:03b5121a232e 25658
pcercuei 0:03b5121a232e 25659 if (fixed) {
pcercuei 0:03b5121a232e 25660 /*
pcercuei 0:03b5121a232e 25661 * SPEC Attribute Locally Valid (Use) (cvc-au)
pcercuei 0:03b5121a232e 25662 * "For an attribute information item to be `valid`
pcercuei 0:03b5121a232e 25663 * with respect to an attribute use its *normalized*
pcercuei 0:03b5121a232e 25664 * value must match the *canonical* lexical
pcercuei 0:03b5121a232e 25665 * representation of the attribute use's {value
pcercuei 0:03b5121a232e 25666 * constraint}value, if it is present and fixed."
pcercuei 0:03b5121a232e 25667 *
pcercuei 0:03b5121a232e 25668 * VAL TODO: The requirement for the *canonical* value
pcercuei 0:03b5121a232e 25669 * will be removed in XML Schema 1.1.
pcercuei 0:03b5121a232e 25670 */
pcercuei 0:03b5121a232e 25671 /*
pcercuei 0:03b5121a232e 25672 * SPEC Attribute Locally Valid (cvc-attribute)
pcercuei 0:03b5121a232e 25673 * (4) "The item's *actual* value must match the *value* of
pcercuei 0:03b5121a232e 25674 * the {value constraint}, if it is present and fixed."
pcercuei 0:03b5121a232e 25675 */
pcercuei 0:03b5121a232e 25676 if (iattr->val == NULL) {
pcercuei 0:03b5121a232e 25677 /* VAL TODO: A value was not precomputed. */
pcercuei 0:03b5121a232e 25678 TODO
pcercuei 0:03b5121a232e 25679 goto eval_idcs;
pcercuei 0:03b5121a232e 25680 }
pcercuei 0:03b5121a232e 25681 if ((iattr->use != NULL) &&
pcercuei 0:03b5121a232e 25682 (iattr->use->defValue != NULL)) {
pcercuei 0:03b5121a232e 25683 if (iattr->use->defVal == NULL) {
pcercuei 0:03b5121a232e 25684 /* VAL TODO: A default value was not precomputed. */
pcercuei 0:03b5121a232e 25685 TODO
pcercuei 0:03b5121a232e 25686 goto eval_idcs;
pcercuei 0:03b5121a232e 25687 }
pcercuei 0:03b5121a232e 25688 iattr->vcValue = iattr->use->defValue;
pcercuei 0:03b5121a232e 25689 /*
pcercuei 0:03b5121a232e 25690 if (xmlSchemaCompareValuesWhtsp(attr->val,
pcercuei 0:03b5121a232e 25691 (xmlSchemaWhitespaceValueType) ws,
pcercuei 0:03b5121a232e 25692 attr->use->defVal,
pcercuei 0:03b5121a232e 25693 (xmlSchemaWhitespaceValueType) ws) != 0) {
pcercuei 0:03b5121a232e 25694 */
pcercuei 0:03b5121a232e 25695 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
pcercuei 0:03b5121a232e 25696 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
pcercuei 0:03b5121a232e 25697 } else {
pcercuei 0:03b5121a232e 25698 if (iattr->decl->defVal == NULL) {
pcercuei 0:03b5121a232e 25699 /* VAL TODO: A default value was not precomputed. */
pcercuei 0:03b5121a232e 25700 TODO
pcercuei 0:03b5121a232e 25701 goto eval_idcs;
pcercuei 0:03b5121a232e 25702 }
pcercuei 0:03b5121a232e 25703 iattr->vcValue = iattr->decl->defValue;
pcercuei 0:03b5121a232e 25704 /*
pcercuei 0:03b5121a232e 25705 if (xmlSchemaCompareValuesWhtsp(attr->val,
pcercuei 0:03b5121a232e 25706 (xmlSchemaWhitespaceValueType) ws,
pcercuei 0:03b5121a232e 25707 attrDecl->defVal,
pcercuei 0:03b5121a232e 25708 (xmlSchemaWhitespaceValueType) ws) != 0) {
pcercuei 0:03b5121a232e 25709 */
pcercuei 0:03b5121a232e 25710 if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
pcercuei 0:03b5121a232e 25711 iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
pcercuei 0:03b5121a232e 25712 }
pcercuei 0:03b5121a232e 25713 /*
pcercuei 0:03b5121a232e 25714 * [validity] = "valid"
pcercuei 0:03b5121a232e 25715 */
pcercuei 0:03b5121a232e 25716 }
pcercuei 0:03b5121a232e 25717 eval_idcs:
pcercuei 0:03b5121a232e 25718 /*
pcercuei 0:03b5121a232e 25719 * Evaluate IDCs.
pcercuei 0:03b5121a232e 25720 */
pcercuei 0:03b5121a232e 25721 if (xpathRes) {
pcercuei 0:03b5121a232e 25722 if (xmlSchemaXPathProcessHistory(vctxt,
pcercuei 0:03b5121a232e 25723 vctxt->depth +1) == -1) {
pcercuei 0:03b5121a232e 25724 VERROR_INT("xmlSchemaVAttributesComplex",
pcercuei 0:03b5121a232e 25725 "calling xmlSchemaXPathEvaluate()");
pcercuei 0:03b5121a232e 25726 goto internal_error;
pcercuei 0:03b5121a232e 25727 }
pcercuei 0:03b5121a232e 25728 } else if (vctxt->xpathStates != NULL)
pcercuei 0:03b5121a232e 25729 xmlSchemaXPathPop(vctxt);
pcercuei 0:03b5121a232e 25730 }
pcercuei 0:03b5121a232e 25731
pcercuei 0:03b5121a232e 25732 /*
pcercuei 0:03b5121a232e 25733 * Report errors.
pcercuei 0:03b5121a232e 25734 */
pcercuei 0:03b5121a232e 25735 for (i = 0; i < vctxt->nbAttrInfos; i++) {
pcercuei 0:03b5121a232e 25736 iattr = vctxt->attrInfos[i];
pcercuei 0:03b5121a232e 25737 if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
pcercuei 0:03b5121a232e 25738 (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
pcercuei 0:03b5121a232e 25739 (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
pcercuei 0:03b5121a232e 25740 (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
pcercuei 0:03b5121a232e 25741 continue;
pcercuei 0:03b5121a232e 25742 ACTIVATE_ATTRIBUTE(iattr);
pcercuei 0:03b5121a232e 25743 switch (iattr->state) {
pcercuei 0:03b5121a232e 25744 case XML_SCHEMAS_ATTR_ERR_MISSING: {
pcercuei 0:03b5121a232e 25745 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 25746 ACTIVATE_ELEM;
pcercuei 0:03b5121a232e 25747 xmlSchemaCustomErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 25748 XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
pcercuei 0:03b5121a232e 25749 "The attribute '%s' is required but missing",
pcercuei 0:03b5121a232e 25750 xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 25751 iattr->decl->targetNamespace,
pcercuei 0:03b5121a232e 25752 iattr->decl->name),
pcercuei 0:03b5121a232e 25753 NULL);
pcercuei 0:03b5121a232e 25754 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 25755 break;
pcercuei 0:03b5121a232e 25756 }
pcercuei 0:03b5121a232e 25757 case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
pcercuei 0:03b5121a232e 25758 VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
pcercuei 0:03b5121a232e 25759 "The type definition is absent");
pcercuei 0:03b5121a232e 25760 break;
pcercuei 0:03b5121a232e 25761 case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
pcercuei 0:03b5121a232e 25762 xmlSchemaCustomErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 25763 XML_SCHEMAV_CVC_AU, NULL, NULL,
pcercuei 0:03b5121a232e 25764 "The value '%s' does not match the fixed "
pcercuei 0:03b5121a232e 25765 "value constraint '%s'",
pcercuei 0:03b5121a232e 25766 iattr->value, iattr->vcValue);
pcercuei 0:03b5121a232e 25767 break;
pcercuei 0:03b5121a232e 25768 case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
pcercuei 0:03b5121a232e 25769 VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
pcercuei 0:03b5121a232e 25770 "No matching global attribute declaration available, but "
pcercuei 0:03b5121a232e 25771 "demanded by the strict wildcard");
pcercuei 0:03b5121a232e 25772 break;
pcercuei 0:03b5121a232e 25773 case XML_SCHEMAS_ATTR_UNKNOWN:
pcercuei 0:03b5121a232e 25774 if (iattr->metaType)
pcercuei 0:03b5121a232e 25775 break;
pcercuei 0:03b5121a232e 25776 /*
pcercuei 0:03b5121a232e 25777 * MAYBE VAL TODO: One might report different error messages
pcercuei 0:03b5121a232e 25778 * for the following errors.
pcercuei 0:03b5121a232e 25779 */
pcercuei 0:03b5121a232e 25780 if (type->attributeWildcard == NULL) {
pcercuei 0:03b5121a232e 25781 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 25782 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
pcercuei 0:03b5121a232e 25783 } else {
pcercuei 0:03b5121a232e 25784 xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 25785 XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
pcercuei 0:03b5121a232e 25786 }
pcercuei 0:03b5121a232e 25787 break;
pcercuei 0:03b5121a232e 25788 default:
pcercuei 0:03b5121a232e 25789 break;
pcercuei 0:03b5121a232e 25790 }
pcercuei 0:03b5121a232e 25791 }
pcercuei 0:03b5121a232e 25792
pcercuei 0:03b5121a232e 25793 ACTIVATE_ELEM;
pcercuei 0:03b5121a232e 25794 return (0);
pcercuei 0:03b5121a232e 25795 internal_error:
pcercuei 0:03b5121a232e 25796 ACTIVATE_ELEM;
pcercuei 0:03b5121a232e 25797 return (-1);
pcercuei 0:03b5121a232e 25798 }
pcercuei 0:03b5121a232e 25799
pcercuei 0:03b5121a232e 25800 static int
pcercuei 0:03b5121a232e 25801 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 25802 int *skip)
pcercuei 0:03b5121a232e 25803 {
pcercuei 0:03b5121a232e 25804 xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
pcercuei 0:03b5121a232e 25805 /*
pcercuei 0:03b5121a232e 25806 * The namespace of the element was already identified to be
pcercuei 0:03b5121a232e 25807 * matching the wildcard.
pcercuei 0:03b5121a232e 25808 */
pcercuei 0:03b5121a232e 25809 if ((skip == NULL) || (wild == NULL) ||
pcercuei 0:03b5121a232e 25810 (wild->type != XML_SCHEMA_TYPE_ANY)) {
pcercuei 0:03b5121a232e 25811 VERROR_INT("xmlSchemaValidateElemWildcard",
pcercuei 0:03b5121a232e 25812 "bad arguments");
pcercuei 0:03b5121a232e 25813 return (-1);
pcercuei 0:03b5121a232e 25814 }
pcercuei 0:03b5121a232e 25815 *skip = 0;
pcercuei 0:03b5121a232e 25816 if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
pcercuei 0:03b5121a232e 25817 /*
pcercuei 0:03b5121a232e 25818 * URGENT VAL TODO: Either we need to position the stream to the
pcercuei 0:03b5121a232e 25819 * next sibling, or walk the whole subtree.
pcercuei 0:03b5121a232e 25820 */
pcercuei 0:03b5121a232e 25821 *skip = 1;
pcercuei 0:03b5121a232e 25822 return (0);
pcercuei 0:03b5121a232e 25823 }
pcercuei 0:03b5121a232e 25824 {
pcercuei 0:03b5121a232e 25825 xmlSchemaElementPtr decl = NULL;
pcercuei 0:03b5121a232e 25826
pcercuei 0:03b5121a232e 25827 decl = xmlSchemaGetElem(vctxt->schema,
pcercuei 0:03b5121a232e 25828 vctxt->inode->localName, vctxt->inode->nsName);
pcercuei 0:03b5121a232e 25829 if (decl != NULL) {
pcercuei 0:03b5121a232e 25830 vctxt->inode->decl = decl;
pcercuei 0:03b5121a232e 25831 return (0);
pcercuei 0:03b5121a232e 25832 }
pcercuei 0:03b5121a232e 25833 }
pcercuei 0:03b5121a232e 25834 if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
pcercuei 0:03b5121a232e 25835 /* VAL TODO: Change to proper error code. */
pcercuei 0:03b5121a232e 25836 VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
pcercuei 0:03b5121a232e 25837 "No matching global element declaration available, but "
pcercuei 0:03b5121a232e 25838 "demanded by the strict wildcard");
pcercuei 0:03b5121a232e 25839 return (vctxt->err);
pcercuei 0:03b5121a232e 25840 }
pcercuei 0:03b5121a232e 25841 if (vctxt->nbAttrInfos != 0) {
pcercuei 0:03b5121a232e 25842 xmlSchemaAttrInfoPtr iattr;
pcercuei 0:03b5121a232e 25843 /*
pcercuei 0:03b5121a232e 25844 * SPEC Validation Rule: Schema-Validity Assessment (Element)
pcercuei 0:03b5121a232e 25845 * (1.2.1.2.1) - (1.2.1.2.3 )
pcercuei 0:03b5121a232e 25846 *
pcercuei 0:03b5121a232e 25847 * Use the xsi:type attribute for the type definition.
pcercuei 0:03b5121a232e 25848 */
pcercuei 0:03b5121a232e 25849 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
pcercuei 0:03b5121a232e 25850 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
pcercuei 0:03b5121a232e 25851 if (iattr != NULL) {
pcercuei 0:03b5121a232e 25852 if (xmlSchemaProcessXSIType(vctxt, iattr,
pcercuei 0:03b5121a232e 25853 &(vctxt->inode->typeDef), NULL) == -1) {
pcercuei 0:03b5121a232e 25854 VERROR_INT("xmlSchemaValidateElemWildcard",
pcercuei 0:03b5121a232e 25855 "calling xmlSchemaProcessXSIType() to "
pcercuei 0:03b5121a232e 25856 "process the attribute 'xsi:nil'");
pcercuei 0:03b5121a232e 25857 return (-1);
pcercuei 0:03b5121a232e 25858 }
pcercuei 0:03b5121a232e 25859 /*
pcercuei 0:03b5121a232e 25860 * Don't return an error on purpose.
pcercuei 0:03b5121a232e 25861 */
pcercuei 0:03b5121a232e 25862 return (0);
pcercuei 0:03b5121a232e 25863 }
pcercuei 0:03b5121a232e 25864 }
pcercuei 0:03b5121a232e 25865 /*
pcercuei 0:03b5121a232e 25866 * SPEC Validation Rule: Schema-Validity Assessment (Element)
pcercuei 0:03b5121a232e 25867 *
pcercuei 0:03b5121a232e 25868 * Fallback to "anyType".
pcercuei 0:03b5121a232e 25869 */
pcercuei 0:03b5121a232e 25870 vctxt->inode->typeDef =
pcercuei 0:03b5121a232e 25871 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
pcercuei 0:03b5121a232e 25872 return (0);
pcercuei 0:03b5121a232e 25873 }
pcercuei 0:03b5121a232e 25874
pcercuei 0:03b5121a232e 25875 /*
pcercuei 0:03b5121a232e 25876 * xmlSchemaCheckCOSValidDefault:
pcercuei 0:03b5121a232e 25877 *
pcercuei 0:03b5121a232e 25878 * This will be called if: not nilled, no content and a default/fixed
pcercuei 0:03b5121a232e 25879 * value is provided.
pcercuei 0:03b5121a232e 25880 */
pcercuei 0:03b5121a232e 25881
pcercuei 0:03b5121a232e 25882 static int
pcercuei 0:03b5121a232e 25883 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 25884 const xmlChar *value,
pcercuei 0:03b5121a232e 25885 xmlSchemaValPtr *val)
pcercuei 0:03b5121a232e 25886 {
pcercuei 0:03b5121a232e 25887 int ret = 0;
pcercuei 0:03b5121a232e 25888 xmlSchemaNodeInfoPtr inode = vctxt->inode;
pcercuei 0:03b5121a232e 25889
pcercuei 0:03b5121a232e 25890 /*
pcercuei 0:03b5121a232e 25891 * cos-valid-default:
pcercuei 0:03b5121a232e 25892 * Schema Component Constraint: Element Default Valid (Immediate)
pcercuei 0:03b5121a232e 25893 * For a string to be a valid default with respect to a type
pcercuei 0:03b5121a232e 25894 * definition the appropriate case among the following must be true:
pcercuei 0:03b5121a232e 25895 */
pcercuei 0:03b5121a232e 25896 if WXS_IS_COMPLEX(inode->typeDef) {
pcercuei 0:03b5121a232e 25897 /*
pcercuei 0:03b5121a232e 25898 * Complex type.
pcercuei 0:03b5121a232e 25899 *
pcercuei 0:03b5121a232e 25900 * SPEC (2.1) "its {content type} must be a simple type definition
pcercuei 0:03b5121a232e 25901 * or mixed."
pcercuei 0:03b5121a232e 25902 * SPEC (2.2.2) "If the {content type} is mixed, then the {content
pcercuei 0:03b5121a232e 25903 * type}'s particle must be `emptiable` as defined by
pcercuei 0:03b5121a232e 25904 * Particle Emptiable ($3.9.6)."
pcercuei 0:03b5121a232e 25905 */
pcercuei 0:03b5121a232e 25906 if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
pcercuei 0:03b5121a232e 25907 ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
pcercuei 0:03b5121a232e 25908 (! WXS_EMPTIABLE(inode->typeDef)))) {
pcercuei 0:03b5121a232e 25909 ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
pcercuei 0:03b5121a232e 25910 /* NOTE that this covers (2.2.2) as well. */
pcercuei 0:03b5121a232e 25911 VERROR(ret, NULL,
pcercuei 0:03b5121a232e 25912 "For a string to be a valid default, the type definition "
pcercuei 0:03b5121a232e 25913 "must be a simple type or a complex type with simple content "
pcercuei 0:03b5121a232e 25914 "or mixed content and a particle emptiable");
pcercuei 0:03b5121a232e 25915 return(ret);
pcercuei 0:03b5121a232e 25916 }
pcercuei 0:03b5121a232e 25917 }
pcercuei 0:03b5121a232e 25918 /*
pcercuei 0:03b5121a232e 25919 * 1 If the type definition is a simple type definition, then the string
pcercuei 0:03b5121a232e 25920 * must be `valid` with respect to that definition as defined by String
pcercuei 0:03b5121a232e 25921 * Valid ($3.14.4).
pcercuei 0:03b5121a232e 25922 *
pcercuei 0:03b5121a232e 25923 * AND
pcercuei 0:03b5121a232e 25924 *
pcercuei 0:03b5121a232e 25925 * 2.2.1 If the {content type} is a simple type definition, then the
pcercuei 0:03b5121a232e 25926 * string must be `valid` with respect to that simple type definition
pcercuei 0:03b5121a232e 25927 * as defined by String Valid ($3.14.4).
pcercuei 0:03b5121a232e 25928 */
pcercuei 0:03b5121a232e 25929 if (WXS_IS_SIMPLE(inode->typeDef)) {
pcercuei 0:03b5121a232e 25930
pcercuei 0:03b5121a232e 25931 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 25932 NULL, inode->typeDef, value, val, 1, 1, 0);
pcercuei 0:03b5121a232e 25933
pcercuei 0:03b5121a232e 25934 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
pcercuei 0:03b5121a232e 25935
pcercuei 0:03b5121a232e 25936 ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 25937 NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
pcercuei 0:03b5121a232e 25938 }
pcercuei 0:03b5121a232e 25939 if (ret < 0) {
pcercuei 0:03b5121a232e 25940 VERROR_INT("xmlSchemaCheckCOSValidDefault",
pcercuei 0:03b5121a232e 25941 "calling xmlSchemaVCheckCVCSimpleType()");
pcercuei 0:03b5121a232e 25942 }
pcercuei 0:03b5121a232e 25943 return (ret);
pcercuei 0:03b5121a232e 25944 }
pcercuei 0:03b5121a232e 25945
pcercuei 0:03b5121a232e 25946 static void
pcercuei 0:03b5121a232e 25947 xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 25948 const xmlChar * name ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 25949 xmlSchemaElementPtr item,
pcercuei 0:03b5121a232e 25950 xmlSchemaNodeInfoPtr inode)
pcercuei 0:03b5121a232e 25951 {
pcercuei 0:03b5121a232e 25952 inode->decl = item;
pcercuei 0:03b5121a232e 25953 #ifdef DEBUG_CONTENT
pcercuei 0:03b5121a232e 25954 {
pcercuei 0:03b5121a232e 25955 xmlChar *str = NULL;
pcercuei 0:03b5121a232e 25956
pcercuei 0:03b5121a232e 25957 if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
pcercuei 0:03b5121a232e 25958 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 25959 "AUTOMATON callback for '%s' [declaration]\n",
pcercuei 0:03b5121a232e 25960 xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 25961 inode->localName, inode->nsName));
pcercuei 0:03b5121a232e 25962 } else {
pcercuei 0:03b5121a232e 25963 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 25964 "AUTOMATON callback for '%s' [wildcard]\n",
pcercuei 0:03b5121a232e 25965 xmlSchemaFormatQName(&str,
pcercuei 0:03b5121a232e 25966 inode->localName, inode->nsName));
pcercuei 0:03b5121a232e 25967
pcercuei 0:03b5121a232e 25968 }
pcercuei 0:03b5121a232e 25969 FREE_AND_NULL(str)
pcercuei 0:03b5121a232e 25970 }
pcercuei 0:03b5121a232e 25971 #endif
pcercuei 0:03b5121a232e 25972 }
pcercuei 0:03b5121a232e 25973
pcercuei 0:03b5121a232e 25974 static int
pcercuei 0:03b5121a232e 25975 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 25976 {
pcercuei 0:03b5121a232e 25977 vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
pcercuei 0:03b5121a232e 25978 if (vctxt->inode == NULL) {
pcercuei 0:03b5121a232e 25979 VERROR_INT("xmlSchemaValidatorPushElem",
pcercuei 0:03b5121a232e 25980 "calling xmlSchemaGetFreshElemInfo()");
pcercuei 0:03b5121a232e 25981 return (-1);
pcercuei 0:03b5121a232e 25982 }
pcercuei 0:03b5121a232e 25983 vctxt->nbAttrInfos = 0;
pcercuei 0:03b5121a232e 25984 return (0);
pcercuei 0:03b5121a232e 25985 }
pcercuei 0:03b5121a232e 25986
pcercuei 0:03b5121a232e 25987 static int
pcercuei 0:03b5121a232e 25988 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 25989 xmlSchemaNodeInfoPtr inode,
pcercuei 0:03b5121a232e 25990 xmlSchemaTypePtr type,
pcercuei 0:03b5121a232e 25991 const xmlChar *value)
pcercuei 0:03b5121a232e 25992 {
pcercuei 0:03b5121a232e 25993 if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
pcercuei 0:03b5121a232e 25994 return (xmlSchemaVCheckCVCSimpleType(
pcercuei 0:03b5121a232e 25995 ACTXT_CAST vctxt, NULL,
pcercuei 0:03b5121a232e 25996 type, value, &(inode->val), 1, 1, 0));
pcercuei 0:03b5121a232e 25997 else
pcercuei 0:03b5121a232e 25998 return (xmlSchemaVCheckCVCSimpleType(
pcercuei 0:03b5121a232e 25999 ACTXT_CAST vctxt, NULL,
pcercuei 0:03b5121a232e 26000 type, value, NULL, 1, 0, 0));
pcercuei 0:03b5121a232e 26001 }
pcercuei 0:03b5121a232e 26002
pcercuei 0:03b5121a232e 26003
pcercuei 0:03b5121a232e 26004
pcercuei 0:03b5121a232e 26005 /*
pcercuei 0:03b5121a232e 26006 * Process END of element.
pcercuei 0:03b5121a232e 26007 */
pcercuei 0:03b5121a232e 26008 static int
pcercuei 0:03b5121a232e 26009 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 26010 {
pcercuei 0:03b5121a232e 26011 int ret = 0;
pcercuei 0:03b5121a232e 26012 xmlSchemaNodeInfoPtr inode = vctxt->inode;
pcercuei 0:03b5121a232e 26013
pcercuei 0:03b5121a232e 26014 if (vctxt->nbAttrInfos != 0)
pcercuei 0:03b5121a232e 26015 xmlSchemaClearAttrInfos(vctxt);
pcercuei 0:03b5121a232e 26016 if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
pcercuei 0:03b5121a232e 26017 /*
pcercuei 0:03b5121a232e 26018 * This element was not expected;
pcercuei 0:03b5121a232e 26019 * we will not validate child elements of broken parents.
pcercuei 0:03b5121a232e 26020 * Skip validation of all content of the parent.
pcercuei 0:03b5121a232e 26021 */
pcercuei 0:03b5121a232e 26022 vctxt->skipDepth = vctxt->depth -1;
pcercuei 0:03b5121a232e 26023 goto end_elem;
pcercuei 0:03b5121a232e 26024 }
pcercuei 0:03b5121a232e 26025 if ((inode->typeDef == NULL) ||
pcercuei 0:03b5121a232e 26026 (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
pcercuei 0:03b5121a232e 26027 /*
pcercuei 0:03b5121a232e 26028 * 1. the type definition might be missing if the element was
pcercuei 0:03b5121a232e 26029 * error prone
pcercuei 0:03b5121a232e 26030 * 2. it might be abstract.
pcercuei 0:03b5121a232e 26031 */
pcercuei 0:03b5121a232e 26032 goto end_elem;
pcercuei 0:03b5121a232e 26033 }
pcercuei 0:03b5121a232e 26034 /*
pcercuei 0:03b5121a232e 26035 * Check the content model.
pcercuei 0:03b5121a232e 26036 */
pcercuei 0:03b5121a232e 26037 if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
pcercuei 0:03b5121a232e 26038 (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
pcercuei 0:03b5121a232e 26039
pcercuei 0:03b5121a232e 26040 /*
pcercuei 0:03b5121a232e 26041 * Workaround for "anyType".
pcercuei 0:03b5121a232e 26042 */
pcercuei 0:03b5121a232e 26043 if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
pcercuei 0:03b5121a232e 26044 goto character_content;
pcercuei 0:03b5121a232e 26045
pcercuei 0:03b5121a232e 26046 if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
pcercuei 0:03b5121a232e 26047 xmlChar *values[10];
pcercuei 0:03b5121a232e 26048 int terminal, nbval = 10, nbneg;
pcercuei 0:03b5121a232e 26049
pcercuei 0:03b5121a232e 26050 if (inode->regexCtxt == NULL) {
pcercuei 0:03b5121a232e 26051 /*
pcercuei 0:03b5121a232e 26052 * Create the regex context.
pcercuei 0:03b5121a232e 26053 */
pcercuei 0:03b5121a232e 26054 inode->regexCtxt =
pcercuei 0:03b5121a232e 26055 xmlRegNewExecCtxt(inode->typeDef->contModel,
pcercuei 0:03b5121a232e 26056 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
pcercuei 0:03b5121a232e 26057 vctxt);
pcercuei 0:03b5121a232e 26058 if (inode->regexCtxt == NULL) {
pcercuei 0:03b5121a232e 26059 VERROR_INT("xmlSchemaValidatorPopElem",
pcercuei 0:03b5121a232e 26060 "failed to create a regex context");
pcercuei 0:03b5121a232e 26061 goto internal_error;
pcercuei 0:03b5121a232e 26062 }
pcercuei 0:03b5121a232e 26063 #ifdef DEBUG_AUTOMATA
pcercuei 0:03b5121a232e 26064 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 26065 "AUTOMATON create on '%s'\n", inode->localName);
pcercuei 0:03b5121a232e 26066 #endif
pcercuei 0:03b5121a232e 26067 }
pcercuei 0:03b5121a232e 26068
pcercuei 0:03b5121a232e 26069 /*
pcercuei 0:03b5121a232e 26070 * Do not check further content if the node has been nilled
pcercuei 0:03b5121a232e 26071 */
pcercuei 0:03b5121a232e 26072 if (INODE_NILLED(inode)) {
pcercuei 0:03b5121a232e 26073 ret = 0;
pcercuei 0:03b5121a232e 26074 #ifdef DEBUG_AUTOMATA
pcercuei 0:03b5121a232e 26075 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 26076 "AUTOMATON succeeded on nilled '%s'\n",
pcercuei 0:03b5121a232e 26077 inode->localName);
pcercuei 0:03b5121a232e 26078 #endif
pcercuei 0:03b5121a232e 26079 goto skip_nilled;
pcercuei 0:03b5121a232e 26080 }
pcercuei 0:03b5121a232e 26081
pcercuei 0:03b5121a232e 26082 /*
pcercuei 0:03b5121a232e 26083 * Get hold of the still expected content, since a further
pcercuei 0:03b5121a232e 26084 * call to xmlRegExecPushString() will loose this information.
pcercuei 0:03b5121a232e 26085 */
pcercuei 0:03b5121a232e 26086 xmlRegExecNextValues(inode->regexCtxt,
pcercuei 0:03b5121a232e 26087 &nbval, &nbneg, &values[0], &terminal);
pcercuei 0:03b5121a232e 26088 ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
pcercuei 0:03b5121a232e 26089 if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
pcercuei 0:03b5121a232e 26090 /*
pcercuei 0:03b5121a232e 26091 * Still missing something.
pcercuei 0:03b5121a232e 26092 */
pcercuei 0:03b5121a232e 26093 ret = 1;
pcercuei 0:03b5121a232e 26094 inode->flags |=
pcercuei 0:03b5121a232e 26095 XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
pcercuei 0:03b5121a232e 26096 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 26097 XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
pcercuei 0:03b5121a232e 26098 "Missing child element(s)",
pcercuei 0:03b5121a232e 26099 nbval, nbneg, values);
pcercuei 0:03b5121a232e 26100 #ifdef DEBUG_AUTOMATA
pcercuei 0:03b5121a232e 26101 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 26102 "AUTOMATON missing ERROR on '%s'\n",
pcercuei 0:03b5121a232e 26103 inode->localName);
pcercuei 0:03b5121a232e 26104 #endif
pcercuei 0:03b5121a232e 26105 } else {
pcercuei 0:03b5121a232e 26106 /*
pcercuei 0:03b5121a232e 26107 * Content model is satisfied.
pcercuei 0:03b5121a232e 26108 */
pcercuei 0:03b5121a232e 26109 ret = 0;
pcercuei 0:03b5121a232e 26110 #ifdef DEBUG_AUTOMATA
pcercuei 0:03b5121a232e 26111 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 26112 "AUTOMATON succeeded on '%s'\n",
pcercuei 0:03b5121a232e 26113 inode->localName);
pcercuei 0:03b5121a232e 26114 #endif
pcercuei 0:03b5121a232e 26115 }
pcercuei 0:03b5121a232e 26116
pcercuei 0:03b5121a232e 26117 }
pcercuei 0:03b5121a232e 26118 }
pcercuei 0:03b5121a232e 26119
pcercuei 0:03b5121a232e 26120 skip_nilled:
pcercuei 0:03b5121a232e 26121
pcercuei 0:03b5121a232e 26122 if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
pcercuei 0:03b5121a232e 26123 goto end_elem;
pcercuei 0:03b5121a232e 26124
pcercuei 0:03b5121a232e 26125 character_content:
pcercuei 0:03b5121a232e 26126
pcercuei 0:03b5121a232e 26127 if (vctxt->value != NULL) {
pcercuei 0:03b5121a232e 26128 xmlSchemaFreeValue(vctxt->value);
pcercuei 0:03b5121a232e 26129 vctxt->value = NULL;
pcercuei 0:03b5121a232e 26130 }
pcercuei 0:03b5121a232e 26131 /*
pcercuei 0:03b5121a232e 26132 * Check character content.
pcercuei 0:03b5121a232e 26133 */
pcercuei 0:03b5121a232e 26134 if (inode->decl == NULL) {
pcercuei 0:03b5121a232e 26135 /*
pcercuei 0:03b5121a232e 26136 * Speedup if no declaration exists.
pcercuei 0:03b5121a232e 26137 */
pcercuei 0:03b5121a232e 26138 if (WXS_IS_SIMPLE(inode->typeDef)) {
pcercuei 0:03b5121a232e 26139 ret = xmlSchemaVCheckINodeDataType(vctxt,
pcercuei 0:03b5121a232e 26140 inode, inode->typeDef, inode->value);
pcercuei 0:03b5121a232e 26141 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
pcercuei 0:03b5121a232e 26142 ret = xmlSchemaVCheckINodeDataType(vctxt,
pcercuei 0:03b5121a232e 26143 inode, inode->typeDef->contentTypeDef,
pcercuei 0:03b5121a232e 26144 inode->value);
pcercuei 0:03b5121a232e 26145 }
pcercuei 0:03b5121a232e 26146 if (ret < 0) {
pcercuei 0:03b5121a232e 26147 VERROR_INT("xmlSchemaValidatorPopElem",
pcercuei 0:03b5121a232e 26148 "calling xmlSchemaVCheckCVCSimpleType()");
pcercuei 0:03b5121a232e 26149 goto internal_error;
pcercuei 0:03b5121a232e 26150 }
pcercuei 0:03b5121a232e 26151 goto end_elem;
pcercuei 0:03b5121a232e 26152 }
pcercuei 0:03b5121a232e 26153 /*
pcercuei 0:03b5121a232e 26154 * cvc-elt (3.3.4) : 5
pcercuei 0:03b5121a232e 26155 * The appropriate case among the following must be true:
pcercuei 0:03b5121a232e 26156 */
pcercuei 0:03b5121a232e 26157 /*
pcercuei 0:03b5121a232e 26158 * cvc-elt (3.3.4) : 5.1
pcercuei 0:03b5121a232e 26159 * If the declaration has a {value constraint},
pcercuei 0:03b5121a232e 26160 * the item has neither element nor character [children] and
pcercuei 0:03b5121a232e 26161 * clause 3.2 has not applied, then all of the following must be true:
pcercuei 0:03b5121a232e 26162 */
pcercuei 0:03b5121a232e 26163 if ((inode->decl->value != NULL) &&
pcercuei 0:03b5121a232e 26164 (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
pcercuei 0:03b5121a232e 26165 (! INODE_NILLED(inode))) {
pcercuei 0:03b5121a232e 26166 /*
pcercuei 0:03b5121a232e 26167 * cvc-elt (3.3.4) : 5.1.1
pcercuei 0:03b5121a232e 26168 * If the `actual type definition` is a `local type definition`
pcercuei 0:03b5121a232e 26169 * then the canonical lexical representation of the {value constraint}
pcercuei 0:03b5121a232e 26170 * value must be a valid default for the `actual type definition` as
pcercuei 0:03b5121a232e 26171 * defined in Element Default Valid (Immediate) ($3.3.6).
pcercuei 0:03b5121a232e 26172 */
pcercuei 0:03b5121a232e 26173 /*
pcercuei 0:03b5121a232e 26174 * NOTE: 'local' above means types acquired by xsi:type.
pcercuei 0:03b5121a232e 26175 * NOTE: Although the *canonical* value is stated, it is not
pcercuei 0:03b5121a232e 26176 * relevant if canonical or not. Additionally XML Schema 1.1
pcercuei 0:03b5121a232e 26177 * will removed this requirement as well.
pcercuei 0:03b5121a232e 26178 */
pcercuei 0:03b5121a232e 26179 if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
pcercuei 0:03b5121a232e 26180
pcercuei 0:03b5121a232e 26181 ret = xmlSchemaCheckCOSValidDefault(vctxt,
pcercuei 0:03b5121a232e 26182 inode->decl->value, &(inode->val));
pcercuei 0:03b5121a232e 26183 if (ret != 0) {
pcercuei 0:03b5121a232e 26184 if (ret < 0) {
pcercuei 0:03b5121a232e 26185 VERROR_INT("xmlSchemaValidatorPopElem",
pcercuei 0:03b5121a232e 26186 "calling xmlSchemaCheckCOSValidDefault()");
pcercuei 0:03b5121a232e 26187 goto internal_error;
pcercuei 0:03b5121a232e 26188 }
pcercuei 0:03b5121a232e 26189 goto end_elem;
pcercuei 0:03b5121a232e 26190 }
pcercuei 0:03b5121a232e 26191 /*
pcercuei 0:03b5121a232e 26192 * Stop here, to avoid redundant validation of the value
pcercuei 0:03b5121a232e 26193 * (see following).
pcercuei 0:03b5121a232e 26194 */
pcercuei 0:03b5121a232e 26195 goto default_psvi;
pcercuei 0:03b5121a232e 26196 }
pcercuei 0:03b5121a232e 26197 /*
pcercuei 0:03b5121a232e 26198 * cvc-elt (3.3.4) : 5.1.2
pcercuei 0:03b5121a232e 26199 * The element information item with the canonical lexical
pcercuei 0:03b5121a232e 26200 * representation of the {value constraint} value used as its
pcercuei 0:03b5121a232e 26201 * `normalized value` must be `valid` with respect to the
pcercuei 0:03b5121a232e 26202 * `actual type definition` as defined by Element Locally Valid (Type)
pcercuei 0:03b5121a232e 26203 * ($3.3.4).
pcercuei 0:03b5121a232e 26204 */
pcercuei 0:03b5121a232e 26205 if (WXS_IS_SIMPLE(inode->typeDef)) {
pcercuei 0:03b5121a232e 26206 ret = xmlSchemaVCheckINodeDataType(vctxt,
pcercuei 0:03b5121a232e 26207 inode, inode->typeDef, inode->decl->value);
pcercuei 0:03b5121a232e 26208 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
pcercuei 0:03b5121a232e 26209 ret = xmlSchemaVCheckINodeDataType(vctxt,
pcercuei 0:03b5121a232e 26210 inode, inode->typeDef->contentTypeDef,
pcercuei 0:03b5121a232e 26211 inode->decl->value);
pcercuei 0:03b5121a232e 26212 }
pcercuei 0:03b5121a232e 26213 if (ret != 0) {
pcercuei 0:03b5121a232e 26214 if (ret < 0) {
pcercuei 0:03b5121a232e 26215 VERROR_INT("xmlSchemaValidatorPopElem",
pcercuei 0:03b5121a232e 26216 "calling xmlSchemaVCheckCVCSimpleType()");
pcercuei 0:03b5121a232e 26217 goto internal_error;
pcercuei 0:03b5121a232e 26218 }
pcercuei 0:03b5121a232e 26219 goto end_elem;
pcercuei 0:03b5121a232e 26220 }
pcercuei 0:03b5121a232e 26221
pcercuei 0:03b5121a232e 26222 default_psvi:
pcercuei 0:03b5121a232e 26223 /*
pcercuei 0:03b5121a232e 26224 * PSVI: Create a text node on the instance element.
pcercuei 0:03b5121a232e 26225 */
pcercuei 0:03b5121a232e 26226 if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
pcercuei 0:03b5121a232e 26227 (inode->node != NULL)) {
pcercuei 0:03b5121a232e 26228 xmlNodePtr textChild;
pcercuei 0:03b5121a232e 26229 xmlChar *normValue;
pcercuei 0:03b5121a232e 26230 /*
pcercuei 0:03b5121a232e 26231 * VAL TODO: Normalize the value.
pcercuei 0:03b5121a232e 26232 */
pcercuei 0:03b5121a232e 26233 normValue = xmlSchemaNormalizeValue(inode->typeDef,
pcercuei 0:03b5121a232e 26234 inode->decl->value);
pcercuei 0:03b5121a232e 26235 if (normValue != NULL) {
pcercuei 0:03b5121a232e 26236 textChild = xmlNewText(BAD_CAST normValue);
pcercuei 0:03b5121a232e 26237 xmlFree(normValue);
pcercuei 0:03b5121a232e 26238 } else
pcercuei 0:03b5121a232e 26239 textChild = xmlNewText(inode->decl->value);
pcercuei 0:03b5121a232e 26240 if (textChild == NULL) {
pcercuei 0:03b5121a232e 26241 VERROR_INT("xmlSchemaValidatorPopElem",
pcercuei 0:03b5121a232e 26242 "calling xmlNewText()");
pcercuei 0:03b5121a232e 26243 goto internal_error;
pcercuei 0:03b5121a232e 26244 } else
pcercuei 0:03b5121a232e 26245 xmlAddChild(inode->node, textChild);
pcercuei 0:03b5121a232e 26246 }
pcercuei 0:03b5121a232e 26247
pcercuei 0:03b5121a232e 26248 } else if (! INODE_NILLED(inode)) {
pcercuei 0:03b5121a232e 26249 /*
pcercuei 0:03b5121a232e 26250 * 5.2.1 The element information item must be `valid` with respect
pcercuei 0:03b5121a232e 26251 * to the `actual type definition` as defined by Element Locally
pcercuei 0:03b5121a232e 26252 * Valid (Type) ($3.3.4).
pcercuei 0:03b5121a232e 26253 */
pcercuei 0:03b5121a232e 26254 if (WXS_IS_SIMPLE(inode->typeDef)) {
pcercuei 0:03b5121a232e 26255 /*
pcercuei 0:03b5121a232e 26256 * SPEC (cvc-type) (3.1)
pcercuei 0:03b5121a232e 26257 * "If the type definition is a simple type definition, ..."
pcercuei 0:03b5121a232e 26258 * (3.1.3) "If clause 3.2 of Element Locally Valid
pcercuei 0:03b5121a232e 26259 * (Element) ($3.3.4) did not apply, then the `normalized value`
pcercuei 0:03b5121a232e 26260 * must be `valid` with respect to the type definition as defined
pcercuei 0:03b5121a232e 26261 * by String Valid ($3.14.4).
pcercuei 0:03b5121a232e 26262 */
pcercuei 0:03b5121a232e 26263 ret = xmlSchemaVCheckINodeDataType(vctxt,
pcercuei 0:03b5121a232e 26264 inode, inode->typeDef, inode->value);
pcercuei 0:03b5121a232e 26265 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
pcercuei 0:03b5121a232e 26266 /*
pcercuei 0:03b5121a232e 26267 * SPEC (cvc-type) (3.2) "If the type definition is a complex type
pcercuei 0:03b5121a232e 26268 * definition, then the element information item must be
pcercuei 0:03b5121a232e 26269 * `valid` with respect to the type definition as per
pcercuei 0:03b5121a232e 26270 * Element Locally Valid (Complex Type) ($3.4.4);"
pcercuei 0:03b5121a232e 26271 *
pcercuei 0:03b5121a232e 26272 * SPEC (cvc-complex-type) (2.2)
pcercuei 0:03b5121a232e 26273 * "If the {content type} is a simple type definition, ...
pcercuei 0:03b5121a232e 26274 * the `normalized value` of the element information item is
pcercuei 0:03b5121a232e 26275 * `valid` with respect to that simple type definition as
pcercuei 0:03b5121a232e 26276 * defined by String Valid ($3.14.4)."
pcercuei 0:03b5121a232e 26277 */
pcercuei 0:03b5121a232e 26278 ret = xmlSchemaVCheckINodeDataType(vctxt,
pcercuei 0:03b5121a232e 26279 inode, inode->typeDef->contentTypeDef, inode->value);
pcercuei 0:03b5121a232e 26280 }
pcercuei 0:03b5121a232e 26281 if (ret != 0) {
pcercuei 0:03b5121a232e 26282 if (ret < 0) {
pcercuei 0:03b5121a232e 26283 VERROR_INT("xmlSchemaValidatorPopElem",
pcercuei 0:03b5121a232e 26284 "calling xmlSchemaVCheckCVCSimpleType()");
pcercuei 0:03b5121a232e 26285 goto internal_error;
pcercuei 0:03b5121a232e 26286 }
pcercuei 0:03b5121a232e 26287 goto end_elem;
pcercuei 0:03b5121a232e 26288 }
pcercuei 0:03b5121a232e 26289 /*
pcercuei 0:03b5121a232e 26290 * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
pcercuei 0:03b5121a232e 26291 * not applied, all of the following must be true:
pcercuei 0:03b5121a232e 26292 */
pcercuei 0:03b5121a232e 26293 if ((inode->decl->value != NULL) &&
pcercuei 0:03b5121a232e 26294 (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
pcercuei 0:03b5121a232e 26295
pcercuei 0:03b5121a232e 26296 /*
pcercuei 0:03b5121a232e 26297 * TODO: We will need a computed value, when comparison is
pcercuei 0:03b5121a232e 26298 * done on computed values.
pcercuei 0:03b5121a232e 26299 */
pcercuei 0:03b5121a232e 26300 /*
pcercuei 0:03b5121a232e 26301 * 5.2.2.1 The element information item must have no element
pcercuei 0:03b5121a232e 26302 * information item [children].
pcercuei 0:03b5121a232e 26303 */
pcercuei 0:03b5121a232e 26304 if (inode->flags &
pcercuei 0:03b5121a232e 26305 XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
pcercuei 0:03b5121a232e 26306 ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
pcercuei 0:03b5121a232e 26307 VERROR(ret, NULL,
pcercuei 0:03b5121a232e 26308 "The content must not containt element nodes since "
pcercuei 0:03b5121a232e 26309 "there is a fixed value constraint");
pcercuei 0:03b5121a232e 26310 goto end_elem;
pcercuei 0:03b5121a232e 26311 } else {
pcercuei 0:03b5121a232e 26312 /*
pcercuei 0:03b5121a232e 26313 * 5.2.2.2 The appropriate case among the following must
pcercuei 0:03b5121a232e 26314 * be true:
pcercuei 0:03b5121a232e 26315 */
pcercuei 0:03b5121a232e 26316 if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
pcercuei 0:03b5121a232e 26317 /*
pcercuei 0:03b5121a232e 26318 * 5.2.2.2.1 If the {content type} of the `actual type
pcercuei 0:03b5121a232e 26319 * definition` is mixed, then the *initial value* of the
pcercuei 0:03b5121a232e 26320 * item must match the canonical lexical representation
pcercuei 0:03b5121a232e 26321 * of the {value constraint} value.
pcercuei 0:03b5121a232e 26322 *
pcercuei 0:03b5121a232e 26323 * ... the *initial value* of an element information
pcercuei 0:03b5121a232e 26324 * item is the string composed of, in order, the
pcercuei 0:03b5121a232e 26325 * [character code] of each character information item in
pcercuei 0:03b5121a232e 26326 * the [children] of that element information item.
pcercuei 0:03b5121a232e 26327 */
pcercuei 0:03b5121a232e 26328 if (! xmlStrEqual(inode->value, inode->decl->value)){
pcercuei 0:03b5121a232e 26329 /*
pcercuei 0:03b5121a232e 26330 * VAL TODO: Report invalid & expected values as well.
pcercuei 0:03b5121a232e 26331 * VAL TODO: Implement the canonical stuff.
pcercuei 0:03b5121a232e 26332 */
pcercuei 0:03b5121a232e 26333 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
pcercuei 0:03b5121a232e 26334 xmlSchemaCustomErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 26335 ret, NULL, NULL,
pcercuei 0:03b5121a232e 26336 "The initial value '%s' does not match the fixed "
pcercuei 0:03b5121a232e 26337 "value constraint '%s'",
pcercuei 0:03b5121a232e 26338 inode->value, inode->decl->value);
pcercuei 0:03b5121a232e 26339 goto end_elem;
pcercuei 0:03b5121a232e 26340 }
pcercuei 0:03b5121a232e 26341 } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
pcercuei 0:03b5121a232e 26342 /*
pcercuei 0:03b5121a232e 26343 * 5.2.2.2.2 If the {content type} of the `actual type
pcercuei 0:03b5121a232e 26344 * definition` is a simple type definition, then the
pcercuei 0:03b5121a232e 26345 * *actual value* of the item must match the canonical
pcercuei 0:03b5121a232e 26346 * lexical representation of the {value constraint} value.
pcercuei 0:03b5121a232e 26347 */
pcercuei 0:03b5121a232e 26348 /*
pcercuei 0:03b5121a232e 26349 * VAL TODO: *actual value* is the normalized value, impl.
pcercuei 0:03b5121a232e 26350 * this.
pcercuei 0:03b5121a232e 26351 * VAL TODO: Report invalid & expected values as well.
pcercuei 0:03b5121a232e 26352 * VAL TODO: Implement a comparison with the computed values.
pcercuei 0:03b5121a232e 26353 */
pcercuei 0:03b5121a232e 26354 if (! xmlStrEqual(inode->value,
pcercuei 0:03b5121a232e 26355 inode->decl->value)) {
pcercuei 0:03b5121a232e 26356 ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
pcercuei 0:03b5121a232e 26357 xmlSchemaCustomErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 26358 ret, NULL, NULL,
pcercuei 0:03b5121a232e 26359 "The actual value '%s' does not match the fixed "
pcercuei 0:03b5121a232e 26360 "value constraint '%s'",
pcercuei 0:03b5121a232e 26361 inode->value,
pcercuei 0:03b5121a232e 26362 inode->decl->value);
pcercuei 0:03b5121a232e 26363 goto end_elem;
pcercuei 0:03b5121a232e 26364 }
pcercuei 0:03b5121a232e 26365 }
pcercuei 0:03b5121a232e 26366 }
pcercuei 0:03b5121a232e 26367 }
pcercuei 0:03b5121a232e 26368 }
pcercuei 0:03b5121a232e 26369
pcercuei 0:03b5121a232e 26370 end_elem:
pcercuei 0:03b5121a232e 26371 if (vctxt->depth < 0) {
pcercuei 0:03b5121a232e 26372 /* TODO: raise error? */
pcercuei 0:03b5121a232e 26373 return (0);
pcercuei 0:03b5121a232e 26374 }
pcercuei 0:03b5121a232e 26375 if (vctxt->depth == vctxt->skipDepth)
pcercuei 0:03b5121a232e 26376 vctxt->skipDepth = -1;
pcercuei 0:03b5121a232e 26377 /*
pcercuei 0:03b5121a232e 26378 * Evaluate the history of XPath state objects.
pcercuei 0:03b5121a232e 26379 */
pcercuei 0:03b5121a232e 26380 if (inode->appliedXPath &&
pcercuei 0:03b5121a232e 26381 (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
pcercuei 0:03b5121a232e 26382 goto internal_error;
pcercuei 0:03b5121a232e 26383 /*
pcercuei 0:03b5121a232e 26384 * MAYBE TODO:
pcercuei 0:03b5121a232e 26385 * SPEC (6) "The element information item must be `valid` with
pcercuei 0:03b5121a232e 26386 * respect to each of the {identity-constraint definitions} as per
pcercuei 0:03b5121a232e 26387 * Identity-constraint Satisfied ($3.11.4)."
pcercuei 0:03b5121a232e 26388 */
pcercuei 0:03b5121a232e 26389 /*
pcercuei 0:03b5121a232e 26390 * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
pcercuei 0:03b5121a232e 26391 * need to be built in any case.
pcercuei 0:03b5121a232e 26392 * We will currently build IDC node-tables and bubble them only if
pcercuei 0:03b5121a232e 26393 * keyrefs do exist.
pcercuei 0:03b5121a232e 26394 */
pcercuei 0:03b5121a232e 26395
pcercuei 0:03b5121a232e 26396 /*
pcercuei 0:03b5121a232e 26397 * Add the current IDC target-nodes to the IDC node-tables.
pcercuei 0:03b5121a232e 26398 */
pcercuei 0:03b5121a232e 26399 if ((inode->idcMatchers != NULL) &&
pcercuei 0:03b5121a232e 26400 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
pcercuei 0:03b5121a232e 26401 {
pcercuei 0:03b5121a232e 26402 if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
pcercuei 0:03b5121a232e 26403 goto internal_error;
pcercuei 0:03b5121a232e 26404 }
pcercuei 0:03b5121a232e 26405 /*
pcercuei 0:03b5121a232e 26406 * Validate IDC keyrefs.
pcercuei 0:03b5121a232e 26407 */
pcercuei 0:03b5121a232e 26408 if (vctxt->inode->hasKeyrefs)
pcercuei 0:03b5121a232e 26409 if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
pcercuei 0:03b5121a232e 26410 goto internal_error;
pcercuei 0:03b5121a232e 26411 /*
pcercuei 0:03b5121a232e 26412 * Merge/free the IDC table.
pcercuei 0:03b5121a232e 26413 */
pcercuei 0:03b5121a232e 26414 if (inode->idcTable != NULL) {
pcercuei 0:03b5121a232e 26415 #ifdef DEBUG_IDC_NODE_TABLE
pcercuei 0:03b5121a232e 26416 xmlSchemaDebugDumpIDCTable(stdout,
pcercuei 0:03b5121a232e 26417 inode->nsName,
pcercuei 0:03b5121a232e 26418 inode->localName,
pcercuei 0:03b5121a232e 26419 inode->idcTable);
pcercuei 0:03b5121a232e 26420 #endif
pcercuei 0:03b5121a232e 26421 if ((vctxt->depth > 0) &&
pcercuei 0:03b5121a232e 26422 (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
pcercuei 0:03b5121a232e 26423 {
pcercuei 0:03b5121a232e 26424 /*
pcercuei 0:03b5121a232e 26425 * Merge the IDC node table with the table of the parent node.
pcercuei 0:03b5121a232e 26426 */
pcercuei 0:03b5121a232e 26427 if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
pcercuei 0:03b5121a232e 26428 goto internal_error;
pcercuei 0:03b5121a232e 26429 }
pcercuei 0:03b5121a232e 26430 }
pcercuei 0:03b5121a232e 26431 /*
pcercuei 0:03b5121a232e 26432 * Clear the current ielem.
pcercuei 0:03b5121a232e 26433 * VAL TODO: Don't free the PSVI IDC tables if they are
pcercuei 0:03b5121a232e 26434 * requested for the PSVI.
pcercuei 0:03b5121a232e 26435 */
pcercuei 0:03b5121a232e 26436 xmlSchemaClearElemInfo(vctxt, inode);
pcercuei 0:03b5121a232e 26437 /*
pcercuei 0:03b5121a232e 26438 * Skip further processing if we are on the validation root.
pcercuei 0:03b5121a232e 26439 */
pcercuei 0:03b5121a232e 26440 if (vctxt->depth == 0) {
pcercuei 0:03b5121a232e 26441 vctxt->depth--;
pcercuei 0:03b5121a232e 26442 vctxt->inode = NULL;
pcercuei 0:03b5121a232e 26443 return (0);
pcercuei 0:03b5121a232e 26444 }
pcercuei 0:03b5121a232e 26445 /*
pcercuei 0:03b5121a232e 26446 * Reset the keyrefDepth if needed.
pcercuei 0:03b5121a232e 26447 */
pcercuei 0:03b5121a232e 26448 if (vctxt->aidcs != NULL) {
pcercuei 0:03b5121a232e 26449 xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
pcercuei 0:03b5121a232e 26450 do {
pcercuei 0:03b5121a232e 26451 if (aidc->keyrefDepth == vctxt->depth) {
pcercuei 0:03b5121a232e 26452 /*
pcercuei 0:03b5121a232e 26453 * A 'keyrefDepth' of a key/unique IDC matches the current
pcercuei 0:03b5121a232e 26454 * depth, this means that we are leaving the scope of the
pcercuei 0:03b5121a232e 26455 * top-most keyref IDC which refers to this IDC.
pcercuei 0:03b5121a232e 26456 */
pcercuei 0:03b5121a232e 26457 aidc->keyrefDepth = -1;
pcercuei 0:03b5121a232e 26458 }
pcercuei 0:03b5121a232e 26459 aidc = aidc->next;
pcercuei 0:03b5121a232e 26460 } while (aidc != NULL);
pcercuei 0:03b5121a232e 26461 }
pcercuei 0:03b5121a232e 26462 vctxt->depth--;
pcercuei 0:03b5121a232e 26463 vctxt->inode = vctxt->elemInfos[vctxt->depth];
pcercuei 0:03b5121a232e 26464 /*
pcercuei 0:03b5121a232e 26465 * VAL TODO: 7 If the element information item is the `validation root`, it must be
pcercuei 0:03b5121a232e 26466 * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
pcercuei 0:03b5121a232e 26467 */
pcercuei 0:03b5121a232e 26468 return (ret);
pcercuei 0:03b5121a232e 26469
pcercuei 0:03b5121a232e 26470 internal_error:
pcercuei 0:03b5121a232e 26471 vctxt->err = -1;
pcercuei 0:03b5121a232e 26472 return (-1);
pcercuei 0:03b5121a232e 26473 }
pcercuei 0:03b5121a232e 26474
pcercuei 0:03b5121a232e 26475 /*
pcercuei 0:03b5121a232e 26476 * 3.4.4 Complex Type Definition Validation Rules
pcercuei 0:03b5121a232e 26477 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
pcercuei 0:03b5121a232e 26478 */
pcercuei 0:03b5121a232e 26479 static int
pcercuei 0:03b5121a232e 26480 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 26481 {
pcercuei 0:03b5121a232e 26482 xmlSchemaNodeInfoPtr pielem;
pcercuei 0:03b5121a232e 26483 xmlSchemaTypePtr ptype;
pcercuei 0:03b5121a232e 26484 int ret = 0;
pcercuei 0:03b5121a232e 26485
pcercuei 0:03b5121a232e 26486 if (vctxt->depth <= 0) {
pcercuei 0:03b5121a232e 26487 VERROR_INT("xmlSchemaValidateChildElem",
pcercuei 0:03b5121a232e 26488 "not intended for the validation root");
pcercuei 0:03b5121a232e 26489 return (-1);
pcercuei 0:03b5121a232e 26490 }
pcercuei 0:03b5121a232e 26491 pielem = vctxt->elemInfos[vctxt->depth -1];
pcercuei 0:03b5121a232e 26492 if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
pcercuei 0:03b5121a232e 26493 pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
pcercuei 0:03b5121a232e 26494 /*
pcercuei 0:03b5121a232e 26495 * Handle 'nilled' elements.
pcercuei 0:03b5121a232e 26496 */
pcercuei 0:03b5121a232e 26497 if (INODE_NILLED(pielem)) {
pcercuei 0:03b5121a232e 26498 /*
pcercuei 0:03b5121a232e 26499 * SPEC (cvc-elt) (3.3.4) : (3.2.1)
pcercuei 0:03b5121a232e 26500 */
pcercuei 0:03b5121a232e 26501 ACTIVATE_PARENT_ELEM;
pcercuei 0:03b5121a232e 26502 ret = XML_SCHEMAV_CVC_ELT_3_2_1;
pcercuei 0:03b5121a232e 26503 VERROR(ret, NULL,
pcercuei 0:03b5121a232e 26504 "Neither character nor element content is allowed, "
pcercuei 0:03b5121a232e 26505 "because the element was 'nilled'");
pcercuei 0:03b5121a232e 26506 ACTIVATE_ELEM;
pcercuei 0:03b5121a232e 26507 goto unexpected_elem;
pcercuei 0:03b5121a232e 26508 }
pcercuei 0:03b5121a232e 26509
pcercuei 0:03b5121a232e 26510 ptype = pielem->typeDef;
pcercuei 0:03b5121a232e 26511
pcercuei 0:03b5121a232e 26512 if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
pcercuei 0:03b5121a232e 26513 /*
pcercuei 0:03b5121a232e 26514 * Workaround for "anyType": we have currently no content model
pcercuei 0:03b5121a232e 26515 * assigned for "anyType", so handle it explicitely.
pcercuei 0:03b5121a232e 26516 * "anyType" has an unbounded, lax "any" wildcard.
pcercuei 0:03b5121a232e 26517 */
pcercuei 0:03b5121a232e 26518 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
pcercuei 0:03b5121a232e 26519 vctxt->inode->localName,
pcercuei 0:03b5121a232e 26520 vctxt->inode->nsName);
pcercuei 0:03b5121a232e 26521
pcercuei 0:03b5121a232e 26522 if (vctxt->inode->decl == NULL) {
pcercuei 0:03b5121a232e 26523 xmlSchemaAttrInfoPtr iattr;
pcercuei 0:03b5121a232e 26524 /*
pcercuei 0:03b5121a232e 26525 * Process "xsi:type".
pcercuei 0:03b5121a232e 26526 * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
pcercuei 0:03b5121a232e 26527 */
pcercuei 0:03b5121a232e 26528 iattr = xmlSchemaGetMetaAttrInfo(vctxt,
pcercuei 0:03b5121a232e 26529 XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
pcercuei 0:03b5121a232e 26530 if (iattr != NULL) {
pcercuei 0:03b5121a232e 26531 ret = xmlSchemaProcessXSIType(vctxt, iattr,
pcercuei 0:03b5121a232e 26532 &(vctxt->inode->typeDef), NULL);
pcercuei 0:03b5121a232e 26533 if (ret != 0) {
pcercuei 0:03b5121a232e 26534 if (ret == -1) {
pcercuei 0:03b5121a232e 26535 VERROR_INT("xmlSchemaValidateChildElem",
pcercuei 0:03b5121a232e 26536 "calling xmlSchemaProcessXSIType() to "
pcercuei 0:03b5121a232e 26537 "process the attribute 'xsi:nil'");
pcercuei 0:03b5121a232e 26538 return (-1);
pcercuei 0:03b5121a232e 26539 }
pcercuei 0:03b5121a232e 26540 return (ret);
pcercuei 0:03b5121a232e 26541 }
pcercuei 0:03b5121a232e 26542 } else {
pcercuei 0:03b5121a232e 26543 /*
pcercuei 0:03b5121a232e 26544 * Fallback to "anyType".
pcercuei 0:03b5121a232e 26545 *
pcercuei 0:03b5121a232e 26546 * SPEC (cvc-assess-elt)
pcercuei 0:03b5121a232e 26547 * "If the item cannot be `strictly assessed`, [...]
pcercuei 0:03b5121a232e 26548 * an element information item's schema validity may be laxly
pcercuei 0:03b5121a232e 26549 * assessed if its `context-determined declaration` is not
pcercuei 0:03b5121a232e 26550 * skip by `validating` with respect to the `ur-type
pcercuei 0:03b5121a232e 26551 * definition` as per Element Locally Valid (Type) ($3.3.4)."
pcercuei 0:03b5121a232e 26552 */
pcercuei 0:03b5121a232e 26553 vctxt->inode->typeDef =
pcercuei 0:03b5121a232e 26554 xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
pcercuei 0:03b5121a232e 26555 }
pcercuei 0:03b5121a232e 26556 }
pcercuei 0:03b5121a232e 26557 return (0);
pcercuei 0:03b5121a232e 26558 }
pcercuei 0:03b5121a232e 26559
pcercuei 0:03b5121a232e 26560 switch (ptype->contentType) {
pcercuei 0:03b5121a232e 26561 case XML_SCHEMA_CONTENT_EMPTY:
pcercuei 0:03b5121a232e 26562 /*
pcercuei 0:03b5121a232e 26563 * SPEC (2.1) "If the {content type} is empty, then the
pcercuei 0:03b5121a232e 26564 * element information item has no character or element
pcercuei 0:03b5121a232e 26565 * information item [children]."
pcercuei 0:03b5121a232e 26566 */
pcercuei 0:03b5121a232e 26567 ACTIVATE_PARENT_ELEM
pcercuei 0:03b5121a232e 26568 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
pcercuei 0:03b5121a232e 26569 VERROR(ret, NULL,
pcercuei 0:03b5121a232e 26570 "Element content is not allowed, "
pcercuei 0:03b5121a232e 26571 "because the content type is empty");
pcercuei 0:03b5121a232e 26572 ACTIVATE_ELEM
pcercuei 0:03b5121a232e 26573 goto unexpected_elem;
pcercuei 0:03b5121a232e 26574 break;
pcercuei 0:03b5121a232e 26575
pcercuei 0:03b5121a232e 26576 case XML_SCHEMA_CONTENT_MIXED:
pcercuei 0:03b5121a232e 26577 case XML_SCHEMA_CONTENT_ELEMENTS: {
pcercuei 0:03b5121a232e 26578 xmlRegExecCtxtPtr regexCtxt;
pcercuei 0:03b5121a232e 26579 xmlChar *values[10];
pcercuei 0:03b5121a232e 26580 int terminal, nbval = 10, nbneg;
pcercuei 0:03b5121a232e 26581
pcercuei 0:03b5121a232e 26582 /* VAL TODO: Optimized "anyType" validation.*/
pcercuei 0:03b5121a232e 26583
pcercuei 0:03b5121a232e 26584 if (ptype->contModel == NULL) {
pcercuei 0:03b5121a232e 26585 VERROR_INT("xmlSchemaValidateChildElem",
pcercuei 0:03b5121a232e 26586 "type has elem content but no content model");
pcercuei 0:03b5121a232e 26587 return (-1);
pcercuei 0:03b5121a232e 26588 }
pcercuei 0:03b5121a232e 26589 /*
pcercuei 0:03b5121a232e 26590 * Safety belf for evaluation if the cont. model was already
pcercuei 0:03b5121a232e 26591 * examined to be invalid.
pcercuei 0:03b5121a232e 26592 */
pcercuei 0:03b5121a232e 26593 if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
pcercuei 0:03b5121a232e 26594 VERROR_INT("xmlSchemaValidateChildElem",
pcercuei 0:03b5121a232e 26595 "validating elem, but elem content is already invalid");
pcercuei 0:03b5121a232e 26596 return (-1);
pcercuei 0:03b5121a232e 26597 }
pcercuei 0:03b5121a232e 26598
pcercuei 0:03b5121a232e 26599 regexCtxt = pielem->regexCtxt;
pcercuei 0:03b5121a232e 26600 if (regexCtxt == NULL) {
pcercuei 0:03b5121a232e 26601 /*
pcercuei 0:03b5121a232e 26602 * Create the regex context.
pcercuei 0:03b5121a232e 26603 */
pcercuei 0:03b5121a232e 26604 regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
pcercuei 0:03b5121a232e 26605 (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
pcercuei 0:03b5121a232e 26606 vctxt);
pcercuei 0:03b5121a232e 26607 if (regexCtxt == NULL) {
pcercuei 0:03b5121a232e 26608 VERROR_INT("xmlSchemaValidateChildElem",
pcercuei 0:03b5121a232e 26609 "failed to create a regex context");
pcercuei 0:03b5121a232e 26610 return (-1);
pcercuei 0:03b5121a232e 26611 }
pcercuei 0:03b5121a232e 26612 pielem->regexCtxt = regexCtxt;
pcercuei 0:03b5121a232e 26613 #ifdef DEBUG_AUTOMATA
pcercuei 0:03b5121a232e 26614 xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
pcercuei 0:03b5121a232e 26615 pielem->localName);
pcercuei 0:03b5121a232e 26616 #endif
pcercuei 0:03b5121a232e 26617 }
pcercuei 0:03b5121a232e 26618
pcercuei 0:03b5121a232e 26619 /*
pcercuei 0:03b5121a232e 26620 * SPEC (2.4) "If the {content type} is element-only or mixed,
pcercuei 0:03b5121a232e 26621 * then the sequence of the element information item's
pcercuei 0:03b5121a232e 26622 * element information item [children], if any, taken in
pcercuei 0:03b5121a232e 26623 * order, is `valid` with respect to the {content type}'s
pcercuei 0:03b5121a232e 26624 * particle, as defined in Element Sequence Locally Valid
pcercuei 0:03b5121a232e 26625 * (Particle) ($3.9.4)."
pcercuei 0:03b5121a232e 26626 */
pcercuei 0:03b5121a232e 26627 ret = xmlRegExecPushString2(regexCtxt,
pcercuei 0:03b5121a232e 26628 vctxt->inode->localName,
pcercuei 0:03b5121a232e 26629 vctxt->inode->nsName,
pcercuei 0:03b5121a232e 26630 vctxt->inode);
pcercuei 0:03b5121a232e 26631 #ifdef DEBUG_AUTOMATA
pcercuei 0:03b5121a232e 26632 if (ret < 0)
pcercuei 0:03b5121a232e 26633 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 26634 "AUTOMATON push ERROR for '%s' on '%s'\n",
pcercuei 0:03b5121a232e 26635 vctxt->inode->localName, pielem->localName);
pcercuei 0:03b5121a232e 26636 else
pcercuei 0:03b5121a232e 26637 xmlGenericError(xmlGenericErrorContext,
pcercuei 0:03b5121a232e 26638 "AUTOMATON push OK for '%s' on '%s'\n",
pcercuei 0:03b5121a232e 26639 vctxt->inode->localName, pielem->localName);
pcercuei 0:03b5121a232e 26640 #endif
pcercuei 0:03b5121a232e 26641 if (vctxt->err == XML_SCHEMAV_INTERNAL) {
pcercuei 0:03b5121a232e 26642 VERROR_INT("xmlSchemaValidateChildElem",
pcercuei 0:03b5121a232e 26643 "calling xmlRegExecPushString2()");
pcercuei 0:03b5121a232e 26644 return (-1);
pcercuei 0:03b5121a232e 26645 }
pcercuei 0:03b5121a232e 26646 if (ret < 0) {
pcercuei 0:03b5121a232e 26647 xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
pcercuei 0:03b5121a232e 26648 &values[0], &terminal);
pcercuei 0:03b5121a232e 26649 xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
pcercuei 0:03b5121a232e 26650 XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
pcercuei 0:03b5121a232e 26651 "This element is not expected",
pcercuei 0:03b5121a232e 26652 nbval, nbneg, values);
pcercuei 0:03b5121a232e 26653 ret = vctxt->err;
pcercuei 0:03b5121a232e 26654 goto unexpected_elem;
pcercuei 0:03b5121a232e 26655 } else
pcercuei 0:03b5121a232e 26656 ret = 0;
pcercuei 0:03b5121a232e 26657 }
pcercuei 0:03b5121a232e 26658 break;
pcercuei 0:03b5121a232e 26659 case XML_SCHEMA_CONTENT_SIMPLE:
pcercuei 0:03b5121a232e 26660 case XML_SCHEMA_CONTENT_BASIC:
pcercuei 0:03b5121a232e 26661 ACTIVATE_PARENT_ELEM
pcercuei 0:03b5121a232e 26662 if (WXS_IS_COMPLEX(ptype)) {
pcercuei 0:03b5121a232e 26663 /*
pcercuei 0:03b5121a232e 26664 * SPEC (cvc-complex-type) (2.2)
pcercuei 0:03b5121a232e 26665 * "If the {content type} is a simple type definition, then
pcercuei 0:03b5121a232e 26666 * the element information item has no element information
pcercuei 0:03b5121a232e 26667 * item [children], ..."
pcercuei 0:03b5121a232e 26668 */
pcercuei 0:03b5121a232e 26669 ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
pcercuei 0:03b5121a232e 26670 VERROR(ret, NULL, "Element content is not allowed, "
pcercuei 0:03b5121a232e 26671 "because the content type is a simple type definition");
pcercuei 0:03b5121a232e 26672 } else {
pcercuei 0:03b5121a232e 26673 /*
pcercuei 0:03b5121a232e 26674 * SPEC (cvc-type) (3.1.2) "The element information item must
pcercuei 0:03b5121a232e 26675 * have no element information item [children]."
pcercuei 0:03b5121a232e 26676 */
pcercuei 0:03b5121a232e 26677 ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
pcercuei 0:03b5121a232e 26678 VERROR(ret, NULL, "Element content is not allowed, "
pcercuei 0:03b5121a232e 26679 "because the type definition is simple");
pcercuei 0:03b5121a232e 26680 }
pcercuei 0:03b5121a232e 26681 ACTIVATE_ELEM
pcercuei 0:03b5121a232e 26682 ret = vctxt->err;
pcercuei 0:03b5121a232e 26683 goto unexpected_elem;
pcercuei 0:03b5121a232e 26684 break;
pcercuei 0:03b5121a232e 26685
pcercuei 0:03b5121a232e 26686 default:
pcercuei 0:03b5121a232e 26687 break;
pcercuei 0:03b5121a232e 26688 }
pcercuei 0:03b5121a232e 26689 return (ret);
pcercuei 0:03b5121a232e 26690 unexpected_elem:
pcercuei 0:03b5121a232e 26691 /*
pcercuei 0:03b5121a232e 26692 * Pop this element and set the skipDepth to skip
pcercuei 0:03b5121a232e 26693 * all further content of the parent element.
pcercuei 0:03b5121a232e 26694 */
pcercuei 0:03b5121a232e 26695 vctxt->skipDepth = vctxt->depth;
pcercuei 0:03b5121a232e 26696 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
pcercuei 0:03b5121a232e 26697 pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
pcercuei 0:03b5121a232e 26698 return (ret);
pcercuei 0:03b5121a232e 26699 }
pcercuei 0:03b5121a232e 26700
pcercuei 0:03b5121a232e 26701 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
pcercuei 0:03b5121a232e 26702 #define XML_SCHEMA_PUSH_TEXT_CREATED 2
pcercuei 0:03b5121a232e 26703 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
pcercuei 0:03b5121a232e 26704
pcercuei 0:03b5121a232e 26705 static int
pcercuei 0:03b5121a232e 26706 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 26707 int nodeType, const xmlChar *value, int len,
pcercuei 0:03b5121a232e 26708 int mode, int *consumed)
pcercuei 0:03b5121a232e 26709 {
pcercuei 0:03b5121a232e 26710 /*
pcercuei 0:03b5121a232e 26711 * Unfortunately we have to duplicate the text sometimes.
pcercuei 0:03b5121a232e 26712 * OPTIMIZE: Maybe we could skip it, if:
pcercuei 0:03b5121a232e 26713 * 1. content type is simple
pcercuei 0:03b5121a232e 26714 * 2. whitespace is "collapse"
pcercuei 0:03b5121a232e 26715 * 3. it consists of whitespace only
pcercuei 0:03b5121a232e 26716 *
pcercuei 0:03b5121a232e 26717 * Process character content.
pcercuei 0:03b5121a232e 26718 */
pcercuei 0:03b5121a232e 26719 if (consumed != NULL)
pcercuei 0:03b5121a232e 26720 *consumed = 0;
pcercuei 0:03b5121a232e 26721 if (INODE_NILLED(vctxt->inode)) {
pcercuei 0:03b5121a232e 26722 /*
pcercuei 0:03b5121a232e 26723 * SPEC cvc-elt (3.3.4 - 3.2.1)
pcercuei 0:03b5121a232e 26724 * "The element information item must have no character or
pcercuei 0:03b5121a232e 26725 * element information item [children]."
pcercuei 0:03b5121a232e 26726 */
pcercuei 0:03b5121a232e 26727 VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
pcercuei 0:03b5121a232e 26728 "Neither character nor element content is allowed "
pcercuei 0:03b5121a232e 26729 "because the element is 'nilled'");
pcercuei 0:03b5121a232e 26730 return (vctxt->err);
pcercuei 0:03b5121a232e 26731 }
pcercuei 0:03b5121a232e 26732 /*
pcercuei 0:03b5121a232e 26733 * SPEC (2.1) "If the {content type} is empty, then the
pcercuei 0:03b5121a232e 26734 * element information item has no character or element
pcercuei 0:03b5121a232e 26735 * information item [children]."
pcercuei 0:03b5121a232e 26736 */
pcercuei 0:03b5121a232e 26737 if (vctxt->inode->typeDef->contentType ==
pcercuei 0:03b5121a232e 26738 XML_SCHEMA_CONTENT_EMPTY) {
pcercuei 0:03b5121a232e 26739 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
pcercuei 0:03b5121a232e 26740 "Character content is not allowed, "
pcercuei 0:03b5121a232e 26741 "because the content type is empty");
pcercuei 0:03b5121a232e 26742 return (vctxt->err);
pcercuei 0:03b5121a232e 26743 }
pcercuei 0:03b5121a232e 26744
pcercuei 0:03b5121a232e 26745 if (vctxt->inode->typeDef->contentType ==
pcercuei 0:03b5121a232e 26746 XML_SCHEMA_CONTENT_ELEMENTS) {
pcercuei 0:03b5121a232e 26747 if ((nodeType != XML_TEXT_NODE) ||
pcercuei 0:03b5121a232e 26748 (! xmlSchemaIsBlank((xmlChar *) value, len))) {
pcercuei 0:03b5121a232e 26749 /*
pcercuei 0:03b5121a232e 26750 * SPEC cvc-complex-type (2.3)
pcercuei 0:03b5121a232e 26751 * "If the {content type} is element-only, then the
pcercuei 0:03b5121a232e 26752 * element information item has no character information
pcercuei 0:03b5121a232e 26753 * item [children] other than those whose [character
pcercuei 0:03b5121a232e 26754 * code] is defined as a white space in [XML 1.0 (Second
pcercuei 0:03b5121a232e 26755 * Edition)]."
pcercuei 0:03b5121a232e 26756 */
pcercuei 0:03b5121a232e 26757 VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
pcercuei 0:03b5121a232e 26758 "Character content other than whitespace is not allowed "
pcercuei 0:03b5121a232e 26759 "because the content type is 'element-only'");
pcercuei 0:03b5121a232e 26760 return (vctxt->err);
pcercuei 0:03b5121a232e 26761 }
pcercuei 0:03b5121a232e 26762 return (0);
pcercuei 0:03b5121a232e 26763 }
pcercuei 0:03b5121a232e 26764
pcercuei 0:03b5121a232e 26765 if ((value == NULL) || (value[0] == 0))
pcercuei 0:03b5121a232e 26766 return (0);
pcercuei 0:03b5121a232e 26767 /*
pcercuei 0:03b5121a232e 26768 * Save the value.
pcercuei 0:03b5121a232e 26769 * NOTE that even if the content type is *mixed*, we need the
pcercuei 0:03b5121a232e 26770 * *initial value* for default/fixed value constraints.
pcercuei 0:03b5121a232e 26771 */
pcercuei 0:03b5121a232e 26772 if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
pcercuei 0:03b5121a232e 26773 ((vctxt->inode->decl == NULL) ||
pcercuei 0:03b5121a232e 26774 (vctxt->inode->decl->value == NULL)))
pcercuei 0:03b5121a232e 26775 return (0);
pcercuei 0:03b5121a232e 26776
pcercuei 0:03b5121a232e 26777 if (vctxt->inode->value == NULL) {
pcercuei 0:03b5121a232e 26778 /*
pcercuei 0:03b5121a232e 26779 * Set the value.
pcercuei 0:03b5121a232e 26780 */
pcercuei 0:03b5121a232e 26781 switch (mode) {
pcercuei 0:03b5121a232e 26782 case XML_SCHEMA_PUSH_TEXT_PERSIST:
pcercuei 0:03b5121a232e 26783 /*
pcercuei 0:03b5121a232e 26784 * When working on a tree.
pcercuei 0:03b5121a232e 26785 */
pcercuei 0:03b5121a232e 26786 vctxt->inode->value = value;
pcercuei 0:03b5121a232e 26787 break;
pcercuei 0:03b5121a232e 26788 case XML_SCHEMA_PUSH_TEXT_CREATED:
pcercuei 0:03b5121a232e 26789 /*
pcercuei 0:03b5121a232e 26790 * When working with the reader.
pcercuei 0:03b5121a232e 26791 * The value will be freed by the element info.
pcercuei 0:03b5121a232e 26792 */
pcercuei 0:03b5121a232e 26793 vctxt->inode->value = value;
pcercuei 0:03b5121a232e 26794 if (consumed != NULL)
pcercuei 0:03b5121a232e 26795 *consumed = 1;
pcercuei 0:03b5121a232e 26796 vctxt->inode->flags |=
pcercuei 0:03b5121a232e 26797 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
pcercuei 0:03b5121a232e 26798 break;
pcercuei 0:03b5121a232e 26799 case XML_SCHEMA_PUSH_TEXT_VOLATILE:
pcercuei 0:03b5121a232e 26800 /*
pcercuei 0:03b5121a232e 26801 * When working with SAX.
pcercuei 0:03b5121a232e 26802 * The value will be freed by the element info.
pcercuei 0:03b5121a232e 26803 */
pcercuei 0:03b5121a232e 26804 if (len != -1)
pcercuei 0:03b5121a232e 26805 vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
pcercuei 0:03b5121a232e 26806 else
pcercuei 0:03b5121a232e 26807 vctxt->inode->value = BAD_CAST xmlStrdup(value);
pcercuei 0:03b5121a232e 26808 vctxt->inode->flags |=
pcercuei 0:03b5121a232e 26809 XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
pcercuei 0:03b5121a232e 26810 break;
pcercuei 0:03b5121a232e 26811 default:
pcercuei 0:03b5121a232e 26812 break;
pcercuei 0:03b5121a232e 26813 }
pcercuei 0:03b5121a232e 26814 } else {
pcercuei 0:03b5121a232e 26815 if (len < 0)
pcercuei 0:03b5121a232e 26816 len = xmlStrlen(value);
pcercuei 0:03b5121a232e 26817 /*
pcercuei 0:03b5121a232e 26818 * Concat the value.
pcercuei 0:03b5121a232e 26819 */
pcercuei 0:03b5121a232e 26820 if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
pcercuei 0:03b5121a232e 26821 vctxt->inode->value = BAD_CAST xmlStrncat(
pcercuei 0:03b5121a232e 26822 (xmlChar *) vctxt->inode->value, value, len);
pcercuei 0:03b5121a232e 26823 } else {
pcercuei 0:03b5121a232e 26824 vctxt->inode->value =
pcercuei 0:03b5121a232e 26825 BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
pcercuei 0:03b5121a232e 26826 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
pcercuei 0:03b5121a232e 26827 }
pcercuei 0:03b5121a232e 26828 }
pcercuei 0:03b5121a232e 26829
pcercuei 0:03b5121a232e 26830 return (0);
pcercuei 0:03b5121a232e 26831 }
pcercuei 0:03b5121a232e 26832
pcercuei 0:03b5121a232e 26833 static int
pcercuei 0:03b5121a232e 26834 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 26835 {
pcercuei 0:03b5121a232e 26836 int ret = 0;
pcercuei 0:03b5121a232e 26837
pcercuei 0:03b5121a232e 26838 if ((vctxt->skipDepth != -1) &&
pcercuei 0:03b5121a232e 26839 (vctxt->depth >= vctxt->skipDepth)) {
pcercuei 0:03b5121a232e 26840 VERROR_INT("xmlSchemaValidateElem",
pcercuei 0:03b5121a232e 26841 "in skip-state");
pcercuei 0:03b5121a232e 26842 goto internal_error;
pcercuei 0:03b5121a232e 26843 }
pcercuei 0:03b5121a232e 26844 if (vctxt->xsiAssemble) {
pcercuei 0:03b5121a232e 26845 /*
pcercuei 0:03b5121a232e 26846 * We will stop validation if there was an error during
pcercuei 0:03b5121a232e 26847 * dynamic schema construction.
pcercuei 0:03b5121a232e 26848 * Note that we simply set @skipDepth to 0, this could
pcercuei 0:03b5121a232e 26849 * mean that a streaming document via SAX would be
pcercuei 0:03b5121a232e 26850 * still read to the end but it won't be validated any more.
pcercuei 0:03b5121a232e 26851 * TODO: If we are sure how to stop the validation at once
pcercuei 0:03b5121a232e 26852 * for all input scenarios, then this should be changed to
pcercuei 0:03b5121a232e 26853 * instantly stop the validation.
pcercuei 0:03b5121a232e 26854 */
pcercuei 0:03b5121a232e 26855 ret = xmlSchemaAssembleByXSI(vctxt);
pcercuei 0:03b5121a232e 26856 if (ret != 0) {
pcercuei 0:03b5121a232e 26857 if (ret == -1)
pcercuei 0:03b5121a232e 26858 goto internal_error;
pcercuei 0:03b5121a232e 26859 vctxt->skipDepth = 0;
pcercuei 0:03b5121a232e 26860 return(ret);
pcercuei 0:03b5121a232e 26861 }
pcercuei 0:03b5121a232e 26862 /*
pcercuei 0:03b5121a232e 26863 * Augment the IDC definitions for the main schema and all imported ones
pcercuei 0:03b5121a232e 26864 * NOTE: main schema is the first in the imported list
pcercuei 0:03b5121a232e 26865 */
pcercuei 0:03b5121a232e 26866 xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
pcercuei 0:03b5121a232e 26867 }
pcercuei 0:03b5121a232e 26868 if (vctxt->depth > 0) {
pcercuei 0:03b5121a232e 26869 /*
pcercuei 0:03b5121a232e 26870 * Validate this element against the content model
pcercuei 0:03b5121a232e 26871 * of the parent.
pcercuei 0:03b5121a232e 26872 */
pcercuei 0:03b5121a232e 26873 ret = xmlSchemaValidateChildElem(vctxt);
pcercuei 0:03b5121a232e 26874 if (ret != 0) {
pcercuei 0:03b5121a232e 26875 if (ret < 0) {
pcercuei 0:03b5121a232e 26876 VERROR_INT("xmlSchemaValidateElem",
pcercuei 0:03b5121a232e 26877 "calling xmlSchemaStreamValidateChildElement()");
pcercuei 0:03b5121a232e 26878 goto internal_error;
pcercuei 0:03b5121a232e 26879 }
pcercuei 0:03b5121a232e 26880 goto exit;
pcercuei 0:03b5121a232e 26881 }
pcercuei 0:03b5121a232e 26882 if (vctxt->depth == vctxt->skipDepth)
pcercuei 0:03b5121a232e 26883 goto exit;
pcercuei 0:03b5121a232e 26884 if ((vctxt->inode->decl == NULL) &&
pcercuei 0:03b5121a232e 26885 (vctxt->inode->typeDef == NULL)) {
pcercuei 0:03b5121a232e 26886 VERROR_INT("xmlSchemaValidateElem",
pcercuei 0:03b5121a232e 26887 "the child element was valid but neither the "
pcercuei 0:03b5121a232e 26888 "declaration nor the type was set");
pcercuei 0:03b5121a232e 26889 goto internal_error;
pcercuei 0:03b5121a232e 26890 }
pcercuei 0:03b5121a232e 26891 } else {
pcercuei 0:03b5121a232e 26892 /*
pcercuei 0:03b5121a232e 26893 * Get the declaration of the validation root.
pcercuei 0:03b5121a232e 26894 */
pcercuei 0:03b5121a232e 26895 vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
pcercuei 0:03b5121a232e 26896 vctxt->inode->localName,
pcercuei 0:03b5121a232e 26897 vctxt->inode->nsName);
pcercuei 0:03b5121a232e 26898 if (vctxt->inode->decl == NULL) {
pcercuei 0:03b5121a232e 26899 ret = XML_SCHEMAV_CVC_ELT_1;
pcercuei 0:03b5121a232e 26900 VERROR(ret, NULL,
pcercuei 0:03b5121a232e 26901 "No matching global declaration available "
pcercuei 0:03b5121a232e 26902 "for the validation root");
pcercuei 0:03b5121a232e 26903 goto exit;
pcercuei 0:03b5121a232e 26904 }
pcercuei 0:03b5121a232e 26905 }
pcercuei 0:03b5121a232e 26906
pcercuei 0:03b5121a232e 26907 if (vctxt->inode->decl == NULL)
pcercuei 0:03b5121a232e 26908 goto type_validation;
pcercuei 0:03b5121a232e 26909
pcercuei 0:03b5121a232e 26910 if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
pcercuei 0:03b5121a232e 26911 int skip;
pcercuei 0:03b5121a232e 26912 /*
pcercuei 0:03b5121a232e 26913 * Wildcards.
pcercuei 0:03b5121a232e 26914 */
pcercuei 0:03b5121a232e 26915 ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
pcercuei 0:03b5121a232e 26916 if (ret != 0) {
pcercuei 0:03b5121a232e 26917 if (ret < 0) {
pcercuei 0:03b5121a232e 26918 VERROR_INT("xmlSchemaValidateElem",
pcercuei 0:03b5121a232e 26919 "calling xmlSchemaValidateElemWildcard()");
pcercuei 0:03b5121a232e 26920 goto internal_error;
pcercuei 0:03b5121a232e 26921 }
pcercuei 0:03b5121a232e 26922 goto exit;
pcercuei 0:03b5121a232e 26923 }
pcercuei 0:03b5121a232e 26924 if (skip) {
pcercuei 0:03b5121a232e 26925 vctxt->skipDepth = vctxt->depth;
pcercuei 0:03b5121a232e 26926 goto exit;
pcercuei 0:03b5121a232e 26927 }
pcercuei 0:03b5121a232e 26928 /*
pcercuei 0:03b5121a232e 26929 * The declaration might be set by the wildcard validation,
pcercuei 0:03b5121a232e 26930 * when the processContents is "lax" or "strict".
pcercuei 0:03b5121a232e 26931 */
pcercuei 0:03b5121a232e 26932 if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
pcercuei 0:03b5121a232e 26933 /*
pcercuei 0:03b5121a232e 26934 * Clear the "decl" field to not confuse further processing.
pcercuei 0:03b5121a232e 26935 */
pcercuei 0:03b5121a232e 26936 vctxt->inode->decl = NULL;
pcercuei 0:03b5121a232e 26937 goto type_validation;
pcercuei 0:03b5121a232e 26938 }
pcercuei 0:03b5121a232e 26939 }
pcercuei 0:03b5121a232e 26940 /*
pcercuei 0:03b5121a232e 26941 * Validate against the declaration.
pcercuei 0:03b5121a232e 26942 */
pcercuei 0:03b5121a232e 26943 ret = xmlSchemaValidateElemDecl(vctxt);
pcercuei 0:03b5121a232e 26944 if (ret != 0) {
pcercuei 0:03b5121a232e 26945 if (ret < 0) {
pcercuei 0:03b5121a232e 26946 VERROR_INT("xmlSchemaValidateElem",
pcercuei 0:03b5121a232e 26947 "calling xmlSchemaValidateElemDecl()");
pcercuei 0:03b5121a232e 26948 goto internal_error;
pcercuei 0:03b5121a232e 26949 }
pcercuei 0:03b5121a232e 26950 goto exit;
pcercuei 0:03b5121a232e 26951 }
pcercuei 0:03b5121a232e 26952 /*
pcercuei 0:03b5121a232e 26953 * Validate against the type definition.
pcercuei 0:03b5121a232e 26954 */
pcercuei 0:03b5121a232e 26955 type_validation:
pcercuei 0:03b5121a232e 26956
pcercuei 0:03b5121a232e 26957 if (vctxt->inode->typeDef == NULL) {
pcercuei 0:03b5121a232e 26958 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
pcercuei 0:03b5121a232e 26959 ret = XML_SCHEMAV_CVC_TYPE_1;
pcercuei 0:03b5121a232e 26960 VERROR(ret, NULL,
pcercuei 0:03b5121a232e 26961 "The type definition is absent");
pcercuei 0:03b5121a232e 26962 goto exit;
pcercuei 0:03b5121a232e 26963 }
pcercuei 0:03b5121a232e 26964 if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
pcercuei 0:03b5121a232e 26965 vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
pcercuei 0:03b5121a232e 26966 ret = XML_SCHEMAV_CVC_TYPE_2;
pcercuei 0:03b5121a232e 26967 VERROR(ret, NULL,
pcercuei 0:03b5121a232e 26968 "The type definition is abstract");
pcercuei 0:03b5121a232e 26969 goto exit;
pcercuei 0:03b5121a232e 26970 }
pcercuei 0:03b5121a232e 26971 /*
pcercuei 0:03b5121a232e 26972 * Evaluate IDCs. Do it here, since new IDC matchers are registered
pcercuei 0:03b5121a232e 26973 * during validation against the declaration. This must be done
pcercuei 0:03b5121a232e 26974 * _before_ attribute validation.
pcercuei 0:03b5121a232e 26975 */
pcercuei 0:03b5121a232e 26976 if (vctxt->xpathStates != NULL) {
pcercuei 0:03b5121a232e 26977 ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
pcercuei 0:03b5121a232e 26978 vctxt->inode->appliedXPath = 1;
pcercuei 0:03b5121a232e 26979 if (ret == -1) {
pcercuei 0:03b5121a232e 26980 VERROR_INT("xmlSchemaValidateElem",
pcercuei 0:03b5121a232e 26981 "calling xmlSchemaXPathEvaluate()");
pcercuei 0:03b5121a232e 26982 goto internal_error;
pcercuei 0:03b5121a232e 26983 }
pcercuei 0:03b5121a232e 26984 }
pcercuei 0:03b5121a232e 26985 /*
pcercuei 0:03b5121a232e 26986 * Validate attributes.
pcercuei 0:03b5121a232e 26987 */
pcercuei 0:03b5121a232e 26988 if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
pcercuei 0:03b5121a232e 26989 if ((vctxt->nbAttrInfos != 0) ||
pcercuei 0:03b5121a232e 26990 (vctxt->inode->typeDef->attrUses != NULL)) {
pcercuei 0:03b5121a232e 26991
pcercuei 0:03b5121a232e 26992 ret = xmlSchemaVAttributesComplex(vctxt);
pcercuei 0:03b5121a232e 26993 }
pcercuei 0:03b5121a232e 26994 } else if (vctxt->nbAttrInfos != 0) {
pcercuei 0:03b5121a232e 26995
pcercuei 0:03b5121a232e 26996 ret = xmlSchemaVAttributesSimple(vctxt);
pcercuei 0:03b5121a232e 26997 }
pcercuei 0:03b5121a232e 26998 /*
pcercuei 0:03b5121a232e 26999 * Clear registered attributes.
pcercuei 0:03b5121a232e 27000 */
pcercuei 0:03b5121a232e 27001 if (vctxt->nbAttrInfos != 0)
pcercuei 0:03b5121a232e 27002 xmlSchemaClearAttrInfos(vctxt);
pcercuei 0:03b5121a232e 27003 if (ret == -1) {
pcercuei 0:03b5121a232e 27004 VERROR_INT("xmlSchemaValidateElem",
pcercuei 0:03b5121a232e 27005 "calling attributes validation");
pcercuei 0:03b5121a232e 27006 goto internal_error;
pcercuei 0:03b5121a232e 27007 }
pcercuei 0:03b5121a232e 27008 /*
pcercuei 0:03b5121a232e 27009 * Don't return an error if attributes are invalid on purpose.
pcercuei 0:03b5121a232e 27010 */
pcercuei 0:03b5121a232e 27011 ret = 0;
pcercuei 0:03b5121a232e 27012
pcercuei 0:03b5121a232e 27013 exit:
pcercuei 0:03b5121a232e 27014 if (ret != 0)
pcercuei 0:03b5121a232e 27015 vctxt->skipDepth = vctxt->depth;
pcercuei 0:03b5121a232e 27016 return (ret);
pcercuei 0:03b5121a232e 27017 internal_error:
pcercuei 0:03b5121a232e 27018 return (-1);
pcercuei 0:03b5121a232e 27019 }
pcercuei 0:03b5121a232e 27020
pcercuei 0:03b5121a232e 27021 #ifdef XML_SCHEMA_READER_ENABLED
pcercuei 0:03b5121a232e 27022 static int
pcercuei 0:03b5121a232e 27023 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 27024 {
pcercuei 0:03b5121a232e 27025 const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
pcercuei 0:03b5121a232e 27026 int depth, nodeType, ret = 0, consumed;
pcercuei 0:03b5121a232e 27027 xmlSchemaNodeInfoPtr ielem;
pcercuei 0:03b5121a232e 27028
pcercuei 0:03b5121a232e 27029 vctxt->depth = -1;
pcercuei 0:03b5121a232e 27030 ret = xmlTextReaderRead(vctxt->reader);
pcercuei 0:03b5121a232e 27031 /*
pcercuei 0:03b5121a232e 27032 * Move to the document element.
pcercuei 0:03b5121a232e 27033 */
pcercuei 0:03b5121a232e 27034 while (ret == 1) {
pcercuei 0:03b5121a232e 27035 nodeType = xmlTextReaderNodeType(vctxt->reader);
pcercuei 0:03b5121a232e 27036 if (nodeType == XML_ELEMENT_NODE)
pcercuei 0:03b5121a232e 27037 goto root_found;
pcercuei 0:03b5121a232e 27038 ret = xmlTextReaderRead(vctxt->reader);
pcercuei 0:03b5121a232e 27039 }
pcercuei 0:03b5121a232e 27040 goto exit;
pcercuei 0:03b5121a232e 27041
pcercuei 0:03b5121a232e 27042 root_found:
pcercuei 0:03b5121a232e 27043
pcercuei 0:03b5121a232e 27044 do {
pcercuei 0:03b5121a232e 27045 depth = xmlTextReaderDepth(vctxt->reader);
pcercuei 0:03b5121a232e 27046 nodeType = xmlTextReaderNodeType(vctxt->reader);
pcercuei 0:03b5121a232e 27047
pcercuei 0:03b5121a232e 27048 if (nodeType == XML_ELEMENT_NODE) {
pcercuei 0:03b5121a232e 27049
pcercuei 0:03b5121a232e 27050 vctxt->depth++;
pcercuei 0:03b5121a232e 27051 if (xmlSchemaValidatorPushElem(vctxt) == -1) {
pcercuei 0:03b5121a232e 27052 VERROR_INT("xmlSchemaVReaderWalk",
pcercuei 0:03b5121a232e 27053 "calling xmlSchemaValidatorPushElem()");
pcercuei 0:03b5121a232e 27054 goto internal_error;
pcercuei 0:03b5121a232e 27055 }
pcercuei 0:03b5121a232e 27056 ielem = vctxt->inode;
pcercuei 0:03b5121a232e 27057 ielem->localName = xmlTextReaderLocalName(vctxt->reader);
pcercuei 0:03b5121a232e 27058 ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
pcercuei 0:03b5121a232e 27059 ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
pcercuei 0:03b5121a232e 27060 /*
pcercuei 0:03b5121a232e 27061 * Is the element empty?
pcercuei 0:03b5121a232e 27062 */
pcercuei 0:03b5121a232e 27063 ret = xmlTextReaderIsEmptyElement(vctxt->reader);
pcercuei 0:03b5121a232e 27064 if (ret == -1) {
pcercuei 0:03b5121a232e 27065 VERROR_INT("xmlSchemaVReaderWalk",
pcercuei 0:03b5121a232e 27066 "calling xmlTextReaderIsEmptyElement()");
pcercuei 0:03b5121a232e 27067 goto internal_error;
pcercuei 0:03b5121a232e 27068 }
pcercuei 0:03b5121a232e 27069 if (ret) {
pcercuei 0:03b5121a232e 27070 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
pcercuei 0:03b5121a232e 27071 }
pcercuei 0:03b5121a232e 27072 /*
pcercuei 0:03b5121a232e 27073 * Register attributes.
pcercuei 0:03b5121a232e 27074 */
pcercuei 0:03b5121a232e 27075 vctxt->nbAttrInfos = 0;
pcercuei 0:03b5121a232e 27076 ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
pcercuei 0:03b5121a232e 27077 if (ret == -1) {
pcercuei 0:03b5121a232e 27078 VERROR_INT("xmlSchemaVReaderWalk",
pcercuei 0:03b5121a232e 27079 "calling xmlTextReaderMoveToFirstAttribute()");
pcercuei 0:03b5121a232e 27080 goto internal_error;
pcercuei 0:03b5121a232e 27081 }
pcercuei 0:03b5121a232e 27082 if (ret == 1) {
pcercuei 0:03b5121a232e 27083 do {
pcercuei 0:03b5121a232e 27084 /*
pcercuei 0:03b5121a232e 27085 * VAL TODO: How do we know that the reader works on a
pcercuei 0:03b5121a232e 27086 * node tree, to be able to pass a node here?
pcercuei 0:03b5121a232e 27087 */
pcercuei 0:03b5121a232e 27088 if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
pcercuei 0:03b5121a232e 27089 (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
pcercuei 0:03b5121a232e 27090 xmlTextReaderNamespaceUri(vctxt->reader), 1,
pcercuei 0:03b5121a232e 27091 xmlTextReaderValue(vctxt->reader), 1) == -1) {
pcercuei 0:03b5121a232e 27092
pcercuei 0:03b5121a232e 27093 VERROR_INT("xmlSchemaVReaderWalk",
pcercuei 0:03b5121a232e 27094 "calling xmlSchemaValidatorPushAttribute()");
pcercuei 0:03b5121a232e 27095 goto internal_error;
pcercuei 0:03b5121a232e 27096 }
pcercuei 0:03b5121a232e 27097 ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
pcercuei 0:03b5121a232e 27098 if (ret == -1) {
pcercuei 0:03b5121a232e 27099 VERROR_INT("xmlSchemaVReaderWalk",
pcercuei 0:03b5121a232e 27100 "calling xmlTextReaderMoveToFirstAttribute()");
pcercuei 0:03b5121a232e 27101 goto internal_error;
pcercuei 0:03b5121a232e 27102 }
pcercuei 0:03b5121a232e 27103 } while (ret == 1);
pcercuei 0:03b5121a232e 27104 /*
pcercuei 0:03b5121a232e 27105 * Back to element position.
pcercuei 0:03b5121a232e 27106 */
pcercuei 0:03b5121a232e 27107 ret = xmlTextReaderMoveToElement(vctxt->reader);
pcercuei 0:03b5121a232e 27108 if (ret == -1) {
pcercuei 0:03b5121a232e 27109 VERROR_INT("xmlSchemaVReaderWalk",
pcercuei 0:03b5121a232e 27110 "calling xmlTextReaderMoveToElement()");
pcercuei 0:03b5121a232e 27111 goto internal_error;
pcercuei 0:03b5121a232e 27112 }
pcercuei 0:03b5121a232e 27113 }
pcercuei 0:03b5121a232e 27114 /*
pcercuei 0:03b5121a232e 27115 * Validate the element.
pcercuei 0:03b5121a232e 27116 */
pcercuei 0:03b5121a232e 27117 ret= xmlSchemaValidateElem(vctxt);
pcercuei 0:03b5121a232e 27118 if (ret != 0) {
pcercuei 0:03b5121a232e 27119 if (ret == -1) {
pcercuei 0:03b5121a232e 27120 VERROR_INT("xmlSchemaVReaderWalk",
pcercuei 0:03b5121a232e 27121 "calling xmlSchemaValidateElem()");
pcercuei 0:03b5121a232e 27122 goto internal_error;
pcercuei 0:03b5121a232e 27123 }
pcercuei 0:03b5121a232e 27124 goto exit;
pcercuei 0:03b5121a232e 27125 }
pcercuei 0:03b5121a232e 27126 if (vctxt->depth == vctxt->skipDepth) {
pcercuei 0:03b5121a232e 27127 int curDepth;
pcercuei 0:03b5121a232e 27128 /*
pcercuei 0:03b5121a232e 27129 * Skip all content.
pcercuei 0:03b5121a232e 27130 */
pcercuei 0:03b5121a232e 27131 if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
pcercuei 0:03b5121a232e 27132 ret = xmlTextReaderRead(vctxt->reader);
pcercuei 0:03b5121a232e 27133 curDepth = xmlTextReaderDepth(vctxt->reader);
pcercuei 0:03b5121a232e 27134 while ((ret == 1) && (curDepth != depth)) {
pcercuei 0:03b5121a232e 27135 ret = xmlTextReaderRead(vctxt->reader);
pcercuei 0:03b5121a232e 27136 curDepth = xmlTextReaderDepth(vctxt->reader);
pcercuei 0:03b5121a232e 27137 }
pcercuei 0:03b5121a232e 27138 if (ret < 0) {
pcercuei 0:03b5121a232e 27139 /*
pcercuei 0:03b5121a232e 27140 * VAL TODO: A reader error occured; what to do here?
pcercuei 0:03b5121a232e 27141 */
pcercuei 0:03b5121a232e 27142 ret = 1;
pcercuei 0:03b5121a232e 27143 goto exit;
pcercuei 0:03b5121a232e 27144 }
pcercuei 0:03b5121a232e 27145 }
pcercuei 0:03b5121a232e 27146 goto leave_elem;
pcercuei 0:03b5121a232e 27147 }
pcercuei 0:03b5121a232e 27148 /*
pcercuei 0:03b5121a232e 27149 * READER VAL TODO: Is an END_ELEM really never called
pcercuei 0:03b5121a232e 27150 * if the elem is empty?
pcercuei 0:03b5121a232e 27151 */
pcercuei 0:03b5121a232e 27152 if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
pcercuei 0:03b5121a232e 27153 goto leave_elem;
pcercuei 0:03b5121a232e 27154 } else if (nodeType == END_ELEM) {
pcercuei 0:03b5121a232e 27155 /*
pcercuei 0:03b5121a232e 27156 * Process END of element.
pcercuei 0:03b5121a232e 27157 */
pcercuei 0:03b5121a232e 27158 leave_elem:
pcercuei 0:03b5121a232e 27159 ret = xmlSchemaValidatorPopElem(vctxt);
pcercuei 0:03b5121a232e 27160 if (ret != 0) {
pcercuei 0:03b5121a232e 27161 if (ret < 0) {
pcercuei 0:03b5121a232e 27162 VERROR_INT("xmlSchemaVReaderWalk",
pcercuei 0:03b5121a232e 27163 "calling xmlSchemaValidatorPopElem()");
pcercuei 0:03b5121a232e 27164 goto internal_error;
pcercuei 0:03b5121a232e 27165 }
pcercuei 0:03b5121a232e 27166 goto exit;
pcercuei 0:03b5121a232e 27167 }
pcercuei 0:03b5121a232e 27168 if (vctxt->depth >= 0)
pcercuei 0:03b5121a232e 27169 ielem = vctxt->inode;
pcercuei 0:03b5121a232e 27170 else
pcercuei 0:03b5121a232e 27171 ielem = NULL;
pcercuei 0:03b5121a232e 27172 } else if ((nodeType == XML_TEXT_NODE) ||
pcercuei 0:03b5121a232e 27173 (nodeType == XML_CDATA_SECTION_NODE) ||
pcercuei 0:03b5121a232e 27174 (nodeType == WHTSP) ||
pcercuei 0:03b5121a232e 27175 (nodeType == SIGN_WHTSP)) {
pcercuei 0:03b5121a232e 27176 /*
pcercuei 0:03b5121a232e 27177 * Process character content.
pcercuei 0:03b5121a232e 27178 */
pcercuei 0:03b5121a232e 27179 xmlChar *value;
pcercuei 0:03b5121a232e 27180
pcercuei 0:03b5121a232e 27181 if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
pcercuei 0:03b5121a232e 27182 nodeType = XML_TEXT_NODE;
pcercuei 0:03b5121a232e 27183
pcercuei 0:03b5121a232e 27184 value = xmlTextReaderValue(vctxt->reader);
pcercuei 0:03b5121a232e 27185 ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
pcercuei 0:03b5121a232e 27186 -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
pcercuei 0:03b5121a232e 27187 if (! consumed)
pcercuei 0:03b5121a232e 27188 xmlFree(value);
pcercuei 0:03b5121a232e 27189 if (ret == -1) {
pcercuei 0:03b5121a232e 27190 VERROR_INT("xmlSchemaVReaderWalk",
pcercuei 0:03b5121a232e 27191 "calling xmlSchemaVPushText()");
pcercuei 0:03b5121a232e 27192 goto internal_error;
pcercuei 0:03b5121a232e 27193 }
pcercuei 0:03b5121a232e 27194 } else if ((nodeType == XML_ENTITY_NODE) ||
pcercuei 0:03b5121a232e 27195 (nodeType == XML_ENTITY_REF_NODE)) {
pcercuei 0:03b5121a232e 27196 /*
pcercuei 0:03b5121a232e 27197 * VAL TODO: What to do with entities?
pcercuei 0:03b5121a232e 27198 */
pcercuei 0:03b5121a232e 27199 TODO
pcercuei 0:03b5121a232e 27200 }
pcercuei 0:03b5121a232e 27201 /*
pcercuei 0:03b5121a232e 27202 * Read next node.
pcercuei 0:03b5121a232e 27203 */
pcercuei 0:03b5121a232e 27204 ret = xmlTextReaderRead(vctxt->reader);
pcercuei 0:03b5121a232e 27205 } while (ret == 1);
pcercuei 0:03b5121a232e 27206
pcercuei 0:03b5121a232e 27207 exit:
pcercuei 0:03b5121a232e 27208 return (ret);
pcercuei 0:03b5121a232e 27209 internal_error:
pcercuei 0:03b5121a232e 27210 return (-1);
pcercuei 0:03b5121a232e 27211 }
pcercuei 0:03b5121a232e 27212 #endif
pcercuei 0:03b5121a232e 27213
pcercuei 0:03b5121a232e 27214 /************************************************************************
pcercuei 0:03b5121a232e 27215 * *
pcercuei 0:03b5121a232e 27216 * SAX validation handlers *
pcercuei 0:03b5121a232e 27217 * *
pcercuei 0:03b5121a232e 27218 ************************************************************************/
pcercuei 0:03b5121a232e 27219
pcercuei 0:03b5121a232e 27220 /*
pcercuei 0:03b5121a232e 27221 * Process text content.
pcercuei 0:03b5121a232e 27222 */
pcercuei 0:03b5121a232e 27223 static void
pcercuei 0:03b5121a232e 27224 xmlSchemaSAXHandleText(void *ctx,
pcercuei 0:03b5121a232e 27225 const xmlChar * ch,
pcercuei 0:03b5121a232e 27226 int len)
pcercuei 0:03b5121a232e 27227 {
pcercuei 0:03b5121a232e 27228 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
pcercuei 0:03b5121a232e 27229
pcercuei 0:03b5121a232e 27230 if (vctxt->depth < 0)
pcercuei 0:03b5121a232e 27231 return;
pcercuei 0:03b5121a232e 27232 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
pcercuei 0:03b5121a232e 27233 return;
pcercuei 0:03b5121a232e 27234 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
pcercuei 0:03b5121a232e 27235 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
pcercuei 0:03b5121a232e 27236 if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
pcercuei 0:03b5121a232e 27237 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
pcercuei 0:03b5121a232e 27238 VERROR_INT("xmlSchemaSAXHandleCDataSection",
pcercuei 0:03b5121a232e 27239 "calling xmlSchemaVPushText()");
pcercuei 0:03b5121a232e 27240 vctxt->err = -1;
pcercuei 0:03b5121a232e 27241 xmlStopParser(vctxt->parserCtxt);
pcercuei 0:03b5121a232e 27242 }
pcercuei 0:03b5121a232e 27243 }
pcercuei 0:03b5121a232e 27244
pcercuei 0:03b5121a232e 27245 /*
pcercuei 0:03b5121a232e 27246 * Process CDATA content.
pcercuei 0:03b5121a232e 27247 */
pcercuei 0:03b5121a232e 27248 static void
pcercuei 0:03b5121a232e 27249 xmlSchemaSAXHandleCDataSection(void *ctx,
pcercuei 0:03b5121a232e 27250 const xmlChar * ch,
pcercuei 0:03b5121a232e 27251 int len)
pcercuei 0:03b5121a232e 27252 {
pcercuei 0:03b5121a232e 27253 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
pcercuei 0:03b5121a232e 27254
pcercuei 0:03b5121a232e 27255 if (vctxt->depth < 0)
pcercuei 0:03b5121a232e 27256 return;
pcercuei 0:03b5121a232e 27257 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
pcercuei 0:03b5121a232e 27258 return;
pcercuei 0:03b5121a232e 27259 if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
pcercuei 0:03b5121a232e 27260 vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
pcercuei 0:03b5121a232e 27261 if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
pcercuei 0:03b5121a232e 27262 XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
pcercuei 0:03b5121a232e 27263 VERROR_INT("xmlSchemaSAXHandleCDataSection",
pcercuei 0:03b5121a232e 27264 "calling xmlSchemaVPushText()");
pcercuei 0:03b5121a232e 27265 vctxt->err = -1;
pcercuei 0:03b5121a232e 27266 xmlStopParser(vctxt->parserCtxt);
pcercuei 0:03b5121a232e 27267 }
pcercuei 0:03b5121a232e 27268 }
pcercuei 0:03b5121a232e 27269
pcercuei 0:03b5121a232e 27270 static void
pcercuei 0:03b5121a232e 27271 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 27272 const xmlChar * name ATTRIBUTE_UNUSED)
pcercuei 0:03b5121a232e 27273 {
pcercuei 0:03b5121a232e 27274 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
pcercuei 0:03b5121a232e 27275
pcercuei 0:03b5121a232e 27276 if (vctxt->depth < 0)
pcercuei 0:03b5121a232e 27277 return;
pcercuei 0:03b5121a232e 27278 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
pcercuei 0:03b5121a232e 27279 return;
pcercuei 0:03b5121a232e 27280 /* SAX VAL TODO: What to do here? */
pcercuei 0:03b5121a232e 27281 TODO
pcercuei 0:03b5121a232e 27282 }
pcercuei 0:03b5121a232e 27283
pcercuei 0:03b5121a232e 27284 static void
pcercuei 0:03b5121a232e 27285 xmlSchemaSAXHandleStartElementNs(void *ctx,
pcercuei 0:03b5121a232e 27286 const xmlChar * localname,
pcercuei 0:03b5121a232e 27287 const xmlChar * prefix ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 27288 const xmlChar * URI,
pcercuei 0:03b5121a232e 27289 int nb_namespaces,
pcercuei 0:03b5121a232e 27290 const xmlChar ** namespaces,
pcercuei 0:03b5121a232e 27291 int nb_attributes,
pcercuei 0:03b5121a232e 27292 int nb_defaulted ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 27293 const xmlChar ** attributes)
pcercuei 0:03b5121a232e 27294 {
pcercuei 0:03b5121a232e 27295 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
pcercuei 0:03b5121a232e 27296 int ret;
pcercuei 0:03b5121a232e 27297 xmlSchemaNodeInfoPtr ielem;
pcercuei 0:03b5121a232e 27298 int i, j;
pcercuei 0:03b5121a232e 27299
pcercuei 0:03b5121a232e 27300 /*
pcercuei 0:03b5121a232e 27301 * SAX VAL TODO: What to do with nb_defaulted?
pcercuei 0:03b5121a232e 27302 */
pcercuei 0:03b5121a232e 27303 /*
pcercuei 0:03b5121a232e 27304 * Skip elements if inside a "skip" wildcard or invalid.
pcercuei 0:03b5121a232e 27305 */
pcercuei 0:03b5121a232e 27306 vctxt->depth++;
pcercuei 0:03b5121a232e 27307 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
pcercuei 0:03b5121a232e 27308 return;
pcercuei 0:03b5121a232e 27309 /*
pcercuei 0:03b5121a232e 27310 * Push the element.
pcercuei 0:03b5121a232e 27311 */
pcercuei 0:03b5121a232e 27312 if (xmlSchemaValidatorPushElem(vctxt) == -1) {
pcercuei 0:03b5121a232e 27313 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
pcercuei 0:03b5121a232e 27314 "calling xmlSchemaValidatorPushElem()");
pcercuei 0:03b5121a232e 27315 goto internal_error;
pcercuei 0:03b5121a232e 27316 }
pcercuei 0:03b5121a232e 27317 ielem = vctxt->inode;
pcercuei 0:03b5121a232e 27318 /*
pcercuei 0:03b5121a232e 27319 * TODO: Is this OK?
pcercuei 0:03b5121a232e 27320 */
pcercuei 0:03b5121a232e 27321 ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
pcercuei 0:03b5121a232e 27322 ielem->localName = localname;
pcercuei 0:03b5121a232e 27323 ielem->nsName = URI;
pcercuei 0:03b5121a232e 27324 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
pcercuei 0:03b5121a232e 27325 /*
pcercuei 0:03b5121a232e 27326 * Register namespaces on the elem info.
pcercuei 0:03b5121a232e 27327 */
pcercuei 0:03b5121a232e 27328 if (nb_namespaces != 0) {
pcercuei 0:03b5121a232e 27329 /*
pcercuei 0:03b5121a232e 27330 * Although the parser builds its own namespace list,
pcercuei 0:03b5121a232e 27331 * we have no access to it, so we'll use an own one.
pcercuei 0:03b5121a232e 27332 */
pcercuei 0:03b5121a232e 27333 for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
pcercuei 0:03b5121a232e 27334 /*
pcercuei 0:03b5121a232e 27335 * Store prefix and namespace name.
pcercuei 0:03b5121a232e 27336 */
pcercuei 0:03b5121a232e 27337 if (ielem->nsBindings == NULL) {
pcercuei 0:03b5121a232e 27338 ielem->nsBindings =
pcercuei 0:03b5121a232e 27339 (const xmlChar **) xmlMalloc(10 *
pcercuei 0:03b5121a232e 27340 sizeof(const xmlChar *));
pcercuei 0:03b5121a232e 27341 if (ielem->nsBindings == NULL) {
pcercuei 0:03b5121a232e 27342 xmlSchemaVErrMemory(vctxt,
pcercuei 0:03b5121a232e 27343 "allocating namespace bindings for SAX validation",
pcercuei 0:03b5121a232e 27344 NULL);
pcercuei 0:03b5121a232e 27345 goto internal_error;
pcercuei 0:03b5121a232e 27346 }
pcercuei 0:03b5121a232e 27347 ielem->nbNsBindings = 0;
pcercuei 0:03b5121a232e 27348 ielem->sizeNsBindings = 5;
pcercuei 0:03b5121a232e 27349 } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
pcercuei 0:03b5121a232e 27350 ielem->sizeNsBindings *= 2;
pcercuei 0:03b5121a232e 27351 ielem->nsBindings =
pcercuei 0:03b5121a232e 27352 (const xmlChar **) xmlRealloc(
pcercuei 0:03b5121a232e 27353 (void *) ielem->nsBindings,
pcercuei 0:03b5121a232e 27354 ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
pcercuei 0:03b5121a232e 27355 if (ielem->nsBindings == NULL) {
pcercuei 0:03b5121a232e 27356 xmlSchemaVErrMemory(vctxt,
pcercuei 0:03b5121a232e 27357 "re-allocating namespace bindings for SAX validation",
pcercuei 0:03b5121a232e 27358 NULL);
pcercuei 0:03b5121a232e 27359 goto internal_error;
pcercuei 0:03b5121a232e 27360 }
pcercuei 0:03b5121a232e 27361 }
pcercuei 0:03b5121a232e 27362
pcercuei 0:03b5121a232e 27363 ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
pcercuei 0:03b5121a232e 27364 if (namespaces[j+1][0] == 0) {
pcercuei 0:03b5121a232e 27365 /*
pcercuei 0:03b5121a232e 27366 * Handle xmlns="".
pcercuei 0:03b5121a232e 27367 */
pcercuei 0:03b5121a232e 27368 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
pcercuei 0:03b5121a232e 27369 } else
pcercuei 0:03b5121a232e 27370 ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
pcercuei 0:03b5121a232e 27371 namespaces[j+1];
pcercuei 0:03b5121a232e 27372 ielem->nbNsBindings++;
pcercuei 0:03b5121a232e 27373 }
pcercuei 0:03b5121a232e 27374 }
pcercuei 0:03b5121a232e 27375 /*
pcercuei 0:03b5121a232e 27376 * Register attributes.
pcercuei 0:03b5121a232e 27377 * SAX VAL TODO: We are not adding namespace declaration
pcercuei 0:03b5121a232e 27378 * attributes yet.
pcercuei 0:03b5121a232e 27379 */
pcercuei 0:03b5121a232e 27380 if (nb_attributes != 0) {
pcercuei 0:03b5121a232e 27381 xmlChar *value;
pcercuei 0:03b5121a232e 27382
pcercuei 0:03b5121a232e 27383 for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
pcercuei 0:03b5121a232e 27384 /*
pcercuei 0:03b5121a232e 27385 * Duplicate the value.
pcercuei 0:03b5121a232e 27386 */
pcercuei 0:03b5121a232e 27387 value = xmlStrndup(attributes[j+3],
pcercuei 0:03b5121a232e 27388 attributes[j+4] - attributes[j+3]);
pcercuei 0:03b5121a232e 27389 /*
pcercuei 0:03b5121a232e 27390 * TODO: Set the node line.
pcercuei 0:03b5121a232e 27391 */
pcercuei 0:03b5121a232e 27392 ret = xmlSchemaValidatorPushAttribute(vctxt,
pcercuei 0:03b5121a232e 27393 NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
pcercuei 0:03b5121a232e 27394 value, 1);
pcercuei 0:03b5121a232e 27395 if (ret == -1) {
pcercuei 0:03b5121a232e 27396 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
pcercuei 0:03b5121a232e 27397 "calling xmlSchemaValidatorPushAttribute()");
pcercuei 0:03b5121a232e 27398 goto internal_error;
pcercuei 0:03b5121a232e 27399 }
pcercuei 0:03b5121a232e 27400 }
pcercuei 0:03b5121a232e 27401 }
pcercuei 0:03b5121a232e 27402 /*
pcercuei 0:03b5121a232e 27403 * Validate the element.
pcercuei 0:03b5121a232e 27404 */
pcercuei 0:03b5121a232e 27405 ret = xmlSchemaValidateElem(vctxt);
pcercuei 0:03b5121a232e 27406 if (ret != 0) {
pcercuei 0:03b5121a232e 27407 if (ret == -1) {
pcercuei 0:03b5121a232e 27408 VERROR_INT("xmlSchemaSAXHandleStartElementNs",
pcercuei 0:03b5121a232e 27409 "calling xmlSchemaValidateElem()");
pcercuei 0:03b5121a232e 27410 goto internal_error;
pcercuei 0:03b5121a232e 27411 }
pcercuei 0:03b5121a232e 27412 goto exit;
pcercuei 0:03b5121a232e 27413 }
pcercuei 0:03b5121a232e 27414
pcercuei 0:03b5121a232e 27415 exit:
pcercuei 0:03b5121a232e 27416 return;
pcercuei 0:03b5121a232e 27417 internal_error:
pcercuei 0:03b5121a232e 27418 vctxt->err = -1;
pcercuei 0:03b5121a232e 27419 xmlStopParser(vctxt->parserCtxt);
pcercuei 0:03b5121a232e 27420 return;
pcercuei 0:03b5121a232e 27421 }
pcercuei 0:03b5121a232e 27422
pcercuei 0:03b5121a232e 27423 static void
pcercuei 0:03b5121a232e 27424 xmlSchemaSAXHandleEndElementNs(void *ctx,
pcercuei 0:03b5121a232e 27425 const xmlChar * localname ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 27426 const xmlChar * prefix ATTRIBUTE_UNUSED,
pcercuei 0:03b5121a232e 27427 const xmlChar * URI ATTRIBUTE_UNUSED)
pcercuei 0:03b5121a232e 27428 {
pcercuei 0:03b5121a232e 27429 xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
pcercuei 0:03b5121a232e 27430 int res;
pcercuei 0:03b5121a232e 27431
pcercuei 0:03b5121a232e 27432 /*
pcercuei 0:03b5121a232e 27433 * Skip elements if inside a "skip" wildcard or if invalid.
pcercuei 0:03b5121a232e 27434 */
pcercuei 0:03b5121a232e 27435 if (vctxt->skipDepth != -1) {
pcercuei 0:03b5121a232e 27436 if (vctxt->depth > vctxt->skipDepth) {
pcercuei 0:03b5121a232e 27437 vctxt->depth--;
pcercuei 0:03b5121a232e 27438 return;
pcercuei 0:03b5121a232e 27439 } else
pcercuei 0:03b5121a232e 27440 vctxt->skipDepth = -1;
pcercuei 0:03b5121a232e 27441 }
pcercuei 0:03b5121a232e 27442 /*
pcercuei 0:03b5121a232e 27443 * SAX VAL TODO: Just a temporary check.
pcercuei 0:03b5121a232e 27444 */
pcercuei 0:03b5121a232e 27445 if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
pcercuei 0:03b5121a232e 27446 (!xmlStrEqual(vctxt->inode->nsName, URI))) {
pcercuei 0:03b5121a232e 27447 VERROR_INT("xmlSchemaSAXHandleEndElementNs",
pcercuei 0:03b5121a232e 27448 "elem pop mismatch");
pcercuei 0:03b5121a232e 27449 }
pcercuei 0:03b5121a232e 27450 res = xmlSchemaValidatorPopElem(vctxt);
pcercuei 0:03b5121a232e 27451 if (res != 0) {
pcercuei 0:03b5121a232e 27452 if (res < 0) {
pcercuei 0:03b5121a232e 27453 VERROR_INT("xmlSchemaSAXHandleEndElementNs",
pcercuei 0:03b5121a232e 27454 "calling xmlSchemaValidatorPopElem()");
pcercuei 0:03b5121a232e 27455 goto internal_error;
pcercuei 0:03b5121a232e 27456 }
pcercuei 0:03b5121a232e 27457 goto exit;
pcercuei 0:03b5121a232e 27458 }
pcercuei 0:03b5121a232e 27459 exit:
pcercuei 0:03b5121a232e 27460 return;
pcercuei 0:03b5121a232e 27461 internal_error:
pcercuei 0:03b5121a232e 27462 vctxt->err = -1;
pcercuei 0:03b5121a232e 27463 xmlStopParser(vctxt->parserCtxt);
pcercuei 0:03b5121a232e 27464 return;
pcercuei 0:03b5121a232e 27465 }
pcercuei 0:03b5121a232e 27466
pcercuei 0:03b5121a232e 27467 /************************************************************************
pcercuei 0:03b5121a232e 27468 * *
pcercuei 0:03b5121a232e 27469 * Validation interfaces *
pcercuei 0:03b5121a232e 27470 * *
pcercuei 0:03b5121a232e 27471 ************************************************************************/
pcercuei 0:03b5121a232e 27472
pcercuei 0:03b5121a232e 27473 /**
pcercuei 0:03b5121a232e 27474 * xmlSchemaNewValidCtxt:
pcercuei 0:03b5121a232e 27475 * @schema: a precompiled XML Schemas
pcercuei 0:03b5121a232e 27476 *
pcercuei 0:03b5121a232e 27477 * Create an XML Schemas validation context based on the given schema.
pcercuei 0:03b5121a232e 27478 *
pcercuei 0:03b5121a232e 27479 * Returns the validation context or NULL in case of error
pcercuei 0:03b5121a232e 27480 */
pcercuei 0:03b5121a232e 27481 xmlSchemaValidCtxtPtr
pcercuei 0:03b5121a232e 27482 xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
pcercuei 0:03b5121a232e 27483 {
pcercuei 0:03b5121a232e 27484 xmlSchemaValidCtxtPtr ret;
pcercuei 0:03b5121a232e 27485
pcercuei 0:03b5121a232e 27486 ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
pcercuei 0:03b5121a232e 27487 if (ret == NULL) {
pcercuei 0:03b5121a232e 27488 xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
pcercuei 0:03b5121a232e 27489 return (NULL);
pcercuei 0:03b5121a232e 27490 }
pcercuei 0:03b5121a232e 27491 memset(ret, 0, sizeof(xmlSchemaValidCtxt));
pcercuei 0:03b5121a232e 27492 ret->type = XML_SCHEMA_CTXT_VALIDATOR;
pcercuei 0:03b5121a232e 27493 ret->dict = xmlDictCreate();
pcercuei 0:03b5121a232e 27494 ret->nodeQNames = xmlSchemaItemListCreate();
pcercuei 0:03b5121a232e 27495 ret->schema = schema;
pcercuei 0:03b5121a232e 27496 return (ret);
pcercuei 0:03b5121a232e 27497 }
pcercuei 0:03b5121a232e 27498
pcercuei 0:03b5121a232e 27499 /**
pcercuei 0:03b5121a232e 27500 * xmlSchemaValidateSetFilename:
pcercuei 0:03b5121a232e 27501 * @vctxt: the schema validation context
pcercuei 0:03b5121a232e 27502 * @filename: the file name
pcercuei 0:03b5121a232e 27503 *
pcercuei 0:03b5121a232e 27504 * Workaround to provide file error reporting information when this is
pcercuei 0:03b5121a232e 27505 * not provided by current APIs
pcercuei 0:03b5121a232e 27506 */
pcercuei 0:03b5121a232e 27507 void
pcercuei 0:03b5121a232e 27508 xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
pcercuei 0:03b5121a232e 27509 if (vctxt == NULL)
pcercuei 0:03b5121a232e 27510 return;
pcercuei 0:03b5121a232e 27511 if (vctxt->filename != NULL)
pcercuei 0:03b5121a232e 27512 xmlFree(vctxt->filename);
pcercuei 0:03b5121a232e 27513 if (filename != NULL)
pcercuei 0:03b5121a232e 27514 vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
pcercuei 0:03b5121a232e 27515 else
pcercuei 0:03b5121a232e 27516 vctxt->filename = NULL;
pcercuei 0:03b5121a232e 27517 }
pcercuei 0:03b5121a232e 27518
pcercuei 0:03b5121a232e 27519 /**
pcercuei 0:03b5121a232e 27520 * xmlSchemaClearValidCtxt:
pcercuei 0:03b5121a232e 27521 * @vctxt: the schema validation context
pcercuei 0:03b5121a232e 27522 *
pcercuei 0:03b5121a232e 27523 * Free the resources associated to the schema validation context;
pcercuei 0:03b5121a232e 27524 * leaves some fields alive intended for reuse of the context.
pcercuei 0:03b5121a232e 27525 */
pcercuei 0:03b5121a232e 27526 static void
pcercuei 0:03b5121a232e 27527 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 27528 {
pcercuei 0:03b5121a232e 27529 if (vctxt == NULL)
pcercuei 0:03b5121a232e 27530 return;
pcercuei 0:03b5121a232e 27531
pcercuei 0:03b5121a232e 27532 /*
pcercuei 0:03b5121a232e 27533 * TODO: Should we clear the flags?
pcercuei 0:03b5121a232e 27534 * Might be problematic if one reuses the context
pcercuei 0:03b5121a232e 27535 * and assumes that the options remain the same.
pcercuei 0:03b5121a232e 27536 */
pcercuei 0:03b5121a232e 27537 vctxt->flags = 0;
pcercuei 0:03b5121a232e 27538 vctxt->validationRoot = NULL;
pcercuei 0:03b5121a232e 27539 vctxt->doc = NULL;
pcercuei 0:03b5121a232e 27540 #ifdef LIBXML_READER_ENABLED
pcercuei 0:03b5121a232e 27541 vctxt->reader = NULL;
pcercuei 0:03b5121a232e 27542 #endif
pcercuei 0:03b5121a232e 27543 vctxt->hasKeyrefs = 0;
pcercuei 0:03b5121a232e 27544
pcercuei 0:03b5121a232e 27545 if (vctxt->value != NULL) {
pcercuei 0:03b5121a232e 27546 xmlSchemaFreeValue(vctxt->value);
pcercuei 0:03b5121a232e 27547 vctxt->value = NULL;
pcercuei 0:03b5121a232e 27548 }
pcercuei 0:03b5121a232e 27549 /*
pcercuei 0:03b5121a232e 27550 * Augmented IDC information.
pcercuei 0:03b5121a232e 27551 */
pcercuei 0:03b5121a232e 27552 if (vctxt->aidcs != NULL) {
pcercuei 0:03b5121a232e 27553 xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
pcercuei 0:03b5121a232e 27554 do {
pcercuei 0:03b5121a232e 27555 next = cur->next;
pcercuei 0:03b5121a232e 27556 xmlFree(cur);
pcercuei 0:03b5121a232e 27557 cur = next;
pcercuei 0:03b5121a232e 27558 } while (cur != NULL);
pcercuei 0:03b5121a232e 27559 vctxt->aidcs = NULL;
pcercuei 0:03b5121a232e 27560 }
pcercuei 0:03b5121a232e 27561 if (vctxt->idcMatcherCache != NULL) {
pcercuei 0:03b5121a232e 27562 xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
pcercuei 0:03b5121a232e 27563
pcercuei 0:03b5121a232e 27564 while (matcher) {
pcercuei 0:03b5121a232e 27565 tmp = matcher;
pcercuei 0:03b5121a232e 27566 matcher = matcher->nextCached;
pcercuei 0:03b5121a232e 27567 xmlSchemaIDCFreeMatcherList(tmp);
pcercuei 0:03b5121a232e 27568 }
pcercuei 0:03b5121a232e 27569 vctxt->idcMatcherCache = NULL;
pcercuei 0:03b5121a232e 27570 }
pcercuei 0:03b5121a232e 27571
pcercuei 0:03b5121a232e 27572
pcercuei 0:03b5121a232e 27573 if (vctxt->idcNodes != NULL) {
pcercuei 0:03b5121a232e 27574 int i;
pcercuei 0:03b5121a232e 27575 xmlSchemaPSVIIDCNodePtr item;
pcercuei 0:03b5121a232e 27576
pcercuei 0:03b5121a232e 27577 for (i = 0; i < vctxt->nbIdcNodes; i++) {
pcercuei 0:03b5121a232e 27578 item = vctxt->idcNodes[i];
pcercuei 0:03b5121a232e 27579 xmlFree(item->keys);
pcercuei 0:03b5121a232e 27580 xmlFree(item);
pcercuei 0:03b5121a232e 27581 }
pcercuei 0:03b5121a232e 27582 xmlFree(vctxt->idcNodes);
pcercuei 0:03b5121a232e 27583 vctxt->idcNodes = NULL;
pcercuei 0:03b5121a232e 27584 vctxt->nbIdcNodes = 0;
pcercuei 0:03b5121a232e 27585 vctxt->sizeIdcNodes = 0;
pcercuei 0:03b5121a232e 27586 }
pcercuei 0:03b5121a232e 27587 /*
pcercuei 0:03b5121a232e 27588 * Note that we won't delete the XPath state pool here.
pcercuei 0:03b5121a232e 27589 */
pcercuei 0:03b5121a232e 27590 if (vctxt->xpathStates != NULL) {
pcercuei 0:03b5121a232e 27591 xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
pcercuei 0:03b5121a232e 27592 vctxt->xpathStates = NULL;
pcercuei 0:03b5121a232e 27593 }
pcercuei 0:03b5121a232e 27594 /*
pcercuei 0:03b5121a232e 27595 * Attribute info.
pcercuei 0:03b5121a232e 27596 */
pcercuei 0:03b5121a232e 27597 if (vctxt->nbAttrInfos != 0) {
pcercuei 0:03b5121a232e 27598 xmlSchemaClearAttrInfos(vctxt);
pcercuei 0:03b5121a232e 27599 }
pcercuei 0:03b5121a232e 27600 /*
pcercuei 0:03b5121a232e 27601 * Element info.
pcercuei 0:03b5121a232e 27602 */
pcercuei 0:03b5121a232e 27603 if (vctxt->elemInfos != NULL) {
pcercuei 0:03b5121a232e 27604 int i;
pcercuei 0:03b5121a232e 27605 xmlSchemaNodeInfoPtr ei;
pcercuei 0:03b5121a232e 27606
pcercuei 0:03b5121a232e 27607 for (i = 0; i < vctxt->sizeElemInfos; i++) {
pcercuei 0:03b5121a232e 27608 ei = vctxt->elemInfos[i];
pcercuei 0:03b5121a232e 27609 if (ei == NULL)
pcercuei 0:03b5121a232e 27610 break;
pcercuei 0:03b5121a232e 27611 xmlSchemaClearElemInfo(vctxt, ei);
pcercuei 0:03b5121a232e 27612 }
pcercuei 0:03b5121a232e 27613 }
pcercuei 0:03b5121a232e 27614 xmlSchemaItemListClear(vctxt->nodeQNames);
pcercuei 0:03b5121a232e 27615 /* Recreate the dict. */
pcercuei 0:03b5121a232e 27616 xmlDictFree(vctxt->dict);
pcercuei 0:03b5121a232e 27617 /*
pcercuei 0:03b5121a232e 27618 * TODO: Is is save to recreate it? Do we have a scenario
pcercuei 0:03b5121a232e 27619 * where the user provides the dict?
pcercuei 0:03b5121a232e 27620 */
pcercuei 0:03b5121a232e 27621 vctxt->dict = xmlDictCreate();
pcercuei 0:03b5121a232e 27622
pcercuei 0:03b5121a232e 27623 if (vctxt->filename != NULL) {
pcercuei 0:03b5121a232e 27624 xmlFree(vctxt->filename);
pcercuei 0:03b5121a232e 27625 vctxt->filename = NULL;
pcercuei 0:03b5121a232e 27626 }
pcercuei 0:03b5121a232e 27627 }
pcercuei 0:03b5121a232e 27628
pcercuei 0:03b5121a232e 27629 /**
pcercuei 0:03b5121a232e 27630 * xmlSchemaFreeValidCtxt:
pcercuei 0:03b5121a232e 27631 * @ctxt: the schema validation context
pcercuei 0:03b5121a232e 27632 *
pcercuei 0:03b5121a232e 27633 * Free the resources associated to the schema validation context
pcercuei 0:03b5121a232e 27634 */
pcercuei 0:03b5121a232e 27635 void
pcercuei 0:03b5121a232e 27636 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
pcercuei 0:03b5121a232e 27637 {
pcercuei 0:03b5121a232e 27638 if (ctxt == NULL)
pcercuei 0:03b5121a232e 27639 return;
pcercuei 0:03b5121a232e 27640 if (ctxt->value != NULL)
pcercuei 0:03b5121a232e 27641 xmlSchemaFreeValue(ctxt->value);
pcercuei 0:03b5121a232e 27642 if (ctxt->pctxt != NULL)
pcercuei 0:03b5121a232e 27643 xmlSchemaFreeParserCtxt(ctxt->pctxt);
pcercuei 0:03b5121a232e 27644 if (ctxt->idcNodes != NULL) {
pcercuei 0:03b5121a232e 27645 int i;
pcercuei 0:03b5121a232e 27646 xmlSchemaPSVIIDCNodePtr item;
pcercuei 0:03b5121a232e 27647
pcercuei 0:03b5121a232e 27648 for (i = 0; i < ctxt->nbIdcNodes; i++) {
pcercuei 0:03b5121a232e 27649 item = ctxt->idcNodes[i];
pcercuei 0:03b5121a232e 27650 xmlFree(item->keys);
pcercuei 0:03b5121a232e 27651 xmlFree(item);
pcercuei 0:03b5121a232e 27652 }
pcercuei 0:03b5121a232e 27653 xmlFree(ctxt->idcNodes);
pcercuei 0:03b5121a232e 27654 }
pcercuei 0:03b5121a232e 27655 if (ctxt->idcKeys != NULL) {
pcercuei 0:03b5121a232e 27656 int i;
pcercuei 0:03b5121a232e 27657 for (i = 0; i < ctxt->nbIdcKeys; i++)
pcercuei 0:03b5121a232e 27658 xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
pcercuei 0:03b5121a232e 27659 xmlFree(ctxt->idcKeys);
pcercuei 0:03b5121a232e 27660 }
pcercuei 0:03b5121a232e 27661
pcercuei 0:03b5121a232e 27662 if (ctxt->xpathStates != NULL) {
pcercuei 0:03b5121a232e 27663 xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
pcercuei 0:03b5121a232e 27664 ctxt->xpathStates = NULL;
pcercuei 0:03b5121a232e 27665 }
pcercuei 0:03b5121a232e 27666 if (ctxt->xpathStatePool != NULL) {
pcercuei 0:03b5121a232e 27667 xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
pcercuei 0:03b5121a232e 27668 ctxt->xpathStatePool = NULL;
pcercuei 0:03b5121a232e 27669 }
pcercuei 0:03b5121a232e 27670
pcercuei 0:03b5121a232e 27671 /*
pcercuei 0:03b5121a232e 27672 * Augmented IDC information.
pcercuei 0:03b5121a232e 27673 */
pcercuei 0:03b5121a232e 27674 if (ctxt->aidcs != NULL) {
pcercuei 0:03b5121a232e 27675 xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
pcercuei 0:03b5121a232e 27676 do {
pcercuei 0:03b5121a232e 27677 next = cur->next;
pcercuei 0:03b5121a232e 27678 xmlFree(cur);
pcercuei 0:03b5121a232e 27679 cur = next;
pcercuei 0:03b5121a232e 27680 } while (cur != NULL);
pcercuei 0:03b5121a232e 27681 }
pcercuei 0:03b5121a232e 27682 if (ctxt->attrInfos != NULL) {
pcercuei 0:03b5121a232e 27683 int i;
pcercuei 0:03b5121a232e 27684 xmlSchemaAttrInfoPtr attr;
pcercuei 0:03b5121a232e 27685
pcercuei 0:03b5121a232e 27686 /* Just a paranoid call to the cleanup. */
pcercuei 0:03b5121a232e 27687 if (ctxt->nbAttrInfos != 0)
pcercuei 0:03b5121a232e 27688 xmlSchemaClearAttrInfos(ctxt);
pcercuei 0:03b5121a232e 27689 for (i = 0; i < ctxt->sizeAttrInfos; i++) {
pcercuei 0:03b5121a232e 27690 attr = ctxt->attrInfos[i];
pcercuei 0:03b5121a232e 27691 xmlFree(attr);
pcercuei 0:03b5121a232e 27692 }
pcercuei 0:03b5121a232e 27693 xmlFree(ctxt->attrInfos);
pcercuei 0:03b5121a232e 27694 }
pcercuei 0:03b5121a232e 27695 if (ctxt->elemInfos != NULL) {
pcercuei 0:03b5121a232e 27696 int i;
pcercuei 0:03b5121a232e 27697 xmlSchemaNodeInfoPtr ei;
pcercuei 0:03b5121a232e 27698
pcercuei 0:03b5121a232e 27699 for (i = 0; i < ctxt->sizeElemInfos; i++) {
pcercuei 0:03b5121a232e 27700 ei = ctxt->elemInfos[i];
pcercuei 0:03b5121a232e 27701 if (ei == NULL)
pcercuei 0:03b5121a232e 27702 break;
pcercuei 0:03b5121a232e 27703 xmlSchemaClearElemInfo(ctxt, ei);
pcercuei 0:03b5121a232e 27704 xmlFree(ei);
pcercuei 0:03b5121a232e 27705 }
pcercuei 0:03b5121a232e 27706 xmlFree(ctxt->elemInfos);
pcercuei 0:03b5121a232e 27707 }
pcercuei 0:03b5121a232e 27708 if (ctxt->nodeQNames != NULL)
pcercuei 0:03b5121a232e 27709 xmlSchemaItemListFree(ctxt->nodeQNames);
pcercuei 0:03b5121a232e 27710 if (ctxt->dict != NULL)
pcercuei 0:03b5121a232e 27711 xmlDictFree(ctxt->dict);
pcercuei 0:03b5121a232e 27712 if (ctxt->filename != NULL)
pcercuei 0:03b5121a232e 27713 xmlFree(ctxt->filename);
pcercuei 0:03b5121a232e 27714 xmlFree(ctxt);
pcercuei 0:03b5121a232e 27715 }
pcercuei 0:03b5121a232e 27716
pcercuei 0:03b5121a232e 27717 /**
pcercuei 0:03b5121a232e 27718 * xmlSchemaIsValid:
pcercuei 0:03b5121a232e 27719 * @ctxt: the schema validation context
pcercuei 0:03b5121a232e 27720 *
pcercuei 0:03b5121a232e 27721 * Check if any error was detected during validation.
pcercuei 0:03b5121a232e 27722 *
pcercuei 0:03b5121a232e 27723 * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
pcercuei 0:03b5121a232e 27724 * of internal error.
pcercuei 0:03b5121a232e 27725 */
pcercuei 0:03b5121a232e 27726 int
pcercuei 0:03b5121a232e 27727 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
pcercuei 0:03b5121a232e 27728 {
pcercuei 0:03b5121a232e 27729 if (ctxt == NULL)
pcercuei 0:03b5121a232e 27730 return(-1);
pcercuei 0:03b5121a232e 27731 return(ctxt->err == 0);
pcercuei 0:03b5121a232e 27732 }
pcercuei 0:03b5121a232e 27733
pcercuei 0:03b5121a232e 27734 /**
pcercuei 0:03b5121a232e 27735 * xmlSchemaSetValidErrors:
pcercuei 0:03b5121a232e 27736 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 27737 * @err: the error function
pcercuei 0:03b5121a232e 27738 * @warn: the warning function
pcercuei 0:03b5121a232e 27739 * @ctx: the functions context
pcercuei 0:03b5121a232e 27740 *
pcercuei 0:03b5121a232e 27741 * Set the error and warning callback informations
pcercuei 0:03b5121a232e 27742 */
pcercuei 0:03b5121a232e 27743 void
pcercuei 0:03b5121a232e 27744 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
pcercuei 0:03b5121a232e 27745 xmlSchemaValidityErrorFunc err,
pcercuei 0:03b5121a232e 27746 xmlSchemaValidityWarningFunc warn, void *ctx)
pcercuei 0:03b5121a232e 27747 {
pcercuei 0:03b5121a232e 27748 if (ctxt == NULL)
pcercuei 0:03b5121a232e 27749 return;
pcercuei 0:03b5121a232e 27750 ctxt->error = err;
pcercuei 0:03b5121a232e 27751 ctxt->warning = warn;
pcercuei 0:03b5121a232e 27752 ctxt->errCtxt = ctx;
pcercuei 0:03b5121a232e 27753 if (ctxt->pctxt != NULL)
pcercuei 0:03b5121a232e 27754 xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
pcercuei 0:03b5121a232e 27755 }
pcercuei 0:03b5121a232e 27756
pcercuei 0:03b5121a232e 27757 /**
pcercuei 0:03b5121a232e 27758 * xmlSchemaSetValidStructuredErrors:
pcercuei 0:03b5121a232e 27759 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 27760 * @serror: the structured error function
pcercuei 0:03b5121a232e 27761 * @ctx: the functions context
pcercuei 0:03b5121a232e 27762 *
pcercuei 0:03b5121a232e 27763 * Set the structured error callback
pcercuei 0:03b5121a232e 27764 */
pcercuei 0:03b5121a232e 27765 void
pcercuei 0:03b5121a232e 27766 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
pcercuei 0:03b5121a232e 27767 xmlStructuredErrorFunc serror, void *ctx)
pcercuei 0:03b5121a232e 27768 {
pcercuei 0:03b5121a232e 27769 if (ctxt == NULL)
pcercuei 0:03b5121a232e 27770 return;
pcercuei 0:03b5121a232e 27771 ctxt->serror = serror;
pcercuei 0:03b5121a232e 27772 ctxt->error = NULL;
pcercuei 0:03b5121a232e 27773 ctxt->warning = NULL;
pcercuei 0:03b5121a232e 27774 ctxt->errCtxt = ctx;
pcercuei 0:03b5121a232e 27775 if (ctxt->pctxt != NULL)
pcercuei 0:03b5121a232e 27776 xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
pcercuei 0:03b5121a232e 27777 }
pcercuei 0:03b5121a232e 27778
pcercuei 0:03b5121a232e 27779 /**
pcercuei 0:03b5121a232e 27780 * xmlSchemaGetValidErrors:
pcercuei 0:03b5121a232e 27781 * @ctxt: a XML-Schema validation context
pcercuei 0:03b5121a232e 27782 * @err: the error function result
pcercuei 0:03b5121a232e 27783 * @warn: the warning function result
pcercuei 0:03b5121a232e 27784 * @ctx: the functions context result
pcercuei 0:03b5121a232e 27785 *
pcercuei 0:03b5121a232e 27786 * Get the error and warning callback informations
pcercuei 0:03b5121a232e 27787 *
pcercuei 0:03b5121a232e 27788 * Returns -1 in case of error and 0 otherwise
pcercuei 0:03b5121a232e 27789 */
pcercuei 0:03b5121a232e 27790 int
pcercuei 0:03b5121a232e 27791 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
pcercuei 0:03b5121a232e 27792 xmlSchemaValidityErrorFunc * err,
pcercuei 0:03b5121a232e 27793 xmlSchemaValidityWarningFunc * warn, void **ctx)
pcercuei 0:03b5121a232e 27794 {
pcercuei 0:03b5121a232e 27795 if (ctxt == NULL)
pcercuei 0:03b5121a232e 27796 return (-1);
pcercuei 0:03b5121a232e 27797 if (err != NULL)
pcercuei 0:03b5121a232e 27798 *err = ctxt->error;
pcercuei 0:03b5121a232e 27799 if (warn != NULL)
pcercuei 0:03b5121a232e 27800 *warn = ctxt->warning;
pcercuei 0:03b5121a232e 27801 if (ctx != NULL)
pcercuei 0:03b5121a232e 27802 *ctx = ctxt->errCtxt;
pcercuei 0:03b5121a232e 27803 return (0);
pcercuei 0:03b5121a232e 27804 }
pcercuei 0:03b5121a232e 27805
pcercuei 0:03b5121a232e 27806
pcercuei 0:03b5121a232e 27807 /**
pcercuei 0:03b5121a232e 27808 * xmlSchemaSetValidOptions:
pcercuei 0:03b5121a232e 27809 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 27810 * @options: a combination of xmlSchemaValidOption
pcercuei 0:03b5121a232e 27811 *
pcercuei 0:03b5121a232e 27812 * Sets the options to be used during the validation.
pcercuei 0:03b5121a232e 27813 *
pcercuei 0:03b5121a232e 27814 * Returns 0 in case of success, -1 in case of an
pcercuei 0:03b5121a232e 27815 * API error.
pcercuei 0:03b5121a232e 27816 */
pcercuei 0:03b5121a232e 27817 int
pcercuei 0:03b5121a232e 27818 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
pcercuei 0:03b5121a232e 27819 int options)
pcercuei 0:03b5121a232e 27820
pcercuei 0:03b5121a232e 27821 {
pcercuei 0:03b5121a232e 27822 int i;
pcercuei 0:03b5121a232e 27823
pcercuei 0:03b5121a232e 27824 if (ctxt == NULL)
pcercuei 0:03b5121a232e 27825 return (-1);
pcercuei 0:03b5121a232e 27826 /*
pcercuei 0:03b5121a232e 27827 * WARNING: Change the start value if adding to the
pcercuei 0:03b5121a232e 27828 * xmlSchemaValidOption.
pcercuei 0:03b5121a232e 27829 * TODO: Is there an other, more easy to maintain,
pcercuei 0:03b5121a232e 27830 * way?
pcercuei 0:03b5121a232e 27831 */
pcercuei 0:03b5121a232e 27832 for (i = 1; i < (int) sizeof(int) * 8; i++) {
pcercuei 0:03b5121a232e 27833 if (options & 1<<i)
pcercuei 0:03b5121a232e 27834 return (-1);
pcercuei 0:03b5121a232e 27835 }
pcercuei 0:03b5121a232e 27836 ctxt->options = options;
pcercuei 0:03b5121a232e 27837 return (0);
pcercuei 0:03b5121a232e 27838 }
pcercuei 0:03b5121a232e 27839
pcercuei 0:03b5121a232e 27840 /**
pcercuei 0:03b5121a232e 27841 * xmlSchemaValidCtxtGetOptions:
pcercuei 0:03b5121a232e 27842 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 27843 *
pcercuei 0:03b5121a232e 27844 * Get the validation context options.
pcercuei 0:03b5121a232e 27845 *
pcercuei 0:03b5121a232e 27846 * Returns the option combination or -1 on error.
pcercuei 0:03b5121a232e 27847 */
pcercuei 0:03b5121a232e 27848 int
pcercuei 0:03b5121a232e 27849 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
pcercuei 0:03b5121a232e 27850
pcercuei 0:03b5121a232e 27851 {
pcercuei 0:03b5121a232e 27852 if (ctxt == NULL)
pcercuei 0:03b5121a232e 27853 return (-1);
pcercuei 0:03b5121a232e 27854 else
pcercuei 0:03b5121a232e 27855 return (ctxt->options);
pcercuei 0:03b5121a232e 27856 }
pcercuei 0:03b5121a232e 27857
pcercuei 0:03b5121a232e 27858 static int
pcercuei 0:03b5121a232e 27859 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 27860 {
pcercuei 0:03b5121a232e 27861 xmlAttrPtr attr;
pcercuei 0:03b5121a232e 27862 int ret = 0;
pcercuei 0:03b5121a232e 27863 xmlSchemaNodeInfoPtr ielem = NULL;
pcercuei 0:03b5121a232e 27864 xmlNodePtr node, valRoot;
pcercuei 0:03b5121a232e 27865 const xmlChar *nsName;
pcercuei 0:03b5121a232e 27866
pcercuei 0:03b5121a232e 27867 /* DOC VAL TODO: Move this to the start function. */
pcercuei 0:03b5121a232e 27868 if (vctxt->validationRoot != NULL)
pcercuei 0:03b5121a232e 27869 valRoot = vctxt->validationRoot;
pcercuei 0:03b5121a232e 27870 else
pcercuei 0:03b5121a232e 27871 valRoot = xmlDocGetRootElement(vctxt->doc);
pcercuei 0:03b5121a232e 27872 if (valRoot == NULL) {
pcercuei 0:03b5121a232e 27873 /* VAL TODO: Error code? */
pcercuei 0:03b5121a232e 27874 VERROR(1, NULL, "The document has no document element");
pcercuei 0:03b5121a232e 27875 return (1);
pcercuei 0:03b5121a232e 27876 }
pcercuei 0:03b5121a232e 27877 vctxt->depth = -1;
pcercuei 0:03b5121a232e 27878 vctxt->validationRoot = valRoot;
pcercuei 0:03b5121a232e 27879 node = valRoot;
pcercuei 0:03b5121a232e 27880 while (node != NULL) {
pcercuei 0:03b5121a232e 27881 if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
pcercuei 0:03b5121a232e 27882 goto next_sibling;
pcercuei 0:03b5121a232e 27883 if (node->type == XML_ELEMENT_NODE) {
pcercuei 0:03b5121a232e 27884
pcercuei 0:03b5121a232e 27885 /*
pcercuei 0:03b5121a232e 27886 * Init the node-info.
pcercuei 0:03b5121a232e 27887 */
pcercuei 0:03b5121a232e 27888 vctxt->depth++;
pcercuei 0:03b5121a232e 27889 if (xmlSchemaValidatorPushElem(vctxt) == -1)
pcercuei 0:03b5121a232e 27890 goto internal_error;
pcercuei 0:03b5121a232e 27891 ielem = vctxt->inode;
pcercuei 0:03b5121a232e 27892 ielem->node = node;
pcercuei 0:03b5121a232e 27893 ielem->nodeLine = node->line;
pcercuei 0:03b5121a232e 27894 ielem->localName = node->name;
pcercuei 0:03b5121a232e 27895 if (node->ns != NULL)
pcercuei 0:03b5121a232e 27896 ielem->nsName = node->ns->href;
pcercuei 0:03b5121a232e 27897 ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
pcercuei 0:03b5121a232e 27898 /*
pcercuei 0:03b5121a232e 27899 * Register attributes.
pcercuei 0:03b5121a232e 27900 * DOC VAL TODO: We do not register namespace declaration
pcercuei 0:03b5121a232e 27901 * attributes yet.
pcercuei 0:03b5121a232e 27902 */
pcercuei 0:03b5121a232e 27903 vctxt->nbAttrInfos = 0;
pcercuei 0:03b5121a232e 27904 if (node->properties != NULL) {
pcercuei 0:03b5121a232e 27905 attr = node->properties;
pcercuei 0:03b5121a232e 27906 do {
pcercuei 0:03b5121a232e 27907 if (attr->ns != NULL)
pcercuei 0:03b5121a232e 27908 nsName = attr->ns->href;
pcercuei 0:03b5121a232e 27909 else
pcercuei 0:03b5121a232e 27910 nsName = NULL;
pcercuei 0:03b5121a232e 27911 ret = xmlSchemaValidatorPushAttribute(vctxt,
pcercuei 0:03b5121a232e 27912 (xmlNodePtr) attr,
pcercuei 0:03b5121a232e 27913 /*
pcercuei 0:03b5121a232e 27914 * Note that we give it the line number of the
pcercuei 0:03b5121a232e 27915 * parent element.
pcercuei 0:03b5121a232e 27916 */
pcercuei 0:03b5121a232e 27917 ielem->nodeLine,
pcercuei 0:03b5121a232e 27918 attr->name, nsName, 0,
pcercuei 0:03b5121a232e 27919 xmlNodeListGetString(attr->doc, attr->children, 1), 1);
pcercuei 0:03b5121a232e 27920 if (ret == -1) {
pcercuei 0:03b5121a232e 27921 VERROR_INT("xmlSchemaDocWalk",
pcercuei 0:03b5121a232e 27922 "calling xmlSchemaValidatorPushAttribute()");
pcercuei 0:03b5121a232e 27923 goto internal_error;
pcercuei 0:03b5121a232e 27924 }
pcercuei 0:03b5121a232e 27925 attr = attr->next;
pcercuei 0:03b5121a232e 27926 } while (attr);
pcercuei 0:03b5121a232e 27927 }
pcercuei 0:03b5121a232e 27928 /*
pcercuei 0:03b5121a232e 27929 * Validate the element.
pcercuei 0:03b5121a232e 27930 */
pcercuei 0:03b5121a232e 27931 ret = xmlSchemaValidateElem(vctxt);
pcercuei 0:03b5121a232e 27932 if (ret != 0) {
pcercuei 0:03b5121a232e 27933 if (ret == -1) {
pcercuei 0:03b5121a232e 27934 VERROR_INT("xmlSchemaDocWalk",
pcercuei 0:03b5121a232e 27935 "calling xmlSchemaValidateElem()");
pcercuei 0:03b5121a232e 27936 goto internal_error;
pcercuei 0:03b5121a232e 27937 }
pcercuei 0:03b5121a232e 27938 /*
pcercuei 0:03b5121a232e 27939 * Don't stop validation; just skip the content
pcercuei 0:03b5121a232e 27940 * of this element.
pcercuei 0:03b5121a232e 27941 */
pcercuei 0:03b5121a232e 27942 goto leave_node;
pcercuei 0:03b5121a232e 27943 }
pcercuei 0:03b5121a232e 27944 if ((vctxt->skipDepth != -1) &&
pcercuei 0:03b5121a232e 27945 (vctxt->depth >= vctxt->skipDepth))
pcercuei 0:03b5121a232e 27946 goto leave_node;
pcercuei 0:03b5121a232e 27947 } else if ((node->type == XML_TEXT_NODE) ||
pcercuei 0:03b5121a232e 27948 (node->type == XML_CDATA_SECTION_NODE)) {
pcercuei 0:03b5121a232e 27949 /*
pcercuei 0:03b5121a232e 27950 * Process character content.
pcercuei 0:03b5121a232e 27951 */
pcercuei 0:03b5121a232e 27952 if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
pcercuei 0:03b5121a232e 27953 ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
pcercuei 0:03b5121a232e 27954 ret = xmlSchemaVPushText(vctxt, node->type, node->content,
pcercuei 0:03b5121a232e 27955 -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
pcercuei 0:03b5121a232e 27956 if (ret < 0) {
pcercuei 0:03b5121a232e 27957 VERROR_INT("xmlSchemaVDocWalk",
pcercuei 0:03b5121a232e 27958 "calling xmlSchemaVPushText()");
pcercuei 0:03b5121a232e 27959 goto internal_error;
pcercuei 0:03b5121a232e 27960 }
pcercuei 0:03b5121a232e 27961 /*
pcercuei 0:03b5121a232e 27962 * DOC VAL TODO: Should we skip further validation of the
pcercuei 0:03b5121a232e 27963 * element content here?
pcercuei 0:03b5121a232e 27964 */
pcercuei 0:03b5121a232e 27965 } else if ((node->type == XML_ENTITY_NODE) ||
pcercuei 0:03b5121a232e 27966 (node->type == XML_ENTITY_REF_NODE)) {
pcercuei 0:03b5121a232e 27967 /*
pcercuei 0:03b5121a232e 27968 * DOC VAL TODO: What to do with entities?
pcercuei 0:03b5121a232e 27969 */
pcercuei 0:03b5121a232e 27970 VERROR_INT("xmlSchemaVDocWalk",
pcercuei 0:03b5121a232e 27971 "there is at least one entity reference in the node-tree "
pcercuei 0:03b5121a232e 27972 "currently being validated. Processing of entities with "
pcercuei 0:03b5121a232e 27973 "this XML Schema processor is not supported (yet). Please "
pcercuei 0:03b5121a232e 27974 "substitute entities before validation.");
pcercuei 0:03b5121a232e 27975 goto internal_error;
pcercuei 0:03b5121a232e 27976 } else {
pcercuei 0:03b5121a232e 27977 goto leave_node;
pcercuei 0:03b5121a232e 27978 /*
pcercuei 0:03b5121a232e 27979 * DOC VAL TODO: XInclude nodes, etc.
pcercuei 0:03b5121a232e 27980 */
pcercuei 0:03b5121a232e 27981 }
pcercuei 0:03b5121a232e 27982 /*
pcercuei 0:03b5121a232e 27983 * Walk the doc.
pcercuei 0:03b5121a232e 27984 */
pcercuei 0:03b5121a232e 27985 if (node->children != NULL) {
pcercuei 0:03b5121a232e 27986 node = node->children;
pcercuei 0:03b5121a232e 27987 continue;
pcercuei 0:03b5121a232e 27988 }
pcercuei 0:03b5121a232e 27989 leave_node:
pcercuei 0:03b5121a232e 27990 if (node->type == XML_ELEMENT_NODE) {
pcercuei 0:03b5121a232e 27991 /*
pcercuei 0:03b5121a232e 27992 * Leaving the scope of an element.
pcercuei 0:03b5121a232e 27993 */
pcercuei 0:03b5121a232e 27994 if (node != vctxt->inode->node) {
pcercuei 0:03b5121a232e 27995 VERROR_INT("xmlSchemaVDocWalk",
pcercuei 0:03b5121a232e 27996 "element position mismatch");
pcercuei 0:03b5121a232e 27997 goto internal_error;
pcercuei 0:03b5121a232e 27998 }
pcercuei 0:03b5121a232e 27999 ret = xmlSchemaValidatorPopElem(vctxt);
pcercuei 0:03b5121a232e 28000 if (ret != 0) {
pcercuei 0:03b5121a232e 28001 if (ret < 0) {
pcercuei 0:03b5121a232e 28002 VERROR_INT("xmlSchemaVDocWalk",
pcercuei 0:03b5121a232e 28003 "calling xmlSchemaValidatorPopElem()");
pcercuei 0:03b5121a232e 28004 goto internal_error;
pcercuei 0:03b5121a232e 28005 }
pcercuei 0:03b5121a232e 28006 }
pcercuei 0:03b5121a232e 28007 if (node == valRoot)
pcercuei 0:03b5121a232e 28008 goto exit;
pcercuei 0:03b5121a232e 28009 }
pcercuei 0:03b5121a232e 28010 next_sibling:
pcercuei 0:03b5121a232e 28011 if (node->next != NULL)
pcercuei 0:03b5121a232e 28012 node = node->next;
pcercuei 0:03b5121a232e 28013 else {
pcercuei 0:03b5121a232e 28014 node = node->parent;
pcercuei 0:03b5121a232e 28015 goto leave_node;
pcercuei 0:03b5121a232e 28016 }
pcercuei 0:03b5121a232e 28017 }
pcercuei 0:03b5121a232e 28018
pcercuei 0:03b5121a232e 28019 exit:
pcercuei 0:03b5121a232e 28020 return (ret);
pcercuei 0:03b5121a232e 28021 internal_error:
pcercuei 0:03b5121a232e 28022 return (-1);
pcercuei 0:03b5121a232e 28023 }
pcercuei 0:03b5121a232e 28024
pcercuei 0:03b5121a232e 28025 static int
pcercuei 0:03b5121a232e 28026 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
pcercuei 0:03b5121a232e 28027 /*
pcercuei 0:03b5121a232e 28028 * Some initialization.
pcercuei 0:03b5121a232e 28029 */
pcercuei 0:03b5121a232e 28030 vctxt->err = 0;
pcercuei 0:03b5121a232e 28031 vctxt->nberrors = 0;
pcercuei 0:03b5121a232e 28032 vctxt->depth = -1;
pcercuei 0:03b5121a232e 28033 vctxt->skipDepth = -1;
pcercuei 0:03b5121a232e 28034 vctxt->xsiAssemble = 0;
pcercuei 0:03b5121a232e 28035 vctxt->hasKeyrefs = 0;
pcercuei 0:03b5121a232e 28036 #ifdef ENABLE_IDC_NODE_TABLES_TEST
pcercuei 0:03b5121a232e 28037 vctxt->createIDCNodeTables = 1;
pcercuei 0:03b5121a232e 28038 #else
pcercuei 0:03b5121a232e 28039 vctxt->createIDCNodeTables = 0;
pcercuei 0:03b5121a232e 28040 #endif
pcercuei 0:03b5121a232e 28041 /*
pcercuei 0:03b5121a232e 28042 * Create a schema + parser if necessary.
pcercuei 0:03b5121a232e 28043 */
pcercuei 0:03b5121a232e 28044 if (vctxt->schema == NULL) {
pcercuei 0:03b5121a232e 28045 xmlSchemaParserCtxtPtr pctxt;
pcercuei 0:03b5121a232e 28046
pcercuei 0:03b5121a232e 28047 vctxt->xsiAssemble = 1;
pcercuei 0:03b5121a232e 28048 /*
pcercuei 0:03b5121a232e 28049 * If not schema was given then we will create a schema
pcercuei 0:03b5121a232e 28050 * dynamically using XSI schema locations.
pcercuei 0:03b5121a232e 28051 *
pcercuei 0:03b5121a232e 28052 * Create the schema parser context.
pcercuei 0:03b5121a232e 28053 */
pcercuei 0:03b5121a232e 28054 if ((vctxt->pctxt == NULL) &&
pcercuei 0:03b5121a232e 28055 (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
pcercuei 0:03b5121a232e 28056 return (-1);
pcercuei 0:03b5121a232e 28057 pctxt = vctxt->pctxt;
pcercuei 0:03b5121a232e 28058 pctxt->xsiAssemble = 1;
pcercuei 0:03b5121a232e 28059 /*
pcercuei 0:03b5121a232e 28060 * Create the schema.
pcercuei 0:03b5121a232e 28061 */
pcercuei 0:03b5121a232e 28062 vctxt->schema = xmlSchemaNewSchema(pctxt);
pcercuei 0:03b5121a232e 28063 if (vctxt->schema == NULL)
pcercuei 0:03b5121a232e 28064 return (-1);
pcercuei 0:03b5121a232e 28065 /*
pcercuei 0:03b5121a232e 28066 * Create the schema construction context.
pcercuei 0:03b5121a232e 28067 */
pcercuei 0:03b5121a232e 28068 pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
pcercuei 0:03b5121a232e 28069 if (pctxt->constructor == NULL)
pcercuei 0:03b5121a232e 28070 return(-1);
pcercuei 0:03b5121a232e 28071 pctxt->constructor->mainSchema = vctxt->schema;
pcercuei 0:03b5121a232e 28072 /*
pcercuei 0:03b5121a232e 28073 * Take ownership of the constructor to be able to free it.
pcercuei 0:03b5121a232e 28074 */
pcercuei 0:03b5121a232e 28075 pctxt->ownsConstructor = 1;
pcercuei 0:03b5121a232e 28076 }
pcercuei 0:03b5121a232e 28077 /*
pcercuei 0:03b5121a232e 28078 * Augment the IDC definitions for the main schema and all imported ones
pcercuei 0:03b5121a232e 28079 * NOTE: main schema if the first in the imported list
pcercuei 0:03b5121a232e 28080 */
pcercuei 0:03b5121a232e 28081 xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
pcercuei 0:03b5121a232e 28082
pcercuei 0:03b5121a232e 28083 return(0);
pcercuei 0:03b5121a232e 28084 }
pcercuei 0:03b5121a232e 28085
pcercuei 0:03b5121a232e 28086 static void
pcercuei 0:03b5121a232e 28087 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
pcercuei 0:03b5121a232e 28088 if (vctxt->xsiAssemble) {
pcercuei 0:03b5121a232e 28089 if (vctxt->schema != NULL) {
pcercuei 0:03b5121a232e 28090 xmlSchemaFree(vctxt->schema);
pcercuei 0:03b5121a232e 28091 vctxt->schema = NULL;
pcercuei 0:03b5121a232e 28092 }
pcercuei 0:03b5121a232e 28093 }
pcercuei 0:03b5121a232e 28094 xmlSchemaClearValidCtxt(vctxt);
pcercuei 0:03b5121a232e 28095 }
pcercuei 0:03b5121a232e 28096
pcercuei 0:03b5121a232e 28097 static int
pcercuei 0:03b5121a232e 28098 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
pcercuei 0:03b5121a232e 28099 {
pcercuei 0:03b5121a232e 28100 int ret = 0;
pcercuei 0:03b5121a232e 28101
pcercuei 0:03b5121a232e 28102 if (xmlSchemaPreRun(vctxt) < 0)
pcercuei 0:03b5121a232e 28103 return(-1);
pcercuei 0:03b5121a232e 28104
pcercuei 0:03b5121a232e 28105 if (vctxt->doc != NULL) {
pcercuei 0:03b5121a232e 28106 /*
pcercuei 0:03b5121a232e 28107 * Tree validation.
pcercuei 0:03b5121a232e 28108 */
pcercuei 0:03b5121a232e 28109 ret = xmlSchemaVDocWalk(vctxt);
pcercuei 0:03b5121a232e 28110 #ifdef LIBXML_READER_ENABLED
pcercuei 0:03b5121a232e 28111 } else if (vctxt->reader != NULL) {
pcercuei 0:03b5121a232e 28112 /*
pcercuei 0:03b5121a232e 28113 * XML Reader validation.
pcercuei 0:03b5121a232e 28114 */
pcercuei 0:03b5121a232e 28115 #ifdef XML_SCHEMA_READER_ENABLED
pcercuei 0:03b5121a232e 28116 ret = xmlSchemaVReaderWalk(vctxt);
pcercuei 0:03b5121a232e 28117 #endif
pcercuei 0:03b5121a232e 28118 #endif
pcercuei 0:03b5121a232e 28119 } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
pcercuei 0:03b5121a232e 28120 /*
pcercuei 0:03b5121a232e 28121 * SAX validation.
pcercuei 0:03b5121a232e 28122 */
pcercuei 0:03b5121a232e 28123 ret = xmlParseDocument(vctxt->parserCtxt);
pcercuei 0:03b5121a232e 28124 } else {
pcercuei 0:03b5121a232e 28125 VERROR_INT("xmlSchemaVStart",
pcercuei 0:03b5121a232e 28126 "no instance to validate");
pcercuei 0:03b5121a232e 28127 ret = -1;
pcercuei 0:03b5121a232e 28128 }
pcercuei 0:03b5121a232e 28129
pcercuei 0:03b5121a232e 28130 xmlSchemaPostRun(vctxt);
pcercuei 0:03b5121a232e 28131 if (ret == 0)
pcercuei 0:03b5121a232e 28132 ret = vctxt->err;
pcercuei 0:03b5121a232e 28133 return (ret);
pcercuei 0:03b5121a232e 28134 }
pcercuei 0:03b5121a232e 28135
pcercuei 0:03b5121a232e 28136 /**
pcercuei 0:03b5121a232e 28137 * xmlSchemaValidateOneElement:
pcercuei 0:03b5121a232e 28138 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 28139 * @elem: an element node
pcercuei 0:03b5121a232e 28140 *
pcercuei 0:03b5121a232e 28141 * Validate a branch of a tree, starting with the given @elem.
pcercuei 0:03b5121a232e 28142 *
pcercuei 0:03b5121a232e 28143 * Returns 0 if the element and its subtree is valid, a positive error
pcercuei 0:03b5121a232e 28144 * code number otherwise and -1 in case of an internal or API error.
pcercuei 0:03b5121a232e 28145 */
pcercuei 0:03b5121a232e 28146 int
pcercuei 0:03b5121a232e 28147 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
pcercuei 0:03b5121a232e 28148 {
pcercuei 0:03b5121a232e 28149 if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
pcercuei 0:03b5121a232e 28150 return (-1);
pcercuei 0:03b5121a232e 28151
pcercuei 0:03b5121a232e 28152 if (ctxt->schema == NULL)
pcercuei 0:03b5121a232e 28153 return (-1);
pcercuei 0:03b5121a232e 28154
pcercuei 0:03b5121a232e 28155 ctxt->doc = elem->doc;
pcercuei 0:03b5121a232e 28156 ctxt->node = elem;
pcercuei 0:03b5121a232e 28157 ctxt->validationRoot = elem;
pcercuei 0:03b5121a232e 28158 return(xmlSchemaVStart(ctxt));
pcercuei 0:03b5121a232e 28159 }
pcercuei 0:03b5121a232e 28160
pcercuei 0:03b5121a232e 28161 /**
pcercuei 0:03b5121a232e 28162 * xmlSchemaValidateDoc:
pcercuei 0:03b5121a232e 28163 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 28164 * @doc: a parsed document tree
pcercuei 0:03b5121a232e 28165 *
pcercuei 0:03b5121a232e 28166 * Validate a document tree in memory.
pcercuei 0:03b5121a232e 28167 *
pcercuei 0:03b5121a232e 28168 * Returns 0 if the document is schemas valid, a positive error code
pcercuei 0:03b5121a232e 28169 * number otherwise and -1 in case of internal or API error.
pcercuei 0:03b5121a232e 28170 */
pcercuei 0:03b5121a232e 28171 int
pcercuei 0:03b5121a232e 28172 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
pcercuei 0:03b5121a232e 28173 {
pcercuei 0:03b5121a232e 28174 if ((ctxt == NULL) || (doc == NULL))
pcercuei 0:03b5121a232e 28175 return (-1);
pcercuei 0:03b5121a232e 28176
pcercuei 0:03b5121a232e 28177 ctxt->doc = doc;
pcercuei 0:03b5121a232e 28178 ctxt->node = xmlDocGetRootElement(doc);
pcercuei 0:03b5121a232e 28179 if (ctxt->node == NULL) {
pcercuei 0:03b5121a232e 28180 xmlSchemaCustomErr(ACTXT_CAST ctxt,
pcercuei 0:03b5121a232e 28181 XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
pcercuei 0:03b5121a232e 28182 (xmlNodePtr) doc, NULL,
pcercuei 0:03b5121a232e 28183 "The document has no document element", NULL, NULL);
pcercuei 0:03b5121a232e 28184 return (ctxt->err);
pcercuei 0:03b5121a232e 28185 }
pcercuei 0:03b5121a232e 28186 ctxt->validationRoot = ctxt->node;
pcercuei 0:03b5121a232e 28187 return (xmlSchemaVStart(ctxt));
pcercuei 0:03b5121a232e 28188 }
pcercuei 0:03b5121a232e 28189
pcercuei 0:03b5121a232e 28190
pcercuei 0:03b5121a232e 28191 /************************************************************************
pcercuei 0:03b5121a232e 28192 * *
pcercuei 0:03b5121a232e 28193 * Function and data for SAX streaming API *
pcercuei 0:03b5121a232e 28194 * *
pcercuei 0:03b5121a232e 28195 ************************************************************************/
pcercuei 0:03b5121a232e 28196 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
pcercuei 0:03b5121a232e 28197 typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
pcercuei 0:03b5121a232e 28198
pcercuei 0:03b5121a232e 28199 struct _xmlSchemaSplitSAXData {
pcercuei 0:03b5121a232e 28200 xmlSAXHandlerPtr user_sax;
pcercuei 0:03b5121a232e 28201 void *user_data;
pcercuei 0:03b5121a232e 28202 xmlSchemaValidCtxtPtr ctxt;
pcercuei 0:03b5121a232e 28203 xmlSAXHandlerPtr schemas_sax;
pcercuei 0:03b5121a232e 28204 };
pcercuei 0:03b5121a232e 28205
pcercuei 0:03b5121a232e 28206 #define XML_SAX_PLUG_MAGIC 0xdc43ba21
pcercuei 0:03b5121a232e 28207
pcercuei 0:03b5121a232e 28208 struct _xmlSchemaSAXPlug {
pcercuei 0:03b5121a232e 28209 unsigned int magic;
pcercuei 0:03b5121a232e 28210
pcercuei 0:03b5121a232e 28211 /* the original callbacks informations */
pcercuei 0:03b5121a232e 28212 xmlSAXHandlerPtr *user_sax_ptr;
pcercuei 0:03b5121a232e 28213 xmlSAXHandlerPtr user_sax;
pcercuei 0:03b5121a232e 28214 void **user_data_ptr;
pcercuei 0:03b5121a232e 28215 void *user_data;
pcercuei 0:03b5121a232e 28216
pcercuei 0:03b5121a232e 28217 /* the block plugged back and validation informations */
pcercuei 0:03b5121a232e 28218 xmlSAXHandler schemas_sax;
pcercuei 0:03b5121a232e 28219 xmlSchemaValidCtxtPtr ctxt;
pcercuei 0:03b5121a232e 28220 };
pcercuei 0:03b5121a232e 28221
pcercuei 0:03b5121a232e 28222 /* All those functions just bounces to the user provided SAX handlers */
pcercuei 0:03b5121a232e 28223 static void
pcercuei 0:03b5121a232e 28224 internalSubsetSplit(void *ctx, const xmlChar *name,
pcercuei 0:03b5121a232e 28225 const xmlChar *ExternalID, const xmlChar *SystemID)
pcercuei 0:03b5121a232e 28226 {
pcercuei 0:03b5121a232e 28227 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28228 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28229 (ctxt->user_sax->internalSubset != NULL))
pcercuei 0:03b5121a232e 28230 ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
pcercuei 0:03b5121a232e 28231 SystemID);
pcercuei 0:03b5121a232e 28232 }
pcercuei 0:03b5121a232e 28233
pcercuei 0:03b5121a232e 28234 static int
pcercuei 0:03b5121a232e 28235 isStandaloneSplit(void *ctx)
pcercuei 0:03b5121a232e 28236 {
pcercuei 0:03b5121a232e 28237 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28238 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28239 (ctxt->user_sax->isStandalone != NULL))
pcercuei 0:03b5121a232e 28240 return(ctxt->user_sax->isStandalone(ctxt->user_data));
pcercuei 0:03b5121a232e 28241 return(0);
pcercuei 0:03b5121a232e 28242 }
pcercuei 0:03b5121a232e 28243
pcercuei 0:03b5121a232e 28244 static int
pcercuei 0:03b5121a232e 28245 hasInternalSubsetSplit(void *ctx)
pcercuei 0:03b5121a232e 28246 {
pcercuei 0:03b5121a232e 28247 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28248 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28249 (ctxt->user_sax->hasInternalSubset != NULL))
pcercuei 0:03b5121a232e 28250 return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
pcercuei 0:03b5121a232e 28251 return(0);
pcercuei 0:03b5121a232e 28252 }
pcercuei 0:03b5121a232e 28253
pcercuei 0:03b5121a232e 28254 static int
pcercuei 0:03b5121a232e 28255 hasExternalSubsetSplit(void *ctx)
pcercuei 0:03b5121a232e 28256 {
pcercuei 0:03b5121a232e 28257 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28258 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28259 (ctxt->user_sax->hasExternalSubset != NULL))
pcercuei 0:03b5121a232e 28260 return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
pcercuei 0:03b5121a232e 28261 return(0);
pcercuei 0:03b5121a232e 28262 }
pcercuei 0:03b5121a232e 28263
pcercuei 0:03b5121a232e 28264 static void
pcercuei 0:03b5121a232e 28265 externalSubsetSplit(void *ctx, const xmlChar *name,
pcercuei 0:03b5121a232e 28266 const xmlChar *ExternalID, const xmlChar *SystemID)
pcercuei 0:03b5121a232e 28267 {
pcercuei 0:03b5121a232e 28268 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28269 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28270 (ctxt->user_sax->externalSubset != NULL))
pcercuei 0:03b5121a232e 28271 ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
pcercuei 0:03b5121a232e 28272 SystemID);
pcercuei 0:03b5121a232e 28273 }
pcercuei 0:03b5121a232e 28274
pcercuei 0:03b5121a232e 28275 static xmlParserInputPtr
pcercuei 0:03b5121a232e 28276 resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
pcercuei 0:03b5121a232e 28277 {
pcercuei 0:03b5121a232e 28278 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28279 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28280 (ctxt->user_sax->resolveEntity != NULL))
pcercuei 0:03b5121a232e 28281 return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
pcercuei 0:03b5121a232e 28282 systemId));
pcercuei 0:03b5121a232e 28283 return(NULL);
pcercuei 0:03b5121a232e 28284 }
pcercuei 0:03b5121a232e 28285
pcercuei 0:03b5121a232e 28286 static xmlEntityPtr
pcercuei 0:03b5121a232e 28287 getEntitySplit(void *ctx, const xmlChar *name)
pcercuei 0:03b5121a232e 28288 {
pcercuei 0:03b5121a232e 28289 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28290 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28291 (ctxt->user_sax->getEntity != NULL))
pcercuei 0:03b5121a232e 28292 return(ctxt->user_sax->getEntity(ctxt->user_data, name));
pcercuei 0:03b5121a232e 28293 return(NULL);
pcercuei 0:03b5121a232e 28294 }
pcercuei 0:03b5121a232e 28295
pcercuei 0:03b5121a232e 28296 static xmlEntityPtr
pcercuei 0:03b5121a232e 28297 getParameterEntitySplit(void *ctx, const xmlChar *name)
pcercuei 0:03b5121a232e 28298 {
pcercuei 0:03b5121a232e 28299 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28300 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28301 (ctxt->user_sax->getParameterEntity != NULL))
pcercuei 0:03b5121a232e 28302 return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
pcercuei 0:03b5121a232e 28303 return(NULL);
pcercuei 0:03b5121a232e 28304 }
pcercuei 0:03b5121a232e 28305
pcercuei 0:03b5121a232e 28306
pcercuei 0:03b5121a232e 28307 static void
pcercuei 0:03b5121a232e 28308 entityDeclSplit(void *ctx, const xmlChar *name, int type,
pcercuei 0:03b5121a232e 28309 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
pcercuei 0:03b5121a232e 28310 {
pcercuei 0:03b5121a232e 28311 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28312 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28313 (ctxt->user_sax->entityDecl != NULL))
pcercuei 0:03b5121a232e 28314 ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
pcercuei 0:03b5121a232e 28315 systemId, content);
pcercuei 0:03b5121a232e 28316 }
pcercuei 0:03b5121a232e 28317
pcercuei 0:03b5121a232e 28318 static void
pcercuei 0:03b5121a232e 28319 attributeDeclSplit(void *ctx, const xmlChar * elem,
pcercuei 0:03b5121a232e 28320 const xmlChar * name, int type, int def,
pcercuei 0:03b5121a232e 28321 const xmlChar * defaultValue, xmlEnumerationPtr tree)
pcercuei 0:03b5121a232e 28322 {
pcercuei 0:03b5121a232e 28323 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28324 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28325 (ctxt->user_sax->attributeDecl != NULL)) {
pcercuei 0:03b5121a232e 28326 ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
pcercuei 0:03b5121a232e 28327 def, defaultValue, tree);
pcercuei 0:03b5121a232e 28328 } else {
pcercuei 0:03b5121a232e 28329 xmlFreeEnumeration(tree);
pcercuei 0:03b5121a232e 28330 }
pcercuei 0:03b5121a232e 28331 }
pcercuei 0:03b5121a232e 28332
pcercuei 0:03b5121a232e 28333 static void
pcercuei 0:03b5121a232e 28334 elementDeclSplit(void *ctx, const xmlChar *name, int type,
pcercuei 0:03b5121a232e 28335 xmlElementContentPtr content)
pcercuei 0:03b5121a232e 28336 {
pcercuei 0:03b5121a232e 28337 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28338 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28339 (ctxt->user_sax->elementDecl != NULL))
pcercuei 0:03b5121a232e 28340 ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
pcercuei 0:03b5121a232e 28341 }
pcercuei 0:03b5121a232e 28342
pcercuei 0:03b5121a232e 28343 static void
pcercuei 0:03b5121a232e 28344 notationDeclSplit(void *ctx, const xmlChar *name,
pcercuei 0:03b5121a232e 28345 const xmlChar *publicId, const xmlChar *systemId)
pcercuei 0:03b5121a232e 28346 {
pcercuei 0:03b5121a232e 28347 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28348 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28349 (ctxt->user_sax->notationDecl != NULL))
pcercuei 0:03b5121a232e 28350 ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
pcercuei 0:03b5121a232e 28351 systemId);
pcercuei 0:03b5121a232e 28352 }
pcercuei 0:03b5121a232e 28353
pcercuei 0:03b5121a232e 28354 static void
pcercuei 0:03b5121a232e 28355 unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
pcercuei 0:03b5121a232e 28356 const xmlChar *publicId, const xmlChar *systemId,
pcercuei 0:03b5121a232e 28357 const xmlChar *notationName)
pcercuei 0:03b5121a232e 28358 {
pcercuei 0:03b5121a232e 28359 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28360 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28361 (ctxt->user_sax->unparsedEntityDecl != NULL))
pcercuei 0:03b5121a232e 28362 ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
pcercuei 0:03b5121a232e 28363 systemId, notationName);
pcercuei 0:03b5121a232e 28364 }
pcercuei 0:03b5121a232e 28365
pcercuei 0:03b5121a232e 28366 static void
pcercuei 0:03b5121a232e 28367 setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
pcercuei 0:03b5121a232e 28368 {
pcercuei 0:03b5121a232e 28369 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28370 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28371 (ctxt->user_sax->setDocumentLocator != NULL))
pcercuei 0:03b5121a232e 28372 ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
pcercuei 0:03b5121a232e 28373 }
pcercuei 0:03b5121a232e 28374
pcercuei 0:03b5121a232e 28375 static void
pcercuei 0:03b5121a232e 28376 startDocumentSplit(void *ctx)
pcercuei 0:03b5121a232e 28377 {
pcercuei 0:03b5121a232e 28378 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28379 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28380 (ctxt->user_sax->startDocument != NULL))
pcercuei 0:03b5121a232e 28381 ctxt->user_sax->startDocument(ctxt->user_data);
pcercuei 0:03b5121a232e 28382 }
pcercuei 0:03b5121a232e 28383
pcercuei 0:03b5121a232e 28384 static void
pcercuei 0:03b5121a232e 28385 endDocumentSplit(void *ctx)
pcercuei 0:03b5121a232e 28386 {
pcercuei 0:03b5121a232e 28387 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28388 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28389 (ctxt->user_sax->endDocument != NULL))
pcercuei 0:03b5121a232e 28390 ctxt->user_sax->endDocument(ctxt->user_data);
pcercuei 0:03b5121a232e 28391 }
pcercuei 0:03b5121a232e 28392
pcercuei 0:03b5121a232e 28393 static void
pcercuei 0:03b5121a232e 28394 processingInstructionSplit(void *ctx, const xmlChar *target,
pcercuei 0:03b5121a232e 28395 const xmlChar *data)
pcercuei 0:03b5121a232e 28396 {
pcercuei 0:03b5121a232e 28397 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28398 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28399 (ctxt->user_sax->processingInstruction != NULL))
pcercuei 0:03b5121a232e 28400 ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
pcercuei 0:03b5121a232e 28401 }
pcercuei 0:03b5121a232e 28402
pcercuei 0:03b5121a232e 28403 static void
pcercuei 0:03b5121a232e 28404 commentSplit(void *ctx, const xmlChar *value)
pcercuei 0:03b5121a232e 28405 {
pcercuei 0:03b5121a232e 28406 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28407 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28408 (ctxt->user_sax->comment != NULL))
pcercuei 0:03b5121a232e 28409 ctxt->user_sax->comment(ctxt->user_data, value);
pcercuei 0:03b5121a232e 28410 }
pcercuei 0:03b5121a232e 28411
pcercuei 0:03b5121a232e 28412 /*
pcercuei 0:03b5121a232e 28413 * Varargs error callbacks to the user application, harder ...
pcercuei 0:03b5121a232e 28414 */
pcercuei 0:03b5121a232e 28415
pcercuei 0:03b5121a232e 28416 static void XMLCDECL
pcercuei 0:03b5121a232e 28417 warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
pcercuei 0:03b5121a232e 28418 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28419 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28420 (ctxt->user_sax->warning != NULL)) {
pcercuei 0:03b5121a232e 28421 TODO
pcercuei 0:03b5121a232e 28422 }
pcercuei 0:03b5121a232e 28423 }
pcercuei 0:03b5121a232e 28424 static void XMLCDECL
pcercuei 0:03b5121a232e 28425 errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
pcercuei 0:03b5121a232e 28426 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28427 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28428 (ctxt->user_sax->error != NULL)) {
pcercuei 0:03b5121a232e 28429 TODO
pcercuei 0:03b5121a232e 28430 }
pcercuei 0:03b5121a232e 28431 }
pcercuei 0:03b5121a232e 28432 static void XMLCDECL
pcercuei 0:03b5121a232e 28433 fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
pcercuei 0:03b5121a232e 28434 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28435 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28436 (ctxt->user_sax->fatalError != NULL)) {
pcercuei 0:03b5121a232e 28437 TODO
pcercuei 0:03b5121a232e 28438 }
pcercuei 0:03b5121a232e 28439 }
pcercuei 0:03b5121a232e 28440
pcercuei 0:03b5121a232e 28441 /*
pcercuei 0:03b5121a232e 28442 * Those are function where both the user handler and the schemas handler
pcercuei 0:03b5121a232e 28443 * need to be called.
pcercuei 0:03b5121a232e 28444 */
pcercuei 0:03b5121a232e 28445 static void
pcercuei 0:03b5121a232e 28446 charactersSplit(void *ctx, const xmlChar *ch, int len)
pcercuei 0:03b5121a232e 28447 {
pcercuei 0:03b5121a232e 28448 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28449 if (ctxt == NULL)
pcercuei 0:03b5121a232e 28450 return;
pcercuei 0:03b5121a232e 28451 if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
pcercuei 0:03b5121a232e 28452 ctxt->user_sax->characters(ctxt->user_data, ch, len);
pcercuei 0:03b5121a232e 28453 if (ctxt->ctxt != NULL)
pcercuei 0:03b5121a232e 28454 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
pcercuei 0:03b5121a232e 28455 }
pcercuei 0:03b5121a232e 28456
pcercuei 0:03b5121a232e 28457 static void
pcercuei 0:03b5121a232e 28458 ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
pcercuei 0:03b5121a232e 28459 {
pcercuei 0:03b5121a232e 28460 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28461 if (ctxt == NULL)
pcercuei 0:03b5121a232e 28462 return;
pcercuei 0:03b5121a232e 28463 if ((ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28464 (ctxt->user_sax->ignorableWhitespace != NULL))
pcercuei 0:03b5121a232e 28465 ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
pcercuei 0:03b5121a232e 28466 if (ctxt->ctxt != NULL)
pcercuei 0:03b5121a232e 28467 xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
pcercuei 0:03b5121a232e 28468 }
pcercuei 0:03b5121a232e 28469
pcercuei 0:03b5121a232e 28470 static void
pcercuei 0:03b5121a232e 28471 cdataBlockSplit(void *ctx, const xmlChar *value, int len)
pcercuei 0:03b5121a232e 28472 {
pcercuei 0:03b5121a232e 28473 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28474 if (ctxt == NULL)
pcercuei 0:03b5121a232e 28475 return;
pcercuei 0:03b5121a232e 28476 if ((ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28477 (ctxt->user_sax->cdataBlock != NULL))
pcercuei 0:03b5121a232e 28478 ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
pcercuei 0:03b5121a232e 28479 if (ctxt->ctxt != NULL)
pcercuei 0:03b5121a232e 28480 xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
pcercuei 0:03b5121a232e 28481 }
pcercuei 0:03b5121a232e 28482
pcercuei 0:03b5121a232e 28483 static void
pcercuei 0:03b5121a232e 28484 referenceSplit(void *ctx, const xmlChar *name)
pcercuei 0:03b5121a232e 28485 {
pcercuei 0:03b5121a232e 28486 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28487 if (ctxt == NULL)
pcercuei 0:03b5121a232e 28488 return;
pcercuei 0:03b5121a232e 28489 if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28490 (ctxt->user_sax->reference != NULL))
pcercuei 0:03b5121a232e 28491 ctxt->user_sax->reference(ctxt->user_data, name);
pcercuei 0:03b5121a232e 28492 if (ctxt->ctxt != NULL)
pcercuei 0:03b5121a232e 28493 xmlSchemaSAXHandleReference(ctxt->user_data, name);
pcercuei 0:03b5121a232e 28494 }
pcercuei 0:03b5121a232e 28495
pcercuei 0:03b5121a232e 28496 static void
pcercuei 0:03b5121a232e 28497 startElementNsSplit(void *ctx, const xmlChar * localname,
pcercuei 0:03b5121a232e 28498 const xmlChar * prefix, const xmlChar * URI,
pcercuei 0:03b5121a232e 28499 int nb_namespaces, const xmlChar ** namespaces,
pcercuei 0:03b5121a232e 28500 int nb_attributes, int nb_defaulted,
pcercuei 0:03b5121a232e 28501 const xmlChar ** attributes) {
pcercuei 0:03b5121a232e 28502 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28503 if (ctxt == NULL)
pcercuei 0:03b5121a232e 28504 return;
pcercuei 0:03b5121a232e 28505 if ((ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28506 (ctxt->user_sax->startElementNs != NULL))
pcercuei 0:03b5121a232e 28507 ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
pcercuei 0:03b5121a232e 28508 URI, nb_namespaces, namespaces,
pcercuei 0:03b5121a232e 28509 nb_attributes, nb_defaulted,
pcercuei 0:03b5121a232e 28510 attributes);
pcercuei 0:03b5121a232e 28511 if (ctxt->ctxt != NULL)
pcercuei 0:03b5121a232e 28512 xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
pcercuei 0:03b5121a232e 28513 URI, nb_namespaces, namespaces,
pcercuei 0:03b5121a232e 28514 nb_attributes, nb_defaulted,
pcercuei 0:03b5121a232e 28515 attributes);
pcercuei 0:03b5121a232e 28516 }
pcercuei 0:03b5121a232e 28517
pcercuei 0:03b5121a232e 28518 static void
pcercuei 0:03b5121a232e 28519 endElementNsSplit(void *ctx, const xmlChar * localname,
pcercuei 0:03b5121a232e 28520 const xmlChar * prefix, const xmlChar * URI) {
pcercuei 0:03b5121a232e 28521 xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
pcercuei 0:03b5121a232e 28522 if (ctxt == NULL)
pcercuei 0:03b5121a232e 28523 return;
pcercuei 0:03b5121a232e 28524 if ((ctxt->user_sax != NULL) &&
pcercuei 0:03b5121a232e 28525 (ctxt->user_sax->endElementNs != NULL))
pcercuei 0:03b5121a232e 28526 ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
pcercuei 0:03b5121a232e 28527 if (ctxt->ctxt != NULL)
pcercuei 0:03b5121a232e 28528 xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
pcercuei 0:03b5121a232e 28529 }
pcercuei 0:03b5121a232e 28530
pcercuei 0:03b5121a232e 28531 /**
pcercuei 0:03b5121a232e 28532 * xmlSchemaSAXPlug:
pcercuei 0:03b5121a232e 28533 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 28534 * @sax: a pointer to the original xmlSAXHandlerPtr
pcercuei 0:03b5121a232e 28535 * @user_data: a pointer to the original SAX user data pointer
pcercuei 0:03b5121a232e 28536 *
pcercuei 0:03b5121a232e 28537 * Plug a SAX based validation layer in a SAX parsing event flow.
pcercuei 0:03b5121a232e 28538 * The original @saxptr and @dataptr data are replaced by new pointers
pcercuei 0:03b5121a232e 28539 * but the calls to the original will be maintained.
pcercuei 0:03b5121a232e 28540 *
pcercuei 0:03b5121a232e 28541 * Returns a pointer to a data structure needed to unplug the validation layer
pcercuei 0:03b5121a232e 28542 * or NULL in case of errors.
pcercuei 0:03b5121a232e 28543 */
pcercuei 0:03b5121a232e 28544 xmlSchemaSAXPlugPtr
pcercuei 0:03b5121a232e 28545 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
pcercuei 0:03b5121a232e 28546 xmlSAXHandlerPtr *sax, void **user_data)
pcercuei 0:03b5121a232e 28547 {
pcercuei 0:03b5121a232e 28548 xmlSchemaSAXPlugPtr ret;
pcercuei 0:03b5121a232e 28549 xmlSAXHandlerPtr old_sax;
pcercuei 0:03b5121a232e 28550
pcercuei 0:03b5121a232e 28551 if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
pcercuei 0:03b5121a232e 28552 return(NULL);
pcercuei 0:03b5121a232e 28553
pcercuei 0:03b5121a232e 28554 /*
pcercuei 0:03b5121a232e 28555 * We only allow to plug into SAX2 event streams
pcercuei 0:03b5121a232e 28556 */
pcercuei 0:03b5121a232e 28557 old_sax = *sax;
pcercuei 0:03b5121a232e 28558 if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
pcercuei 0:03b5121a232e 28559 return(NULL);
pcercuei 0:03b5121a232e 28560 if ((old_sax != NULL) &&
pcercuei 0:03b5121a232e 28561 (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
pcercuei 0:03b5121a232e 28562 ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
pcercuei 0:03b5121a232e 28563 return(NULL);
pcercuei 0:03b5121a232e 28564
pcercuei 0:03b5121a232e 28565 /*
pcercuei 0:03b5121a232e 28566 * everything seems right allocate the local data needed for that layer
pcercuei 0:03b5121a232e 28567 */
pcercuei 0:03b5121a232e 28568 ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
pcercuei 0:03b5121a232e 28569 if (ret == NULL) {
pcercuei 0:03b5121a232e 28570 return(NULL);
pcercuei 0:03b5121a232e 28571 }
pcercuei 0:03b5121a232e 28572 memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
pcercuei 0:03b5121a232e 28573 ret->magic = XML_SAX_PLUG_MAGIC;
pcercuei 0:03b5121a232e 28574 ret->schemas_sax.initialized = XML_SAX2_MAGIC;
pcercuei 0:03b5121a232e 28575 ret->ctxt = ctxt;
pcercuei 0:03b5121a232e 28576 ret->user_sax_ptr = sax;
pcercuei 0:03b5121a232e 28577 ret->user_sax = old_sax;
pcercuei 0:03b5121a232e 28578 if (old_sax == NULL) {
pcercuei 0:03b5121a232e 28579 /*
pcercuei 0:03b5121a232e 28580 * go direct, no need for the split block and functions.
pcercuei 0:03b5121a232e 28581 */
pcercuei 0:03b5121a232e 28582 ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
pcercuei 0:03b5121a232e 28583 ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
pcercuei 0:03b5121a232e 28584 /*
pcercuei 0:03b5121a232e 28585 * Note that we use the same text-function for both, to prevent
pcercuei 0:03b5121a232e 28586 * the parser from testing for ignorable whitespace.
pcercuei 0:03b5121a232e 28587 */
pcercuei 0:03b5121a232e 28588 ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
pcercuei 0:03b5121a232e 28589 ret->schemas_sax.characters = xmlSchemaSAXHandleText;
pcercuei 0:03b5121a232e 28590
pcercuei 0:03b5121a232e 28591 ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
pcercuei 0:03b5121a232e 28592 ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
pcercuei 0:03b5121a232e 28593
pcercuei 0:03b5121a232e 28594 ret->user_data = ctxt;
pcercuei 0:03b5121a232e 28595 *user_data = ctxt;
pcercuei 0:03b5121a232e 28596 } else {
pcercuei 0:03b5121a232e 28597 /*
pcercuei 0:03b5121a232e 28598 * for each callback unused by Schemas initialize it to the Split
pcercuei 0:03b5121a232e 28599 * routine only if non NULL in the user block, this can speed up
pcercuei 0:03b5121a232e 28600 * things at the SAX level.
pcercuei 0:03b5121a232e 28601 */
pcercuei 0:03b5121a232e 28602 if (old_sax->internalSubset != NULL)
pcercuei 0:03b5121a232e 28603 ret->schemas_sax.internalSubset = internalSubsetSplit;
pcercuei 0:03b5121a232e 28604 if (old_sax->isStandalone != NULL)
pcercuei 0:03b5121a232e 28605 ret->schemas_sax.isStandalone = isStandaloneSplit;
pcercuei 0:03b5121a232e 28606 if (old_sax->hasInternalSubset != NULL)
pcercuei 0:03b5121a232e 28607 ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
pcercuei 0:03b5121a232e 28608 if (old_sax->hasExternalSubset != NULL)
pcercuei 0:03b5121a232e 28609 ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
pcercuei 0:03b5121a232e 28610 if (old_sax->resolveEntity != NULL)
pcercuei 0:03b5121a232e 28611 ret->schemas_sax.resolveEntity = resolveEntitySplit;
pcercuei 0:03b5121a232e 28612 if (old_sax->getEntity != NULL)
pcercuei 0:03b5121a232e 28613 ret->schemas_sax.getEntity = getEntitySplit;
pcercuei 0:03b5121a232e 28614 if (old_sax->entityDecl != NULL)
pcercuei 0:03b5121a232e 28615 ret->schemas_sax.entityDecl = entityDeclSplit;
pcercuei 0:03b5121a232e 28616 if (old_sax->notationDecl != NULL)
pcercuei 0:03b5121a232e 28617 ret->schemas_sax.notationDecl = notationDeclSplit;
pcercuei 0:03b5121a232e 28618 if (old_sax->attributeDecl != NULL)
pcercuei 0:03b5121a232e 28619 ret->schemas_sax.attributeDecl = attributeDeclSplit;
pcercuei 0:03b5121a232e 28620 if (old_sax->elementDecl != NULL)
pcercuei 0:03b5121a232e 28621 ret->schemas_sax.elementDecl = elementDeclSplit;
pcercuei 0:03b5121a232e 28622 if (old_sax->unparsedEntityDecl != NULL)
pcercuei 0:03b5121a232e 28623 ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
pcercuei 0:03b5121a232e 28624 if (old_sax->setDocumentLocator != NULL)
pcercuei 0:03b5121a232e 28625 ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
pcercuei 0:03b5121a232e 28626 if (old_sax->startDocument != NULL)
pcercuei 0:03b5121a232e 28627 ret->schemas_sax.startDocument = startDocumentSplit;
pcercuei 0:03b5121a232e 28628 if (old_sax->endDocument != NULL)
pcercuei 0:03b5121a232e 28629 ret->schemas_sax.endDocument = endDocumentSplit;
pcercuei 0:03b5121a232e 28630 if (old_sax->processingInstruction != NULL)
pcercuei 0:03b5121a232e 28631 ret->schemas_sax.processingInstruction = processingInstructionSplit;
pcercuei 0:03b5121a232e 28632 if (old_sax->comment != NULL)
pcercuei 0:03b5121a232e 28633 ret->schemas_sax.comment = commentSplit;
pcercuei 0:03b5121a232e 28634 if (old_sax->warning != NULL)
pcercuei 0:03b5121a232e 28635 ret->schemas_sax.warning = warningSplit;
pcercuei 0:03b5121a232e 28636 if (old_sax->error != NULL)
pcercuei 0:03b5121a232e 28637 ret->schemas_sax.error = errorSplit;
pcercuei 0:03b5121a232e 28638 if (old_sax->fatalError != NULL)
pcercuei 0:03b5121a232e 28639 ret->schemas_sax.fatalError = fatalErrorSplit;
pcercuei 0:03b5121a232e 28640 if (old_sax->getParameterEntity != NULL)
pcercuei 0:03b5121a232e 28641 ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
pcercuei 0:03b5121a232e 28642 if (old_sax->externalSubset != NULL)
pcercuei 0:03b5121a232e 28643 ret->schemas_sax.externalSubset = externalSubsetSplit;
pcercuei 0:03b5121a232e 28644
pcercuei 0:03b5121a232e 28645 /*
pcercuei 0:03b5121a232e 28646 * the 6 schemas callback have to go to the splitter functions
pcercuei 0:03b5121a232e 28647 * Note that we use the same text-function for ignorableWhitespace
pcercuei 0:03b5121a232e 28648 * if possible, to prevent the parser from testing for ignorable
pcercuei 0:03b5121a232e 28649 * whitespace.
pcercuei 0:03b5121a232e 28650 */
pcercuei 0:03b5121a232e 28651 ret->schemas_sax.characters = charactersSplit;
pcercuei 0:03b5121a232e 28652 if ((old_sax->ignorableWhitespace != NULL) &&
pcercuei 0:03b5121a232e 28653 (old_sax->ignorableWhitespace != old_sax->characters))
pcercuei 0:03b5121a232e 28654 ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
pcercuei 0:03b5121a232e 28655 else
pcercuei 0:03b5121a232e 28656 ret->schemas_sax.ignorableWhitespace = charactersSplit;
pcercuei 0:03b5121a232e 28657 ret->schemas_sax.cdataBlock = cdataBlockSplit;
pcercuei 0:03b5121a232e 28658 ret->schemas_sax.reference = referenceSplit;
pcercuei 0:03b5121a232e 28659 ret->schemas_sax.startElementNs = startElementNsSplit;
pcercuei 0:03b5121a232e 28660 ret->schemas_sax.endElementNs = endElementNsSplit;
pcercuei 0:03b5121a232e 28661
pcercuei 0:03b5121a232e 28662 ret->user_data_ptr = user_data;
pcercuei 0:03b5121a232e 28663 ret->user_data = *user_data;
pcercuei 0:03b5121a232e 28664 *user_data = ret;
pcercuei 0:03b5121a232e 28665 }
pcercuei 0:03b5121a232e 28666
pcercuei 0:03b5121a232e 28667 /*
pcercuei 0:03b5121a232e 28668 * plug the pointers back.
pcercuei 0:03b5121a232e 28669 */
pcercuei 0:03b5121a232e 28670 *sax = &(ret->schemas_sax);
pcercuei 0:03b5121a232e 28671 ctxt->sax = *sax;
pcercuei 0:03b5121a232e 28672 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
pcercuei 0:03b5121a232e 28673 xmlSchemaPreRun(ctxt);
pcercuei 0:03b5121a232e 28674 return(ret);
pcercuei 0:03b5121a232e 28675 }
pcercuei 0:03b5121a232e 28676
pcercuei 0:03b5121a232e 28677 /**
pcercuei 0:03b5121a232e 28678 * xmlSchemaSAXUnplug:
pcercuei 0:03b5121a232e 28679 * @plug: a data structure returned by xmlSchemaSAXPlug
pcercuei 0:03b5121a232e 28680 *
pcercuei 0:03b5121a232e 28681 * Unplug a SAX based validation layer in a SAX parsing event flow.
pcercuei 0:03b5121a232e 28682 * The original pointers used in the call are restored.
pcercuei 0:03b5121a232e 28683 *
pcercuei 0:03b5121a232e 28684 * Returns 0 in case of success and -1 in case of failure.
pcercuei 0:03b5121a232e 28685 */
pcercuei 0:03b5121a232e 28686 int
pcercuei 0:03b5121a232e 28687 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
pcercuei 0:03b5121a232e 28688 {
pcercuei 0:03b5121a232e 28689 xmlSAXHandlerPtr *sax;
pcercuei 0:03b5121a232e 28690 void **user_data;
pcercuei 0:03b5121a232e 28691
pcercuei 0:03b5121a232e 28692 if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
pcercuei 0:03b5121a232e 28693 return(-1);
pcercuei 0:03b5121a232e 28694 plug->magic = 0;
pcercuei 0:03b5121a232e 28695
pcercuei 0:03b5121a232e 28696 xmlSchemaPostRun(plug->ctxt);
pcercuei 0:03b5121a232e 28697 /* restore the data */
pcercuei 0:03b5121a232e 28698 sax = plug->user_sax_ptr;
pcercuei 0:03b5121a232e 28699 *sax = plug->user_sax;
pcercuei 0:03b5121a232e 28700 if (plug->user_sax != NULL) {
pcercuei 0:03b5121a232e 28701 user_data = plug->user_data_ptr;
pcercuei 0:03b5121a232e 28702 *user_data = plug->user_data;
pcercuei 0:03b5121a232e 28703 }
pcercuei 0:03b5121a232e 28704
pcercuei 0:03b5121a232e 28705 /* free and return */
pcercuei 0:03b5121a232e 28706 xmlFree(plug);
pcercuei 0:03b5121a232e 28707 return(0);
pcercuei 0:03b5121a232e 28708 }
pcercuei 0:03b5121a232e 28709
pcercuei 0:03b5121a232e 28710 /**
pcercuei 0:03b5121a232e 28711 * xmlSchemaValidateSetLocator:
pcercuei 0:03b5121a232e 28712 * @vctxt: a schema validation context
pcercuei 0:03b5121a232e 28713 * @f: the locator function pointer
pcercuei 0:03b5121a232e 28714 * @ctxt: the locator context
pcercuei 0:03b5121a232e 28715 *
pcercuei 0:03b5121a232e 28716 * Allows to set a locator function to the validation context,
pcercuei 0:03b5121a232e 28717 * which will be used to provide file and line information since
pcercuei 0:03b5121a232e 28718 * those are not provided as part of the SAX validation flow
pcercuei 0:03b5121a232e 28719 * Setting @f to NULL disable the locator.
pcercuei 0:03b5121a232e 28720 */
pcercuei 0:03b5121a232e 28721
pcercuei 0:03b5121a232e 28722 void
pcercuei 0:03b5121a232e 28723 xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
pcercuei 0:03b5121a232e 28724 xmlSchemaValidityLocatorFunc f,
pcercuei 0:03b5121a232e 28725 void *ctxt)
pcercuei 0:03b5121a232e 28726 {
pcercuei 0:03b5121a232e 28727 if (vctxt == NULL) return;
pcercuei 0:03b5121a232e 28728 vctxt->locFunc = f;
pcercuei 0:03b5121a232e 28729 vctxt->locCtxt = ctxt;
pcercuei 0:03b5121a232e 28730 }
pcercuei 0:03b5121a232e 28731
pcercuei 0:03b5121a232e 28732 /**
pcercuei 0:03b5121a232e 28733 * xmlSchemaValidateStreamLocator:
pcercuei 0:03b5121a232e 28734 * @ctx: the xmlTextReaderPtr used
pcercuei 0:03b5121a232e 28735 * @file: returned file information
pcercuei 0:03b5121a232e 28736 * @line: returned line information
pcercuei 0:03b5121a232e 28737 *
pcercuei 0:03b5121a232e 28738 * Internal locator function for the readers
pcercuei 0:03b5121a232e 28739 *
pcercuei 0:03b5121a232e 28740 * Returns 0 in case the Schema validation could be (des)activated and
pcercuei 0:03b5121a232e 28741 * -1 in case of error.
pcercuei 0:03b5121a232e 28742 */
pcercuei 0:03b5121a232e 28743 static int
pcercuei 0:03b5121a232e 28744 xmlSchemaValidateStreamLocator(void *ctx, const char **file,
pcercuei 0:03b5121a232e 28745 unsigned long *line) {
pcercuei 0:03b5121a232e 28746 xmlParserCtxtPtr ctxt;
pcercuei 0:03b5121a232e 28747
pcercuei 0:03b5121a232e 28748 if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
pcercuei 0:03b5121a232e 28749 return(-1);
pcercuei 0:03b5121a232e 28750
pcercuei 0:03b5121a232e 28751 if (file != NULL)
pcercuei 0:03b5121a232e 28752 *file = NULL;
pcercuei 0:03b5121a232e 28753 if (line != NULL)
pcercuei 0:03b5121a232e 28754 *line = 0;
pcercuei 0:03b5121a232e 28755
pcercuei 0:03b5121a232e 28756 ctxt = (xmlParserCtxtPtr) ctx;
pcercuei 0:03b5121a232e 28757 if (ctxt->input != NULL) {
pcercuei 0:03b5121a232e 28758 if (file != NULL)
pcercuei 0:03b5121a232e 28759 *file = ctxt->input->filename;
pcercuei 0:03b5121a232e 28760 if (line != NULL)
pcercuei 0:03b5121a232e 28761 *line = ctxt->input->line;
pcercuei 0:03b5121a232e 28762 return(0);
pcercuei 0:03b5121a232e 28763 }
pcercuei 0:03b5121a232e 28764 return(-1);
pcercuei 0:03b5121a232e 28765 }
pcercuei 0:03b5121a232e 28766
pcercuei 0:03b5121a232e 28767 /**
pcercuei 0:03b5121a232e 28768 * xmlSchemaValidateStream:
pcercuei 0:03b5121a232e 28769 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 28770 * @input: the input to use for reading the data
pcercuei 0:03b5121a232e 28771 * @enc: an optional encoding information
pcercuei 0:03b5121a232e 28772 * @sax: a SAX handler for the resulting events
pcercuei 0:03b5121a232e 28773 * @user_data: the context to provide to the SAX handler.
pcercuei 0:03b5121a232e 28774 *
pcercuei 0:03b5121a232e 28775 * Validate an input based on a flow of SAX event from the parser
pcercuei 0:03b5121a232e 28776 * and forward the events to the @sax handler with the provided @user_data
pcercuei 0:03b5121a232e 28777 * the user provided @sax handler must be a SAX2 one.
pcercuei 0:03b5121a232e 28778 *
pcercuei 0:03b5121a232e 28779 * Returns 0 if the document is schemas valid, a positive error code
pcercuei 0:03b5121a232e 28780 * number otherwise and -1 in case of internal or API error.
pcercuei 0:03b5121a232e 28781 */
pcercuei 0:03b5121a232e 28782 int
pcercuei 0:03b5121a232e 28783 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
pcercuei 0:03b5121a232e 28784 xmlParserInputBufferPtr input, xmlCharEncoding enc,
pcercuei 0:03b5121a232e 28785 xmlSAXHandlerPtr sax, void *user_data)
pcercuei 0:03b5121a232e 28786 {
pcercuei 0:03b5121a232e 28787 xmlSchemaSAXPlugPtr plug = NULL;
pcercuei 0:03b5121a232e 28788 xmlSAXHandlerPtr old_sax = NULL;
pcercuei 0:03b5121a232e 28789 xmlParserCtxtPtr pctxt = NULL;
pcercuei 0:03b5121a232e 28790 xmlParserInputPtr inputStream = NULL;
pcercuei 0:03b5121a232e 28791 int ret;
pcercuei 0:03b5121a232e 28792
pcercuei 0:03b5121a232e 28793 if ((ctxt == NULL) || (input == NULL))
pcercuei 0:03b5121a232e 28794 return (-1);
pcercuei 0:03b5121a232e 28795
pcercuei 0:03b5121a232e 28796 /*
pcercuei 0:03b5121a232e 28797 * prepare the parser
pcercuei 0:03b5121a232e 28798 */
pcercuei 0:03b5121a232e 28799 pctxt = xmlNewParserCtxt();
pcercuei 0:03b5121a232e 28800 if (pctxt == NULL)
pcercuei 0:03b5121a232e 28801 return (-1);
pcercuei 0:03b5121a232e 28802 old_sax = pctxt->sax;
pcercuei 0:03b5121a232e 28803 pctxt->sax = sax;
pcercuei 0:03b5121a232e 28804 pctxt->userData = user_data;
pcercuei 0:03b5121a232e 28805 #if 0
pcercuei 0:03b5121a232e 28806 if (options)
pcercuei 0:03b5121a232e 28807 xmlCtxtUseOptions(pctxt, options);
pcercuei 0:03b5121a232e 28808 #endif
pcercuei 0:03b5121a232e 28809 pctxt->linenumbers = 1;
pcercuei 0:03b5121a232e 28810 xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
pcercuei 0:03b5121a232e 28811
pcercuei 0:03b5121a232e 28812 inputStream = xmlNewIOInputStream(pctxt, input, enc);;
pcercuei 0:03b5121a232e 28813 if (inputStream == NULL) {
pcercuei 0:03b5121a232e 28814 ret = -1;
pcercuei 0:03b5121a232e 28815 goto done;
pcercuei 0:03b5121a232e 28816 }
pcercuei 0:03b5121a232e 28817 inputPush(pctxt, inputStream);
pcercuei 0:03b5121a232e 28818 ctxt->parserCtxt = pctxt;
pcercuei 0:03b5121a232e 28819 ctxt->input = input;
pcercuei 0:03b5121a232e 28820
pcercuei 0:03b5121a232e 28821 /*
pcercuei 0:03b5121a232e 28822 * Plug the validation and launch the parsing
pcercuei 0:03b5121a232e 28823 */
pcercuei 0:03b5121a232e 28824 plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
pcercuei 0:03b5121a232e 28825 if (plug == NULL) {
pcercuei 0:03b5121a232e 28826 ret = -1;
pcercuei 0:03b5121a232e 28827 goto done;
pcercuei 0:03b5121a232e 28828 }
pcercuei 0:03b5121a232e 28829 ctxt->input = input;
pcercuei 0:03b5121a232e 28830 ctxt->enc = enc;
pcercuei 0:03b5121a232e 28831 ctxt->sax = pctxt->sax;
pcercuei 0:03b5121a232e 28832 ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
pcercuei 0:03b5121a232e 28833 ret = xmlSchemaVStart(ctxt);
pcercuei 0:03b5121a232e 28834
pcercuei 0:03b5121a232e 28835 if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
pcercuei 0:03b5121a232e 28836 ret = ctxt->parserCtxt->errNo;
pcercuei 0:03b5121a232e 28837 if (ret == 0)
pcercuei 0:03b5121a232e 28838 ret = 1;
pcercuei 0:03b5121a232e 28839 }
pcercuei 0:03b5121a232e 28840
pcercuei 0:03b5121a232e 28841 done:
pcercuei 0:03b5121a232e 28842 ctxt->parserCtxt = NULL;
pcercuei 0:03b5121a232e 28843 ctxt->sax = NULL;
pcercuei 0:03b5121a232e 28844 ctxt->input = NULL;
pcercuei 0:03b5121a232e 28845 if (plug != NULL) {
pcercuei 0:03b5121a232e 28846 xmlSchemaSAXUnplug(plug);
pcercuei 0:03b5121a232e 28847 }
pcercuei 0:03b5121a232e 28848 /* cleanup */
pcercuei 0:03b5121a232e 28849 if (pctxt != NULL) {
pcercuei 0:03b5121a232e 28850 pctxt->sax = old_sax;
pcercuei 0:03b5121a232e 28851 xmlFreeParserCtxt(pctxt);
pcercuei 0:03b5121a232e 28852 }
pcercuei 0:03b5121a232e 28853 return (ret);
pcercuei 0:03b5121a232e 28854 }
pcercuei 0:03b5121a232e 28855
pcercuei 0:03b5121a232e 28856 /**
pcercuei 0:03b5121a232e 28857 * xmlSchemaValidateFile:
pcercuei 0:03b5121a232e 28858 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 28859 * @filename: the URI of the instance
pcercuei 0:03b5121a232e 28860 * @options: a future set of options, currently unused
pcercuei 0:03b5121a232e 28861 *
pcercuei 0:03b5121a232e 28862 * Do a schemas validation of the given resource, it will use the
pcercuei 0:03b5121a232e 28863 * SAX streamable validation internally.
pcercuei 0:03b5121a232e 28864 *
pcercuei 0:03b5121a232e 28865 * Returns 0 if the document is valid, a positive error code
pcercuei 0:03b5121a232e 28866 * number otherwise and -1 in case of an internal or API error.
pcercuei 0:03b5121a232e 28867 */
pcercuei 0:03b5121a232e 28868 int
pcercuei 0:03b5121a232e 28869 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
pcercuei 0:03b5121a232e 28870 const char * filename,
pcercuei 0:03b5121a232e 28871 int options ATTRIBUTE_UNUSED)
pcercuei 0:03b5121a232e 28872 {
pcercuei 0:03b5121a232e 28873 int ret;
pcercuei 0:03b5121a232e 28874 xmlParserInputBufferPtr input;
pcercuei 0:03b5121a232e 28875
pcercuei 0:03b5121a232e 28876 if ((ctxt == NULL) || (filename == NULL))
pcercuei 0:03b5121a232e 28877 return (-1);
pcercuei 0:03b5121a232e 28878
pcercuei 0:03b5121a232e 28879 input = xmlParserInputBufferCreateFilename(filename,
pcercuei 0:03b5121a232e 28880 XML_CHAR_ENCODING_NONE);
pcercuei 0:03b5121a232e 28881 if (input == NULL)
pcercuei 0:03b5121a232e 28882 return (-1);
pcercuei 0:03b5121a232e 28883 ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
pcercuei 0:03b5121a232e 28884 NULL, NULL);
pcercuei 0:03b5121a232e 28885 return (ret);
pcercuei 0:03b5121a232e 28886 }
pcercuei 0:03b5121a232e 28887
pcercuei 0:03b5121a232e 28888 /**
pcercuei 0:03b5121a232e 28889 * xmlSchemaValidCtxtGetParserCtxt:
pcercuei 0:03b5121a232e 28890 * @ctxt: a schema validation context
pcercuei 0:03b5121a232e 28891 *
pcercuei 0:03b5121a232e 28892 * allow access to the parser context of the schema validation context
pcercuei 0:03b5121a232e 28893 *
pcercuei 0:03b5121a232e 28894 * Returns the parser context of the schema validation context or NULL
pcercuei 0:03b5121a232e 28895 * in case of error.
pcercuei 0:03b5121a232e 28896 */
pcercuei 0:03b5121a232e 28897 xmlParserCtxtPtr
pcercuei 0:03b5121a232e 28898 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
pcercuei 0:03b5121a232e 28899 {
pcercuei 0:03b5121a232e 28900 if (ctxt == NULL)
pcercuei 0:03b5121a232e 28901 return(NULL);
pcercuei 0:03b5121a232e 28902 return (ctxt->parserCtxt);
pcercuei 0:03b5121a232e 28903 }
pcercuei 0:03b5121a232e 28904
pcercuei 0:03b5121a232e 28905 #define bottom_xmlschemas
pcercuei 0:03b5121a232e 28906 #include "elfgcchack.h"
pcercuei 0:03b5121a232e 28907 #endif /* LIBXML_SCHEMAS_ENABLED */
pcercuei 0:03b5121a232e 28908