summaryrefslogtreecommitdiff
path: root/xmlschemas.c
diff options
context:
space:
mode:
Diffstat (limited to 'xmlschemas.c')
-rw-r--r--xmlschemas.c1871
1 files changed, 1228 insertions, 643 deletions
diff --git a/xmlschemas.c b/xmlschemas.c
index afa7010..76bf3fd 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -66,9 +66,9 @@
/* #define ENABLE_PARTICLE_RESTRICTION 1 */
-#define DUMP_CONTENT_MODEL
+/* #define ENABLE_REDEFINE */
-#define XML_SCHEMA_SAX_ENABLED
+#define DUMP_CONTENT_MODEL
#ifdef LIBXML_READER_ENABLED
/* #define XML_SCHEMA_READER_ENABLED */
@@ -100,8 +100,6 @@ static const xmlChar *xmlSchemaElemDesAttrDecl = (const xmlChar *)
"attribute decl.";
static const xmlChar *xmlSchemaElemDesAttrRef = (const xmlChar *)
"attribute use";
-static const xmlChar *xmlSchemaElemDesCT = (const xmlChar *)
- "complex type";
static const xmlChar *xmlSchemaElemModelGrDef = (const xmlChar *)
"model group";
#if 0
@@ -199,19 +197,52 @@ typedef xmlSchemaAssemble *xmlSchemaAssemblePtr;
typedef struct _xmlSchemaItemList xmlSchemaItemList;
typedef xmlSchemaItemList *xmlSchemaItemListPtr;
-
struct _xmlSchemaItemList {
void **items; /* used for dynamic addition of schemata */
int nbItems; /* used for dynamic addition of schemata */
int sizeItems; /* used for dynamic addition of schemata */
};
+/*
+typedef struct _xmlSchemaItemListChain xmlSchemaItemListChain;
+typedef xmlSchemaItemListChain xmlSchemaItemListChainPtr;
+struct _xmlSchemaItemListChain {
+ xmlSchemaItemListChainPtr next;
+ xmlSchemaItemListPtr list;
+}
+*/
+
+/*
+typedef struct _xmlSchemaItemListChain xmlSchemaItemListChain;
+typedef xmlSchemaItemListChain xmlSchemaItemListChainPtr;
+struct _xmlSchemaItemListChain {
+ xmlSchemaItemListChainPtr next;
+ xmlSchemaItemListPtr list;
+}
+*/
+
typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
struct _xmlSchemaAbstractCtxt {
int type;
};
+/**
+ * xmlSchemaContainer:
+ */
+typedef struct _xmlSchemaContainer xmlSchemaContainer;
+typedef xmlSchemaContainer *xmlSchemaContainerPtr;
+struct _xmlSchemaContainer {
+ xmlSchemaItemListPtr typeDefs;
+ xmlSchemaItemListPtr attrDecls;
+ xmlSchemaItemListPtr elemDecls;
+ xmlSchemaItemListPtr attrGroupDefs;
+ xmlSchemaItemListPtr modelGroupDefs;
+ xmlSchemaItemListPtr notationDecls;
+ xmlSchemaItemListPtr annotations;
+ xmlSchemaItemListPtr locals;
+};
+
#define XML_SCHEMA_CTXT_PARSER 1
#define XML_SCHEMA_CTXT_VALIDATOR 2
@@ -224,8 +255,8 @@ struct _xmlSchemaParserCtxt {
int nberrors;
xmlStructuredErrorFunc serror;
- xmlSchemaPtr topschema; /* The main schema */
- xmlHashTablePtr namespaces; /* Hash table of namespaces to schemas */
+ /* xmlSchemaPtr topschema; The main schema */
+ /* xmlHashTablePtr namespaces; Hash table of namespaces to schemas */
xmlSchemaPtr schema; /* The schema in use */
const xmlChar *container; /* the current element, group, ... */
@@ -258,6 +289,8 @@ struct _xmlSchemaParserCtxt {
int nbLocalImports;
xmlHashTablePtr substGroups;
int isS4S;
+ int isRedefine;
+ xmlSchemaContainerPtr compContainer;
};
#define XML_SCHEMAS_ATTR_UNKNOWN 1
@@ -289,6 +322,26 @@ struct _xmlSchemaBasicItem {
xmlSchemaTypeType type;
};
+#define XML_SCHEMA_SCHEMA_REF_IMPORT 1
+#define XML_SCHEMA_SCHEMA_REF_INCLUDE 2
+#define XML_SCHEMA_SCHEMA_REF_REDEFINE 3
+
+#define XML_SCHEMA_SCHEMA_REF_REL_CHILD 1
+#define XML_SCHEMA_SCHEMA_REF_REL_PARENT 2
+/**
+ * xmlSchemaSchemaRef:
+ *
+ * Used to create a graph of schema relationships.
+ */
+typedef struct _xmlSchemaSchemaRef xmlSchemaSchemaRef;
+typedef xmlSchemaSchemaRef *xmlSchemaSchemaRefPtr;
+struct _xmlSchemaSchemaRef {
+ xmlSchemaSchemaRefPtr next;
+ int type; /* E.g. XML_SCHEMA_SCHEMA_REF_IMPORT */
+ int relation;
+ xmlSchemaPtr schema;
+};
+
/**
* xmlSchemaAnnotItem:
*
@@ -462,6 +515,9 @@ typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
struct _xmlSchemaPSVIIDCNode {
xmlNodePtr node;
xmlSchemaPSVIIDCKeyPtr *keys;
+ int nodeLine;
+ int nodeQNameID;
+
};
/**
@@ -552,14 +608,17 @@ struct _xmlSchemaIDCMatcher {
* Holds information of an element node.
*/
struct _xmlSchemaNodeInfo {
- xmlNodePtr node;
int nodeType;
+ xmlNodePtr node;
+ int nodeLine;
const xmlChar *localName;
const xmlChar *nsName;
const xmlChar *value;
xmlSchemaValPtr val; /* the pre-computed value if any */
xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
+
int flags; /* combination of node info flags */
+
int valNeeded;
int normVal;
@@ -588,8 +647,9 @@ struct _xmlSchemaNodeInfo {
typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
struct _xmlSchemaAttrInfo {
- xmlNodePtr node;
int nodeType;
+ xmlNodePtr node;
+ int nodeLine;
const xmlChar *localName;
const xmlChar *nsName;
const xmlChar *value;
@@ -674,6 +734,7 @@ struct _xmlSchemaValidCtxt {
int sizeAttrInfos;
int skipDepth;
+ xmlSchemaItemListPtr nodeQNames;
};
/*
@@ -722,6 +783,11 @@ struct _xmlSchemaSubstGroup {
static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPtr schema,
xmlNodePtr node);
+#ifdef ENABLE_REDEFINE
+static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
+ xmlSchemaPtr schema,
+ xmlNodePtr node);
+#endif
static void
xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl,
xmlSchemaParserCtxtPtr ctxt, const xmlChar * name);
@@ -796,6 +862,16 @@ xmlSchemaCompTypeToString(xmlSchemaTypeType type)
return(BAD_CAST "model group (all)");
case XML_SCHEMA_TYPE_PARTICLE:
return(BAD_CAST "particle");
+ case XML_SCHEMA_TYPE_IDC_UNIQUE:
+ return(BAD_CAST "IDC (unique)");
+ case XML_SCHEMA_TYPE_IDC_KEY:
+ return(BAD_CAST "IDC (key)");
+ case XML_SCHEMA_TYPE_IDC_KEYREF:
+ return(BAD_CAST "IDC (keyref)");
+ case XML_SCHEMA_TYPE_ANY:
+ return(BAD_CAST "wildcard (any)");
+ case XML_SCHEMA_EXTRA_QNAMEREF:
+ return(BAD_CAST "[helper component] QName reference");
default:
return(BAD_CAST "Not a schema component");
}
@@ -1560,9 +1636,10 @@ xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
* Handle a validation error
*/
static void
-xmlSchemaErr3(xmlSchemaAbstractCtxtPtr ctxt,
- int error, xmlNodePtr node, const char *msg,
- const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
+xmlSchemaErr3Line(xmlSchemaAbstractCtxtPtr ctxt,
+ int error, xmlNodePtr node, int line, const char *msg,
+ const xmlChar *str1, const xmlChar *str2,
+ const xmlChar *str3)
{
xmlStructuredErrorFunc schannel = NULL;
xmlGenericErrorFunc channel = NULL;
@@ -1571,7 +1648,6 @@ xmlSchemaErr3(xmlSchemaAbstractCtxtPtr ctxt,
if (ctxt != NULL) {
if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
- int line = 0;
const char *file = NULL;
vctxt->nberrors++;
@@ -1579,15 +1655,41 @@ xmlSchemaErr3(xmlSchemaAbstractCtxtPtr ctxt,
channel = vctxt->error;
schannel = vctxt->serror;
data = vctxt->userData;
- if ((node == NULL) && (vctxt->depth >= 0) &&
- (vctxt->inode != NULL)) {
- node = vctxt->inode->node;
- }
- if ((node == NULL) && (vctxt->parserCtxt != NULL) &&
- (vctxt->parserCtxt->input != NULL)) {
- file = vctxt->parserCtxt->input->filename;
- line = vctxt->parserCtxt->input->line;
- }
+
+ /*
+ * Error node. If we specify a line number, then
+ * do not channel any node to the error function.
+ */
+ if (line == 0) {
+ if ((node == NULL) &&
+ (vctxt->depth >= 0) &&
+ (vctxt->inode != NULL)) {
+ node = vctxt->inode->node;
+ }
+ /*
+ * Get filename and line if no node-tree.
+ */
+ if ((node == NULL) &&
+ (vctxt->parserCtxt != NULL) &&
+ (vctxt->parserCtxt->input != NULL)) {
+ file = vctxt->parserCtxt->input->filename;
+ line = vctxt->parserCtxt->input->line;
+ }
+ } else {
+ /*
+ * Override the given node's (if any) position
+ * and channel only the given line number.
+ */
+ node = NULL;
+ /*
+ * Get filename.
+ */
+ if (vctxt->doc != NULL)
+ file = (const char *) vctxt->doc->URL;
+ else if ((vctxt->parserCtxt != NULL) &&
+ (vctxt->parserCtxt->input != NULL))
+ file = vctxt->parserCtxt->input->filename;
+ }
__xmlRaiseError(schannel, channel, data, ctxt,
node, XML_FROM_SCHEMASV,
error, XML_ERR_ERROR, file, line,
@@ -1613,6 +1715,26 @@ xmlSchemaErr3(xmlSchemaAbstractCtxtPtr ctxt,
}
}
+/**
+ * xmlSchemaErr3:
+ * @ctxt: the validation context
+ * @node: the context node
+ * @error: the error code
+ * @msg: the error message
+ * @str1: extra data
+ * @str2: extra data
+ * @str3: extra data
+ *
+ * Handle a validation error
+ */
+static void
+xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
+ int error, xmlNodePtr node, const char *msg,
+ const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
+{
+ xmlSchemaErr3Line(actxt, error, node, 0, msg, str1, str2, str3);
+}
+
static void
xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
int error, xmlNodePtr node, const char *msg,
@@ -1699,9 +1821,11 @@ xmlSchemaFormatNodeForError(xmlChar ** msg,
}
static void
-xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
+xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
const char *funcName,
- const char *message)
+ const char *message,
+ const xmlChar *str1,
+ const xmlChar *str2)
{
xmlChar *msg = NULL;
@@ -1713,16 +1837,35 @@ xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
- (const char *) msg, NULL, NULL);
+ (const char *) msg, str1, str2);
- else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
+ else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
- (const char *) msg, NULL, NULL);
+ (const char *) msg, str1, str2);
FREE_AND_NULL(msg)
}
static void
+xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
+ const char *funcName,
+ const char *message)
+{
+ xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
+}
+
+static void
+xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
+ const char *funcName,
+ const char *message,
+ const xmlChar *str1,
+ const xmlChar *str2)
+{
+ xmlSchemaInternalErr2((xmlSchemaAbstractCtxtPtr) pctxt, funcName, message,
+ str1, str2);
+}
+
+static void
xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
xmlParserErrors error,
xmlNodePtr node,
@@ -1741,6 +1884,30 @@ xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
FREE_AND_NULL(msg)
}
+static void
+xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
+ xmlParserErrors error,
+ xmlSchemaPSVIIDCNodePtr idcNode,
+ xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
+ const char *message,
+ const xmlChar *str1,
+ const xmlChar *str2)
+{
+ xmlChar *msg = NULL, *qname = NULL;
+
+ msg = xmlStrdup(BAD_CAST "Element '%s': ");
+ msg = xmlStrcat(msg, (const xmlChar *) message);
+ msg = xmlStrcat(msg, BAD_CAST ".\n");
+ xmlSchemaErr3Line((xmlSchemaAbstractCtxtPtr) vctxt,
+ error, NULL, idcNode->nodeLine, (const char *) msg,
+ xmlSchemaFormatQName(&qname,
+ vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
+ vctxt->nodeQNames->items[idcNode->nodeQNameID]),
+ str1, str2);
+ FREE_AND_NULL(qname);
+ FREE_AND_NULL(msg);
+}
+
static int
xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
xmlNodePtr node)
@@ -1879,7 +2046,7 @@ xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
xmlChar *str = NULL, *msg = NULL;
xmlChar *localName, *nsName;
const xmlChar *cur, *end;
- int i;
+ int i, is_not;
xmlSchemaFormatNodeForError(&msg, actxt, node);
msg = xmlStrcat(msg, (const xmlChar *) message);
@@ -1898,6 +2065,16 @@ xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
for (i = 0; i < nbval + nbneg; i++) {
cur = values[i];
+ if (cur == NULL)
+ continue;
+ if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
+ (cur[3] == ' ')) {
+ is_not = 1;
+ cur += 4;
+ str = xmlStrcat(str, BAD_CAST "##other");
+ } else {
+ is_not = 0;
+ }
/*
* Get the local name.
*/
@@ -2088,6 +2265,7 @@ xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
#define VERROR_INT(func, msg) xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) vctxt, func, msg);
#define PERROR_INT(func, msg) xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) pctxt, func, msg);
+#define PERROR_INT2(func, msg) xmlSchemaInternalErr((xmlSchemaAbstractCtxtPtr) ctxt, func, msg);
#define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
@@ -2537,8 +2715,10 @@ xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
else
xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
} else {
+ msg = xmlStrcat(msg, BAD_CAST message);
+ msg = xmlStrcat(msg, BAD_CAST ".\n");
xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
- "%s%s.\n", msg, BAD_CAST message, str1, str2, NULL);
+ (const char*) msg, str1, str2, NULL, NULL, NULL);
}
/* Cleanup. */
FREE_AND_NULL(msg)
@@ -2711,7 +2891,7 @@ xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
}
static xmlSchemaItemListPtr
-xmlSchemaNewItemList(void)
+xmlSchemaItemListCreate(void)
{
xmlSchemaItemListPtr ret;
@@ -2725,6 +2905,98 @@ xmlSchemaNewItemList(void)
return (ret);
}
+static void
+xmlSchemaItemListClear(xmlSchemaItemListPtr list)
+{
+ if (list->items != NULL) {
+ xmlFree(list->items);
+ list->items = NULL;
+ }
+ list->nbItems = 0;
+ list->sizeItems = 0;
+}
+
+static int
+xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
+{
+ if (list->items == NULL) {
+ list->items = (void **) xmlMalloc(
+ 20 * sizeof(void *));
+ if (list->items == NULL) {
+ xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
+ return(-1);
+ }
+ list->sizeItems = 20;
+ } else if (list->sizeItems <= list->nbItems) {
+ list->sizeItems *= 2;
+ list->items = (void **) xmlRealloc(list->items,
+ list->sizeItems * sizeof(void *));
+ if (list->items == NULL) {
+ xmlSchemaPErrMemory(NULL, "growing item list", NULL);
+ list->sizeItems = 0;
+ return(-1);
+ }
+ }
+ /* ((xmlSchemaBasicItemPtr *) list->items)[list->nbItems++] = (void *) item; */
+ list->items[list->nbItems++] = item;
+ return(0);
+}
+
+/**
+ * xmlSchemaItemListFree:
+ * @annot: a schema type structure
+ *
+ * Deallocate a annotation structure
+ */
+static void
+xmlSchemaItemListFree(xmlSchemaItemListPtr list)
+{
+ if (list == NULL)
+ return;
+ if (list->items != NULL)
+ xmlFree(list->items);
+ xmlFree(list);
+}
+
+static xmlSchemaContainerPtr
+xmlSchemaContainerCreate(void)
+{
+ xmlSchemaContainerPtr ret;
+
+ ret = (xmlSchemaContainerPtr) xmlMalloc(sizeof(xmlSchemaContainer));
+ if (ret == NULL) {
+ xmlSchemaPErrMemory(NULL, "allocating component container",
+ NULL);
+ return(NULL);
+ }
+ memset(ret, 0, sizeof(xmlSchemaContainer));
+ return(ret);
+}
+
+static void
+xmlSchemaContainerFree(xmlSchemaContainerPtr cont)
+{
+ if (cont == NULL)
+ return;
+ if (cont->typeDefs != NULL)
+ xmlSchemaItemListFree(cont->typeDefs);
+ if (cont->attrDecls != NULL)
+ xmlSchemaItemListFree(cont->attrDecls);
+ if (cont->elemDecls != NULL)
+ xmlSchemaItemListFree(cont->elemDecls);
+ if (cont->attrGroupDefs != NULL)
+ xmlSchemaItemListFree(cont->attrGroupDefs);
+ if (cont->modelGroupDefs != NULL)
+ xmlSchemaItemListFree(cont->modelGroupDefs);
+ if (cont->notationDecls != NULL)
+ xmlSchemaItemListFree(cont->notationDecls);
+ if (cont->annotations != NULL)
+ xmlSchemaItemListFree(cont->annotations);
+ if (cont->locals != NULL)
+ xmlSchemaItemListFree(cont->locals);
+ xmlFree(cont);
+}
+
/**
* xmlSchemaAddElementSubstitutionMember:
* @pctxt: a schema parser context
@@ -2763,7 +3035,7 @@ xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
NULL);
return (-1);
}
- substGroup->members = xmlSchemaNewItemList();
+ substGroup->members = xmlSchemaItemListCreate();
if (substGroup->members == NULL) {
xmlFree(substGroup);
return (-1);
@@ -2835,22 +3107,6 @@ xmlSchemaGetElementSubstitutionGroup(xmlSchemaParserCtxtPtr pctxt,
}
/**
- * xmlSchemaFreeItemList:
- * @annot: a schema type structure
- *
- * Deallocate a annotation structure
- */
-static void
-xmlSchemaFreeItemList(xmlSchemaItemListPtr list)
-{
- if (list == NULL)
- return;
- if (list->items != NULL)
- xmlFree(list->items);
- xmlFree(list);
-}
-
-/**
* xmlSchemaFreeAnnot:
* @annot: a schema type structure
*
@@ -2861,7 +3117,17 @@ xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
{
if (annot == NULL)
return;
- xmlFree(annot);
+ if (annot->next == NULL) {
+ xmlFree(annot);
+ } else {
+ xmlSchemaAnnotPtr prev;
+
+ do {
+ prev = annot;
+ annot = annot->next;
+ xmlFree(prev);
+ } while (annot != NULL);
+ }
}
/**
@@ -3043,7 +3309,7 @@ xmlSchemaFreeSubstGroup(xmlSchemaSubstGroupPtr item)
if (item == NULL)
return;
if (item->members != NULL)
- xmlSchemaFreeItemList(item->members);
+ xmlSchemaItemListFree(item->members);
xmlFree(item);
}
@@ -3051,39 +3317,15 @@ static int
xmlSchemaAddVolatile(xmlSchemaPtr schema,
xmlSchemaBasicItemPtr item)
{
- xmlSchemaItemListPtr list;
-
if (schema->volatiles == NULL) {
- schema->volatiles = (void *) xmlSchemaNewItemList();
+ schema->volatiles = (void *) xmlSchemaItemListCreate();
if (schema->volatiles == NULL) {
xmlSchemaPErrMemory(NULL,
"allocating list of volatiles", NULL);
return (-1);
}
}
- list = (xmlSchemaItemListPtr) schema->volatiles;
- if (list->items == NULL) {
- list->items = (void **) xmlMalloc(
- 20 * sizeof(xmlSchemaBasicItemPtr));
- if (list->items == NULL) {
- xmlSchemaPErrMemory(NULL,
- "allocating new volatile item buffer", NULL);
- return (-1);
- }
- list->sizeItems = 20;
- } else if (list->sizeItems <= list->nbItems) {
- list->sizeItems *= 2;
- list->items = (void **) xmlRealloc(list->items,
- list->sizeItems * sizeof(xmlSchemaTypePtr));
- if (list->items == NULL) {
- xmlSchemaPErrMemory(NULL,
- "growing volatile item buffer", NULL);
- list->sizeItems = 0;
- return (-1);
- }
- }
- ((xmlSchemaBasicItemPtr *) list->items)[list->nbItems++] = (void *) item;
- return (0);
+ return(xmlSchemaItemListAdd((xmlSchemaItemListPtr) schema->volatiles, item));
}
/**
@@ -3218,6 +3460,9 @@ xmlSchemaFreeType(xmlSchemaTypePtr type)
}
}
if (type->type != XML_SCHEMA_TYPE_BASIC) {
+ /*
+ * TODO: Why is this restricted to non built-in types?
+ */
if (type->attributeUses != NULL)
xmlSchemaFreeAttributeUseList(type->attributeUses);
}
@@ -3333,7 +3578,7 @@ xmlSchemaFreeVolatiles(xmlSchemaPtr schema)
}
}
}
- xmlSchemaFreeItemList(list);
+ xmlSchemaItemListFree(list);
}
}
/**
@@ -3894,35 +4139,19 @@ xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
*/
static xmlSchemaElementPtr
xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
- const xmlChar * namespace)
+ const xmlChar * nsName)
{
xmlSchemaElementPtr ret;
if ((name == NULL) || (schema == NULL))
return (NULL);
- ret = xmlHashLookup2(schema->elemDecl, name, namespace);
+ ret = xmlHashLookup2(schema->elemDecl, name, nsName);
if ((ret != NULL) &&
(ret->flags & XML_SCHEMAS_ELEM_GLOBAL)) {
return (ret);
} else
ret = NULL;
- /*
- * This one was removed, since top level element declarations have
- * the target namespace specified in targetNamespace of the <schema>
- * information element, even if elementFormDefault is "unqualified".
- */
-
- /* else if ((schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0) {
- if (xmlStrEqual(namespace, schema->targetNamespace))
- ret = xmlHashLookup2(schema->elemDecl, name, NULL);
- else
- ret = xmlHashLookup2(schema->elemDecl, name, namespace);
- if ((ret != NULL) &&
- ((level == 0) || (ret->flags & XML_SCHEMAS_ELEM_TOPLEVEL))) {
- return (ret);
- }
- */
/*
* Removed since imported components will be hold by the main schema only.
@@ -3963,18 +4192,25 @@ xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
*/
static xmlSchemaTypePtr
xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
- const xmlChar * namespace)
+ const xmlChar * nsName)
{
xmlSchemaTypePtr ret;
if (name == NULL)
return (NULL);
if (schema != NULL) {
- ret = xmlHashLookup2(schema->typeDecl, name, namespace);
- if ((ret != NULL) && (ret->flags & XML_SCHEMAS_TYPE_GLOBAL))
+ ret = xmlHashLookup2(schema->typeDecl, name, nsName);
+ if ((ret != NULL) && (ret->flags & XML_SCHEMAS_TYPE_GLOBAL)) {
+ if (ret->redef != NULL) {
+ /*
+ * Return the last redefinition.
+ */
+ return(ret->redef);
+ }
return (ret);
+ }
}
- ret = xmlSchemaGetPredefinedType(name, namespace);
+ ret = xmlSchemaGetPredefinedType(name, nsName);
if (ret != NULL)
return (ret);
/*
@@ -3994,14 +4230,14 @@ xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
*/
#ifdef DEBUG
if (ret == NULL) {
- if (namespace == NULL)
+ if (nsName == NULL)
fprintf(stderr, "Unable to lookup type %s", name);
else
fprintf(stderr, "Unable to lookup type %s:%s", name,
- namespace);
+ nsName);
}
#endif
- return (ret);
+ return (NULL);
}
/**
@@ -4548,8 +4784,8 @@ xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*/
static xmlSchemaTypePtr
xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- const xmlChar * name, const xmlChar * namespace,
- xmlNodePtr node)
+ const xmlChar * name, const xmlChar * nsName,
+ xmlNodePtr node, int topLevel)
{
xmlSchemaTypePtr ret = NULL;
int val;
@@ -4557,12 +4793,6 @@ xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
return (NULL);
-#ifdef DEBUG
- fprintf(stderr, "Adding type %s\n", name);
- if (namespace != NULL)
- fprintf(stderr, " target namespace %s\n", namespace);
-#endif
-
if (schema->typeDecl == NULL)
schema->typeDecl = xmlHashCreateDict(10, ctxt->dict);
if (schema->typeDecl == NULL)
@@ -4576,25 +4806,37 @@ xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
memset(ret, 0, sizeof(xmlSchemaType));
ret->name = xmlDictLookup(ctxt->dict, name, -1);
ret->redef = NULL;
- val = xmlHashAddEntry2(schema->typeDecl, name, namespace, ret);
+ val = xmlHashAddEntry2(schema->typeDecl, name, nsName, ret);
if (val != 0) {
- if (ctxt->includes == 0) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_REDEFINED_TYPE,
- NULL, NULL, node,
- "A global type definition with the name '%s' does already exist", name);
+ if (! ctxt->isRedefine) {
+ xmlChar *str = NULL;
+ if (topLevel) {
+ xmlSchemaPCustomErr(ctxt,
+ XML_SCHEMAP_REDEFINED_TYPE,
+ NULL, NULL, node,
+ "A global type definition with the name '%s' does "
+ "already exist",
+ xmlSchemaFormatQName(&str, nsName, name));
+ } else {
+ xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
+ NULL, NULL, node, "Internal error: xmlSchemaAddType, "
+ "local type '%s' has a duplicate",
+ xmlSchemaFormatQName(&str, nsName, name));
+ }
xmlFree(ret);
+ FREE_AND_NULL(str);
return (NULL);
} else {
xmlSchemaTypePtr prev;
- prev = xmlHashLookup2(schema->typeDecl, name, namespace);
+ /*
+ * REDEFINE: Add a redefinition.
+ */
+ TODO
+ prev = xmlHashLookup2(schema->typeDecl, name, nsName);
if (prev == NULL) {
- xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
- XML_ERR_INTERNAL_ERROR,
- "Internal error: xmlSchemaAddType, on type "
- "'%s'.\n",
- name, NULL);
+ PERROR_INT2("xmlSchemaAddType", "hash list didn't return "
+ "a type component, but should");
xmlFree(ret);
return (NULL);
}
@@ -4977,7 +5219,7 @@ xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
return (-1);
if (!strchr((char *) value, ':')) {
- ns = xmlSearchNs(attr->doc, attr->parent, 0);
+ ns = xmlSearchNs(attr->doc, attr->parent, NULL);
if (ns)
*uri = xmlDictLookup(ctxt->dict, ns->href, -1);
else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
@@ -8048,6 +8290,7 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr child = NULL;
const xmlChar *attrValue = NULL;
xmlAttrPtr attr;
+ int hasRestriction = 0;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
@@ -8071,6 +8314,18 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (ctxt->isS4S) {
xmlSchemaTypePtr biType;
+ if (ctxt->isRedefine) {
+ /*
+ * REDEFINE: Disallow redefinition of built-in-types.
+ * TODO: It seems that the spec does not say anything
+ * about this case.
+ */
+ xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
+ NULL, NULL, node,
+ "Redefinition of built-in simple types is not "
+ "supported", NULL);
+ return(NULL);
+ }
biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
if (biType != NULL)
return (biType);
@@ -8085,7 +8340,8 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
* Parse as local simple type definition.
*/
snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf, NULL, node);
+ type = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf, NULL,
+ node, 0);
if (type == NULL)
return (NULL);
type->node = node;
@@ -8115,7 +8371,8 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*
* Note that attrValue is the value of the attribute "name" here.
*/
- type = xmlSchemaAddType(ctxt, schema, attrValue, schema->targetNamespace, node);
+ type = xmlSchemaAddType(ctxt, schema, attrValue,
+ schema->targetNamespace, node, 1);
if (type == NULL)
return (NULL);
type->node = node;
@@ -8186,9 +8443,10 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
NULL, type, node, child, NULL,
"(annotation?, (restriction | list | union))");
- } else if (IS_SCHEMA(child, "restriction")) {
+ } else if (IS_SCHEMA(child, "restriction")) {
xmlSchemaParseRestriction(ctxt, schema, child,
- XML_SCHEMA_TYPE_SIMPLE);
+ XML_SCHEMA_TYPE_SIMPLE);
+ hasRestriction = 1;
child = child->next;
} else if (IS_SCHEMA(child, "list")) {
xmlSchemaParseList(ctxt, schema, child);
@@ -8202,9 +8460,21 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
NULL, type, node, child, NULL,
"(annotation?, (restriction | list | union))");
}
+ /*
+ * REDEFINE: SPEC src-redefine (5)
+ * "Within the [children], each <simpleType> must have a
+ * <restriction> among its [children] ... the ·actual value· of whose
+ * base [attribute] must be the same as the ·actual value· of its own
+ * name attribute plus target namespace;"
+ */
+ if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
+ xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
+ NULL, NULL, node, "This is a redefinition, thus the "
+ "<simpleType> must have a <restriction> child", NULL);
+ }
+
ctxt->parentItem = oldParentItem;
ctxt->ctxtType = oldCtxtType;
-
return (type);
}
@@ -8476,73 +8746,6 @@ xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
}
-/**
- * xmlSchemaImportSchema
- *
- * @ctxt: a schema validation context
- * @schemaLocation: an URI defining where to find the imported schema
- *
- * import a XML schema
- * *WARNING* this interface is highly subject to change
- *
- * Returns -1 in case of error and 1 in case of success.
- */
-#if 0
-static xmlSchemaImportPtr
-xmlSchemaImportSchema(xmlSchemaParserCtxtPtr ctxt,
- const xmlChar *schemaLocation)
-{
- xmlSchemaImportPtr import;
- xmlSchemaParserCtxtPtr newctxt;
-
- newctxt = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
- if (newctxt == NULL) {
- xmlSchemaPErrMemory(ctxt, "allocating schema parser context",
- NULL);
- return (NULL);
- }
- memset(newctxt, 0, sizeof(xmlSchemaParserCtxt));
- /* Keep the same dictionnary for parsing, really */
- xmlDictReference(ctxt->dict);
- newctxt->dict = ctxt->dict;
- newctxt->includes = 0;
- newctxt->URL = xmlDictLookup(newctxt->dict, schemaLocation, -1);
-
- xmlSchemaSetParserErrors(newctxt, ctxt->error, ctxt->warning,
- ctxt->userData);
-
- import = (xmlSchemaImport*) xmlMalloc(sizeof(xmlSchemaImport));
- if (import == NULL) {
- xmlSchemaPErrMemory(NULL, "allocating imported schema",
- NULL);
- xmlSchemaFreeParserCtxt(newctxt);
- return (NULL);
- }
-
- memset(import, 0, sizeof(xmlSchemaImport));
- import->schemaLocation = xmlDictLookup(ctxt->dict, schemaLocation, -1);
- import->schema = xmlSchemaParse(newctxt);
-
- if (import->schema == NULL) {
- /* FIXME use another error enum here ? */
- xmlSchemaPErr(ctxt, NULL, XML_SCHEMAP_INTERNAL,
- "Failed to import schema from location \"%s\".\n",
- schemaLocation, NULL);
-
- xmlSchemaFreeParserCtxt(newctxt);
- /* The schemaLocation is held by the dictionary.
- if (import->schemaLocation != NULL)
- xmlFree((xmlChar *)import->schemaLocation);
- */
- xmlFree(import);
- return NULL;
- }
-
- xmlSchemaFreeParserCtxt(newctxt);
- return import;
-}
-#endif
-
static void
xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
{
@@ -8679,7 +8882,11 @@ xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaParseInclude(ctxt, schema, child);
ctxt->includes--;
} else if (IS_SCHEMA(child, "redefine")) {
+#ifdef ENABLE_REDEFINE
+ xmlSchemaParseRedefine(ctxt, schema, child);
+#else
TODO
+#endif
}
child = child->next;
}
@@ -8756,6 +8963,49 @@ xmlSchemaAddImport(xmlSchemaParserCtxtPtr ctxt,
return (ret);
}
+#ifdef ENABLE_REDEFINE
+static xmlSchemaSchemaRefPtr
+xmlSchemaSchemaRefCreate(void)
+{
+ xmlSchemaSchemaRefPtr ret;
+
+ ret = (xmlSchemaSchemaRefPtr) xmlMalloc(sizeof(xmlSchemaSchemaRef));
+ if (ret == NULL) {
+ xmlSchemaPErrMemory(NULL, "allocating schema reference", NULL);
+ return(NULL);
+ }
+ memset(ret, 0, sizeof(xmlSchemaSchemaRef));
+ return(ret);
+}
+
+static void
+xmlSchemaSchemaRefFree(xmlSchemaSchemaRefPtr ref)
+{
+ xmlFree(ref);
+}
+#endif
+
+static xmlSchemaParserCtxtPtr
+xmlSchemaParserCtxtCreate(void)
+{
+ xmlSchemaParserCtxtPtr ret;
+
+ ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
+ if (ret == NULL) {
+ xmlSchemaPErrMemory(NULL, "allocating schema parser context",
+ NULL);
+ return (NULL);
+ }
+ memset(ret, 0, sizeof(xmlSchemaParserCtxt));
+ ret->type = XML_SCHEMA_CTXT_PARSER;
+ ret->compContainer = xmlSchemaContainerCreate();
+ if (ret->compContainer == NULL) {
+ xmlSchemaFreeParserCtxt(ret);
+ return(NULL);
+ }
+ return(ret);
+}
+
/**
* xmlSchemaNewParserCtxtUseDict:
* @URL: the location of the schema
@@ -8770,18 +9020,10 @@ static xmlSchemaParserCtxtPtr
xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
{
xmlSchemaParserCtxtPtr ret;
- /*
- if (URL == NULL)
- return (NULL);
- */
- ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
- if (ret == NULL) {
- xmlSchemaPErrMemory(NULL, "allocating schema parser context",
- NULL);
+ ret = xmlSchemaParserCtxtCreate();
+ if (ret == NULL)
return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaParserCtxt));
ret->dict = dict;
xmlDictReference(dict);
if (URL != NULL)
@@ -9053,14 +9295,17 @@ xmlSchemaParseForImpInc(xmlSchemaParserCtxtPtr pctxt,
oldURL = pctxt->URL;
/* TODO: Is using the doc->URL here correct? */
pctxt->URL = node->doc->URL;
+
oldLocImps = pctxt->localImports;
pctxt->localImports = NULL;
oldNumLocImps = pctxt->nbLocalImports;
pctxt->nbLocalImports = 0;
oldSizeLocImps = pctxt->sizeLocalImports;
pctxt->sizeLocalImports = 0;
+
oldFlags = schema->flags;
oldIsS4S = pctxt->isS4S;
+
xmlSchemaClearSchemaDefaults(schema);
oldTNS = schema->targetNamespace;
schema->targetNamespace = targetNamespace;
@@ -9103,7 +9348,7 @@ xmlSchemaParseForImpInc(xmlSchemaParserCtxtPtr pctxt,
* not valid and -1 in case of an internal error.
*/
static int
-xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
xmlNodePtr node)
{
xmlNodePtr child;
@@ -9114,7 +9359,7 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlDocPtr doc;
int ret = 0;
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+ if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
return (-1);
/*
@@ -9126,12 +9371,12 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
- xmlSchemaPIllegalAttrErr(ctxt,
+ xmlSchemaPIllegalAttrErr(pctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
NULL, NULL, attr);
}
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
- xmlSchemaPIllegalAttrErr(ctxt,
+ xmlSchemaPIllegalAttrErr(pctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
NULL, NULL, attr);
}
@@ -9140,26 +9385,26 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
/*
* Extract and validate attributes.
*/
- if (xmlSchemaPValAttr(ctxt, NULL, NULL, node,
+ if (xmlSchemaPValAttr(pctxt, NULL, NULL, node,
"namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
&namespaceName) != 0) {
- xmlSchemaPSimpleTypeErr(ctxt,
- XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI,
+ xmlSchemaPSimpleTypeErr(pctxt,
+ XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
NULL, node,
xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
NULL, namespaceName, NULL, NULL, NULL);
- return (XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI);
+ return (pctxt->err);
}
- if (xmlSchemaPValAttr(ctxt, NULL, NULL, node,
+ if (xmlSchemaPValAttr(pctxt, NULL, NULL, node,
"schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
&schemaLocation) != 0) {
- xmlSchemaPSimpleTypeErr(ctxt,
- XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI,
+ xmlSchemaPSimpleTypeErr(pctxt,
+ XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
NULL, node,
xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
NULL, namespaceName, NULL, NULL, NULL);
- return (XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI);
+ return (pctxt->err);
}
/*
* And now for the children...
@@ -9173,8 +9418,8 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
child = child->next;
}
if (child != NULL) {
- xmlSchemaPContentErr(ctxt,
- XML_SCHEMAP_UNKNOWN_IMPORT_CHILD,
+ xmlSchemaPContentErr(pctxt,
+ XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
NULL, NULL, node, child, NULL,
"(annotation?)");
}
@@ -9188,13 +9433,13 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
* targetNamespace [attribute].
*/
if (xmlStrEqual(schema->targetNamespace, namespaceName)) {
- xmlSchemaPCustomErr(ctxt,
+ xmlSchemaPCustomErr(pctxt,
XML_SCHEMAP_SRC_IMPORT_1_1,
NULL, NULL, node,
"The value of the attribute 'namespace' must not match "
"the target namespace '%s' of the importing schema",
schema->targetNamespace);
- return (XML_SCHEMAP_SRC_IMPORT_1_1);
+ return (pctxt->err);
}
} else {
/*
@@ -9202,34 +9447,36 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
* <schema> must have a targetNamespace [attribute].
*/
if (schema->targetNamespace == NULL) {
- xmlSchemaPCustomErr(ctxt,
+ xmlSchemaPCustomErr(pctxt,
XML_SCHEMAP_SRC_IMPORT_1_2,
NULL, NULL, node,
"The attribute 'namespace' must be existent if "
"the importing schema has no target namespace",
NULL);
- return (XML_SCHEMAP_SRC_IMPORT_1_2);
+ return (pctxt->err);
}
}
/*
* Add the namespace to the list of locally imported namespace.
+ * TODO: This could be removed if the schema-graph is ready. I.e.
+ * use the graph for this info instead.
*/
- if (ctxt->localImports == NULL) {
- ctxt->localImports = (const xmlChar **) xmlMalloc(10 *
+ if (pctxt->localImports == NULL) {
+ pctxt->localImports = (const xmlChar **) xmlMalloc(10 *
sizeof(const xmlChar*));
- ctxt->sizeLocalImports = 10;
- ctxt->nbLocalImports = 0;
- } else if (ctxt->sizeLocalImports <= ctxt->nbLocalImports) {
- ctxt->sizeLocalImports *= 2;
- ctxt->localImports = (const xmlChar **) xmlRealloc(
- (xmlChar **) ctxt->localImports,
- ctxt->sizeLocalImports * sizeof(const xmlChar*));
+ pctxt->sizeLocalImports = 10;
+ pctxt->nbLocalImports = 0;
+ } else if (pctxt->sizeLocalImports <= pctxt->nbLocalImports) {
+ pctxt->sizeLocalImports *= 2;
+ pctxt->localImports = (const xmlChar **) xmlRealloc(
+ (xmlChar **) pctxt->localImports,
+ pctxt->sizeLocalImports * sizeof(const xmlChar*));
}
- ctxt->localImports[ctxt->nbLocalImports++] = namespaceName;
+ pctxt->localImports[pctxt->nbLocalImports++] = namespaceName;
/*
* Locate and aquire the schema document.
*/
- ret = xmlSchemaAcquireSchemaDoc((xmlSchemaAbstractCtxtPtr) ctxt,
+ ret = xmlSchemaAcquireSchemaDoc((xmlSchemaAbstractCtxtPtr) pctxt,
schema, node, namespaceName,
schemaLocation, &doc, &targetNamespace, 0);
if (ret != 0) {
@@ -9237,7 +9484,7 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlFreeDoc(doc);
return (ret);
} else if (doc != NULL) {
- xmlSchemaParseForImpInc(ctxt, schema, targetNamespace,
+ xmlSchemaParseForImpInc(pctxt, schema, targetNamespace,
xmlDocGetRootElement(doc));
}
@@ -9245,120 +9492,31 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
}
/**
- * xmlSchemaParseInclude:
- * @ctxt: a schema validation context
+ * xmlSchemaParseIncludedDoc:
+ * @pctxt: a schema validation context
* @schema: the schema being built
* @node: a subtree containing XML Schema informations
*
- * parse a XML schema Include definition
+ * Parse an included (and to-be-redefined) XML schema document.
*
- * Returns -1 in case of error, 0 if the declaration is improper and
- * 1 in case of success.
+ * Returns 0 on success, a positive error code on errors and
+ * -1 in case of an internal or API error.
*/
static int
-xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- xmlNodePtr node)
+xmlSchemaParseIncludedDoc(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
+ xmlNodePtr node, const xmlChar *schemaLocation,
+ int *located)
{
- xmlNodePtr child = NULL;
- const xmlChar *schemaLocation, *targetNamespace;
+ const xmlChar *targetNamespace;
xmlDocPtr doc = NULL;
xmlNodePtr root = NULL;
xmlSchemaIncludePtr include = NULL;
int wasConvertingNs = 0;
- xmlAttrPtr attr;
xmlParserCtxtPtr parserCtxt;
-
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
- return (-1);
-
- /*
- * Check for illegal attributes.
- */
- attr = node->properties;
- while (attr != NULL) {
- if (attr->ns == NULL) {
- if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
- (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
- xmlSchemaPIllegalAttrErr(ctxt,
- XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, NULL, attr);
- }
- } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
- xmlSchemaPIllegalAttrErr(ctxt,
- XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- NULL, NULL, attr);
- }
- attr = attr->next;
- }
- /*
- * Extract and validate attributes.
- */
- xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
- /*
- * Preliminary step, extract the URI-Reference for the include and
- * make an URI from the base.
- */
- attr = xmlSchemaGetPropNode(node, "schemaLocation");
- if (attr != NULL) {
- xmlChar *base = NULL;
- xmlChar *uri = NULL;
-
- if (xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
- xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), &schemaLocation) != 0)
- goto exit_invalid;
- base = xmlNodeGetBase(node->doc, node);
- if (base == NULL) {
- uri = xmlBuildURI(schemaLocation, node->doc->URL);
- } else {
- uri = xmlBuildURI(schemaLocation, base);
- xmlFree(base);
- }
- if (uri == NULL) {
- xmlSchemaPErr(ctxt,
- node,
- XML_SCHEMAP_INTERNAL,
- "Internal error: xmlSchemaParseInclude, "
- "could not build an URI from the schemaLocation.\n",
- NULL, NULL);
- goto exit_failure;
- }
- schemaLocation = xmlDictLookup(ctxt->dict, uri, -1);
- xmlFree(uri);
- } else {
- xmlSchemaPMissingAttrErr(ctxt,
- XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI,
- NULL, node, "schemaLocation", NULL);
- goto exit_invalid;
- }
- /*
- * And now for the children...
- */
- child = node->children;
- while (IS_SCHEMA(child, "annotation")) {
- /*
- * the annotations here are simply discarded ...
- * TODO: really?
- */
- child = child->next;
- }
- if (child != NULL) {
- xmlSchemaPContentErr(ctxt,
- XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD,
- NULL, NULL, node, child, NULL,
- "(annotation?)");
- }
- /*
- * Report self-inclusion.
- */
- if (xmlStrEqual(schemaLocation, ctxt->URL)) {
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_SRC_INCLUDE,
- NULL, NULL, node,
- "The schema document '%s' cannot include itself.",
- schemaLocation);
- return (XML_SCHEMAP_SRC_INCLUDE);
- }
+ if (located == NULL)
+ return(-1);
+ (*located) = 0;
/*
* Check if this one was already processed to avoid incorrect
* duplicate component errors and infinite circular inclusion.
@@ -9366,6 +9524,7 @@ xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
include = schema->includes;
while (include != NULL) {
if (xmlStrEqual(include->schemaLocation, schemaLocation)) {
+ (*located) = 1;
targetNamespace = include->origTargetNamespace;
if (targetNamespace == NULL) {
/*
@@ -9376,7 +9535,7 @@ xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
include->targetNamespace)) {
goto check_targetNamespace;
}
- } else {
+ } else {
goto check_targetNamespace;
}
}
@@ -9393,60 +9552,50 @@ xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
goto exit_failure;
}
- if ((ctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
+ if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
xmlDictFree(parserCtxt->dict);
- parserCtxt->dict = ctxt->dict;
+ parserCtxt->dict = pctxt->dict;
xmlDictReference(parserCtxt->dict);
}
doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
NULL, SCHEMAS_PARSE_OPTIONS);
xmlFreeParserCtxt(parserCtxt);
- if (doc == NULL) {
- /*
- * TODO: It is not an error for the ·actual value· of the
- * schemaLocation [attribute] to fail to resolve it all, in which
- * case no corresponding inclusion is performed.
- * So do we need a warning report here?
- */
- xmlSchemaPCustomErr(ctxt,
- XML_SCHEMAP_FAILED_LOAD,
- NULL, NULL, node,
- "Failed to load the document '%s' for inclusion", schemaLocation);
- goto exit_invalid;
+ if (doc == NULL) {
+ goto exit_not_located;
}
-
+ (*located) = 1;
/*
* Then extract the root of the schema
*/
root = xmlDocGetRootElement(doc);
if (root == NULL) {
- xmlSchemaPCustomErr(ctxt,
+ xmlSchemaPCustomErr(pctxt,
XML_SCHEMAP_NOROOT,
NULL, NULL, node,
"The included document '%s' has no document "
"element", schemaLocation);
- goto exit_invalid;
+ goto exit_error;
}
/*
* Remove all the blank text nodes
*/
- xmlSchemaCleanupDoc(ctxt, root);
+ xmlSchemaCleanupDoc(pctxt, root);
/*
* Check the schemas top level element
*/
if (!IS_SCHEMA(root, "schema")) {
- xmlSchemaPCustomErr(ctxt,
+ xmlSchemaPCustomErr(pctxt,
XML_SCHEMAP_NOT_SCHEMA,
NULL, NULL, node,
"The document '%s' to be included is not a schema document",
schemaLocation);
- goto exit_invalid;
+ goto exit_error;
}
- targetNamespace = xmlSchemaGetProp(ctxt, root, "targetNamespace");
+ targetNamespace = xmlSchemaGetProp(pctxt, root, "targetNamespace");
/*
* 2.1 SII has a targetNamespace [attribute], and its ·actual
* value· is identical to the ·actual value· of the targetNamespace
@@ -9455,22 +9604,22 @@ xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
check_targetNamespace:
if (targetNamespace != NULL) {
if (schema->targetNamespace == NULL) {
- xmlSchemaPCustomErr(ctxt,
+ xmlSchemaPCustomErr(pctxt,
XML_SCHEMAP_SRC_INCLUDE,
NULL, NULL, node,
"The target namespace of the included schema "
"'%s' has to be absent, since the including schema "
"has no target namespace",
schemaLocation);
- goto exit_invalid;
+ goto exit_error;
} else if (!xmlStrEqual(targetNamespace, schema->targetNamespace)) {
- xmlSchemaPCustomErrExt(ctxt,
+ xmlSchemaPCustomErrExt(pctxt,
XML_SCHEMAP_SRC_INCLUDE,
NULL, NULL, node,
"The target namespace '%s' of the included schema '%s' "
"differs from '%s' of the including schema",
targetNamespace, schemaLocation, schema->targetNamespace);
- goto exit_invalid;
+ goto exit_error;
}
} else if (schema->targetNamespace != NULL) {
if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
@@ -9491,13 +9640,14 @@ check_targetNamespace:
* the moment.
* TODO: Check when the namespace in wildcards for chameleons needs
* to be converted: before we built wildcard intersections or after.
+ * Answer: after!
*/
/*
* Register the include.
*/
include = (xmlSchemaIncludePtr) xmlMalloc(sizeof(xmlSchemaInclude));
if (include == NULL) {
- xmlSchemaPErrMemory(ctxt, "allocating include entry", NULL);
+ xmlSchemaPErrMemory(pctxt, "allocating include entry", NULL);
goto exit_failure;
}
memset(include, 0, sizeof(xmlSchemaInclude));
@@ -9529,7 +9679,7 @@ check_targetNamespace:
/*
* Compile the included schema.
*/
- xmlSchemaParseForImpInc(ctxt, schema, schema->targetNamespace, root);
+ xmlSchemaParseForImpInc(pctxt, schema, schema->targetNamespace, root);
exit:
/*
@@ -9538,15 +9688,18 @@ exit:
if ((wasConvertingNs == 0) &&
(schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS))
schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
- return (1);
+ return (0);
-exit_invalid:
+exit_error:
if (doc != NULL) {
if (include != NULL)
include->doc = NULL;
xmlFreeDoc(doc);
}
- return (ctxt->err);
+ return (pctxt->err);
+
+exit_not_located:
+ return(0);
exit_failure:
if (doc != NULL) {
@@ -9557,6 +9710,259 @@ exit_failure:
return (-1);
}
+
+static int
+xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
+ xmlSchemaPtr schema,
+ xmlNodePtr node,
+ xmlChar **schemaLocation,
+ int isRedefine)
+{
+ xmlAttrPtr attr;
+
+ if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
+ (schemaLocation == NULL))
+ return (-1);
+
+ *schemaLocation = NULL;
+ /*
+ * Check for illegal attributes.
+ * Applies for both <include> and <redefine>.
+ */
+ attr = node->properties;
+ while (attr != NULL) {
+ if (attr->ns == NULL) {
+ if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
+ (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
+ xmlSchemaPIllegalAttrErr(pctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
+ xmlSchemaPIllegalAttrErr(pctxt,
+ XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
+ NULL, NULL, attr);
+ }
+ attr = attr->next;
+ }
+ xmlSchemaPValAttrID(pctxt, NULL, NULL, node, BAD_CAST "id");
+ /*
+ * Preliminary step, extract the URI-Reference and make an URI
+ * from the base.
+ */
+ /*
+ * Attribute "schemaLocation" is mandatory.
+ */
+ attr = xmlSchemaGetPropNode(node, "schemaLocation");
+ if (attr != NULL) {
+ xmlChar *base = NULL;
+ xmlChar *uri = NULL;
+
+ if (xmlSchemaPValAttrNode(pctxt, NULL, NULL, attr,
+ xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
+ (const xmlChar **) schemaLocation) != 0)
+ goto exit_error;
+ base = xmlNodeGetBase(node->doc, node);
+ if (base == NULL) {
+ uri = xmlBuildURI(*schemaLocation, node->doc->URL);
+ } else {
+ uri = xmlBuildURI(*schemaLocation, base);
+ xmlFree(base);
+ }
+ if (uri == NULL) {
+ PERROR_INT("xmlSchemaParseIncludeOrRedefine",
+ "could not build an URI from the schemaLocation")
+ goto exit_failure;
+ }
+ (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
+ xmlFree(uri);
+ } else {
+ xmlSchemaPMissingAttrErr(pctxt,
+ XML_SCHEMAP_S4S_ATTR_MISSING,
+ NULL, node, "schemaLocation", NULL);
+ goto exit_error;
+ }
+ /*
+ * Report self-inclusion and self-redefinition.
+ */
+ if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
+ if (isRedefine) {
+ xmlSchemaPCustomErr(pctxt,
+ XML_SCHEMAP_SRC_REDEFINE,
+ NULL, NULL, node,
+ "The schema document '%s' cannot redefine itself.",
+ *schemaLocation);
+ } else {
+ xmlSchemaPCustomErr(pctxt,
+ XML_SCHEMAP_SRC_INCLUDE,
+ NULL, NULL, node,
+ "The schema document '%s' cannot include itself.",
+ *schemaLocation);
+ }
+ goto exit_error;
+ }
+
+ return(0);
+exit_error:
+ return(pctxt->err);
+exit_failure:
+ return(-1);
+}
+
+static int
+xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
+ xmlSchemaPtr schema,
+ xmlNodePtr node,
+ int isRedefine)
+{
+ xmlNodePtr child = NULL;
+ const xmlChar *schemaLocation = NULL;
+ int res = 0, located = 0, hasRedefinitions = 0;
+
+ if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
+ return (-1);
+
+ /*
+ * Parse attributes. Note that the returned schemaLocation will
+ * be already converted to an absolute URI.
+ */
+ res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
+ node, (xmlChar **) (&schemaLocation), isRedefine);
+ if (res != 0)
+ return(res);
+
+ /*
+ * Include the schema.
+ */
+ res = xmlSchemaParseIncludedDoc(pctxt, schema, node,
+ schemaLocation, &located);
+ if (res != 0)
+ return(res);
+
+ /*
+ * And now for the children...
+ */
+ child = node->children;
+
+ if (isRedefine) {
+ /*
+ * Parse (simpleType | complexType | group | attributeGroup))*
+ */
+ pctxt->isRedefine = 1;
+ while (IS_SCHEMA(child, "annotation") ||
+ IS_SCHEMA(child, "simpleType") ||
+ IS_SCHEMA(child, "complexType") ||
+ IS_SCHEMA(child, "group") ||
+ IS_SCHEMA(child, "attributeGroup")) {
+ if (IS_SCHEMA(child, "annotation")) {
+ /*
+ * TODO: discard or not?
+ */
+ } else if (IS_SCHEMA(child, "simpleType")) {
+ xmlSchemaParseSimpleType(pctxt, schema, child, 1);
+ } else if (IS_SCHEMA(child, "complexType")) {
+ xmlSchemaParseComplexType(pctxt, schema, child, 1);
+ hasRedefinitions = 1;
+ } else if (IS_SCHEMA(child, "group")) {
+ TODO
+ hasRedefinitions = 1;
+ /* xmlSchemaParseModelGroupDefinition(pctxt, schema, child); */
+ } else if (IS_SCHEMA(child, "attributeGroup")) {
+ TODO
+ hasRedefinitions = 1;
+ /* xmlSchemaParseAttributeGroup(pctxt, schema, child, 1); */
+ }
+ child = child->next;
+ }
+ pctxt->isRedefine = 0;
+ } else {
+ if (IS_SCHEMA(child, "annotation")) {
+ /*
+ * TODO: discard or not?
+ */
+ child = child->next;
+ }
+ }
+ if (child != NULL) {
+ res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
+ if (isRedefine) {
+ xmlSchemaPContentErr(pctxt,
+ res,
+ NULL, NULL, node, child, NULL,
+ "(annotation | (simpleType | complexType | group | attributeGroup))*");
+ } else {
+ xmlSchemaPContentErr(pctxt,
+ res,
+ NULL, NULL, node, child, NULL,
+ "(annotation?)");
+ }
+ }
+ if (!located) {
+ /*
+ * TODO: This is all *not* yet OK, since we get a !located if the
+ * document was not an XML document as well :-(
+ */
+ if (!isRedefine) {
+ /*
+ * WARNING for <include>:
+ * We will raise an error if the schema cannot be located
+ * for inclusions, since the that was the feedback from the
+ * schema people. I.e. the following spec piece will *not* be
+ * satisfied:
+ * SPEC src-include: "It is not an error for the ·actual value· of the
+ * schemaLocation [attribute] to fail to resolve it all, in which
+ * case no corresponding inclusion is performed.
+ * So do we need a warning report here?"
+ */
+ res = XML_SCHEMAP_SRC_INCLUDE;
+ xmlSchemaPCustomErr(pctxt, res,
+ NULL, NULL, node,
+ "Failed to load the document '%s' for inclusion",
+ schemaLocation);
+ } else if (hasRedefinitions) {
+ /*
+ * SPEC src-redefine (1)
+ * "If there are any element information items among the [children]
+ * other than <annotation> then the ·actual value· of the
+ * schemaLocation [attribute] must successfully resolve."
+ * TODO: Ask the WG if a the location has to resolve here as well!
+ */
+ res = XML_SCHEMAP_SRC_REDEFINE;
+ xmlSchemaPCustomErr(pctxt, res,
+ NULL, NULL, node,
+ "Failed to load the document '%s' for redefinition",
+ schemaLocation);
+ }
+ }
+ return(res);
+}
+
+#ifdef ENABLE_REDEFINE
+static int
+xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
+ xmlNodePtr node)
+{
+ int res;
+
+ res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 1);
+ if (res != 0)
+ return(res);
+ return(0);
+}
+#endif
+
+static int
+xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
+ xmlNodePtr node)
+{
+ int res;
+
+ res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node, 0);
+ if (res != 0)
+ return(res);
+ return(0);
+}
+
/**
* xmlSchemaParseModelGroup:
* @ctxt: a schema validation context
@@ -9805,22 +10211,54 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*/
xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
/*
- * Attribute "base" - mandatory if inside a complex type.
+ * Attribute
*/
/*
- * SPEC (1.2) "otherwise (<restriction> has no <simpleType> "
+ * Extract the base type. The "base" attribute is mandatory if inside
+ * a complex type or if redefining.
+ *
+ * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
* among its [children]), the simple type definition which is
* the {content type} of the type definition ·resolved· to by
* the ·actual value· of the base [attribute]"
*/
- if ((xmlSchemaPValAttrQName(ctxt, schema,
+ if (xmlSchemaPValAttrQName(ctxt, schema,
NULL, NULL, node, "base",
- &(type->baseNs), &(type->base)) == 0) &&
- (type->base == NULL) &&
- (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
- xmlSchemaPMissingAttrErr(ctxt,
- XML_SCHEMAP_S4S_ATTR_MISSING,
- type, node, "base", NULL);
+ &(type->baseNs), &(type->base)) == 0)
+ {
+ if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
+ xmlSchemaPMissingAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_MISSING,
+ type, node, "base", NULL);
+ } else if ((ctxt->isRedefine) &&
+ (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
+ {
+ if (type->base == NULL) {
+ xmlSchemaPMissingAttrErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_MISSING,
+ type, node, "base", NULL);
+ } else if ((! xmlStrEqual(type->base, type->name)) ||
+ (! xmlStrEqual(type->baseNs, type->targetNamespace)))
+ {
+ xmlChar *str1 = NULL, *str2 = NULL;
+ /*
+ * REDEFINE: SPEC src-redefine (5)
+ * "Within the [children], each <simpleType> must have a
+ * <restriction> among its [children] ... the ·actual value· of
+ * whose base [attribute] must be the same as the ·actual value·
+ * of its own name attribute plus target namespace;"
+ */
+ xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
+ NULL, NULL, node, "This is a redefinition, but the QName "
+ "value '%s' of the 'base' attribute does not match the "
+ "type's designation '%s'",
+ xmlSchemaFormatQName(&str1, type->baseNs, type->base),
+ xmlSchemaFormatQName(&str1, type->targetNamespace,
+ type->name), NULL);
+ FREE_AND_NULL(str1);
+ FREE_AND_NULL(str2);
+ }
+ }
}
/*
* And now for the children...
@@ -10174,14 +10612,17 @@ xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*/
static int
xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaPtr schema, xmlNodePtr node)
+ xmlSchemaPtr schema, xmlNodePtr node,
+ int *hasRestrictionOrExtension)
{
xmlSchemaTypePtr type;
xmlNodePtr child = NULL;
xmlAttrPtr attr;
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+ if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
+ (hasRestrictionOrExtension == NULL))
return (-1);
+ *hasRestrictionOrExtension = 0;
/* Not a component, don't create it. */
type = ctxt->ctxtType;
type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
@@ -10218,13 +10659,27 @@ xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaParseAnnotation(ctxt, schema, child));
child = child->next;
}
+ if (child == NULL) {
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_MISSING,
+ NULL, NULL, node, NULL, NULL,
+ "(annotation?, (restriction | extension))");
+ }
+ if (child == NULL) {
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_MISSING,
+ NULL, NULL, node, NULL, NULL,
+ "(annotation?, (restriction | extension))");
+ }
if (IS_SCHEMA(child, "restriction")) {
xmlSchemaParseRestriction(ctxt, schema, child,
XML_SCHEMA_TYPE_SIMPLE_CONTENT);
+ (*hasRestrictionOrExtension) = 1;
child = child->next;
} else if (IS_SCHEMA(child, "extension")) {
xmlSchemaParseExtension(ctxt, schema, child,
XML_SCHEMA_TYPE_SIMPLE_CONTENT);
+ (*hasRestrictionOrExtension) = 1;
child = child->next;
}
if (child != NULL) {
@@ -10249,14 +10704,17 @@ xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
*/
static int
xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
- xmlSchemaPtr schema, xmlNodePtr node)
+ xmlSchemaPtr schema, xmlNodePtr node,
+ int *hasRestrictionOrExtension)
{
xmlSchemaTypePtr type;
xmlNodePtr child = NULL;
xmlAttrPtr attr;
- if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
+ if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
+ (hasRestrictionOrExtension == NULL))
return (-1);
+ *hasRestrictionOrExtension = 0;
/* Not a component, don't create it. */
type = ctxt->ctxtType;
/*
@@ -10298,13 +10756,27 @@ xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaParseAnnotation(ctxt, schema, child));
child = child->next;
}
+ if (child == NULL) {
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_MISSING,
+ NULL, NULL, node, NULL,
+ NULL, "(annotation?, (restriction | extension))");
+ }
+ if (child == NULL) {
+ xmlSchemaPContentErr(ctxt,
+ XML_SCHEMAP_S4S_ELEM_MISSING,
+ NULL, NULL, node, NULL,
+ NULL, "(annotation?, (restriction | extension))");
+ }
if (IS_SCHEMA(child, "restriction")) {
xmlSchemaParseRestriction(ctxt, schema, child,
XML_SCHEMA_TYPE_COMPLEX_CONTENT);
+ (*hasRestrictionOrExtension) = 1;
child = child->next;
} else if (IS_SCHEMA(child, "extension")) {
xmlSchemaParseExtension(ctxt, schema, child,
XML_SCHEMA_TYPE_COMPLEX_CONTENT);
+ (*hasRestrictionOrExtension) = 1;
child = child->next;
}
if (child != NULL) {
@@ -10336,9 +10808,8 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
const xmlChar *oldcontainer, *name = NULL;
xmlAttrPtr attr;
const xmlChar *attrValue;
- xmlChar *des = NULL; /* The reported designation. */
char buf[40];
- int final = 0, block = 0;
+ int final = 0, block = 0, hasRestrictionOrExtension = 0;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
@@ -10353,10 +10824,10 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
return (NULL);
} else if (xmlSchemaPValAttrNode(ctxt,
- (xmlChar **) &xmlSchemaElemDesCT, NULL, attr,
+ NULL, NULL, attr,
xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
return (NULL);
- }
+ }
}
if (topLevel == 0) {
@@ -10364,7 +10835,8 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
* Parse as local complex type definition.
*/
snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf, NULL, node);
+ type = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf, NULL,
+ node, 0);
if (type == NULL)
return (NULL);
name = type->name;
@@ -10377,7 +10849,8 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
/*
* Parse as global complex type definition.
*/
- type = xmlSchemaAddType(ctxt, schema, name, schema->targetNamespace, node);
+ type = xmlSchemaAddType(ctxt, schema, name, schema->targetNamespace,
+ node, 1);
if (type == NULL)
return (NULL);
type->node = node;
@@ -10401,7 +10874,7 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
/*
* Attribute "mixed".
*/
- if (xmlSchemaPGetBoolNodeValue(ctxt, &des, type,
+ if (xmlSchemaPGetBoolNodeValue(ctxt, NULL, type,
(xmlNodePtr) attr))
type->flags |= XML_SCHEMAS_TYPE_MIXED;
} else if (topLevel) {
@@ -10414,7 +10887,7 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
/*
* Attribute "abstract".
*/
- if (xmlSchemaPGetBoolNodeValue(ctxt, &des, type,
+ if (xmlSchemaPGetBoolNodeValue(ctxt, NULL, type,
(xmlNodePtr) attr))
type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
} else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
@@ -10458,17 +10931,17 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
} else {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- &des, type, attr);
+ NULL, type, attr);
}
} else {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- &des, type, attr);
+ NULL, type, attr);
}
} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
xmlSchemaPIllegalAttrErr(ctxt,
XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED,
- &des, type, attr);
+ NULL, type, attr);
}
attr = attr->next;
}
@@ -10503,20 +10976,28 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
ctxt->ctxtType = type;
if (IS_SCHEMA(child, "simpleContent")) {
/*
+ * <complexType><simpleContent>...
* 3.4.3 : 2.2
* Specifying mixed='true' when the <simpleContent>
* alternative is chosen has no effect
*/
if (type->flags & XML_SCHEMAS_TYPE_MIXED)
type->flags ^= XML_SCHEMAS_TYPE_MIXED;
- xmlSchemaParseSimpleContent(ctxt, schema, child);
+ xmlSchemaParseSimpleContent(ctxt, schema, child,
+ &hasRestrictionOrExtension);
child = child->next;
} else if (IS_SCHEMA(child, "complexContent")) {
+ /*
+ * <complexType><complexContent>...
+ */
type->contentType = XML_SCHEMA_CONTENT_EMPTY;
- xmlSchemaParseComplexContent(ctxt, schema, child);
+ xmlSchemaParseComplexContent(ctxt, schema, child,
+ &hasRestrictionOrExtension);
child = child->next;
} else {
/*
+ * E.g <complexType><sequence>... or <complexType><attribute>... etc.
+ *
* SPEC
* "...the third alternative (neither <simpleContent> nor
* <complexContent>) is chosen. This case is understood as shorthand
@@ -10563,12 +11044,20 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if (child != NULL) {
xmlSchemaPContentErr(ctxt,
XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
- &des, type, node, child,
+ NULL, type, node, child,
NULL, "(annotation?, (simpleContent | complexContent | "
"((group | all | choice | sequence)?, ((attribute | "
"attributeGroup)*, anyAttribute?))))");
}
- FREE_AND_NULL(des);
+ /*
+ * REDEFINE: SPEC src-redefine (5)
+ */
+ if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
+ xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
+ NULL, NULL, node, "This is a redefinition, thus the "
+ "<complexType> must have a <restriction> or <extension> "
+ "grand-child", NULL);
+ }
ctxt->container = oldcontainer;
ctxt->ctxtType = ctxtType;
return (type);
@@ -10605,6 +11094,9 @@ xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
ctxt->isS4S = 0;
if (IS_SCHEMA(node, "schema")) {
xmlSchemaImportPtr import;
+#ifdef ENABLE_REDEFINE
+ xmlSchemaSchemaRefPtr ref;
+#endif
schema = xmlSchemaNewSchema(ctxt);
if (schema == NULL)
@@ -10632,14 +11124,23 @@ xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
* if all schemata are constructed dynamically fired by the
* instance or if the schema to be used was specified via
* the API.
+ * TODO
*/
+#ifdef ENABLE_REDEFINE
+ ref = xmlSchemaSchemaRefCreate();
+ if (ref == NULL) {
+ xmlSchemaFree(schema);
+ schema = NULL;
+ return NULL;
+ }
+ ref->schema = schema;
+#endif
+
import = xmlSchemaAddImport(ctxt, &(schema->schemasImports),
schema->targetNamespace);
if (import == NULL) {
- xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_FAILED_BUILD_IMPORT,
- NULL, NULL, (xmlNodePtr) ctxt->doc,
- "Internal error: xmlSchemaParseSchema, "
- "failed to add an import entry", NULL);
+ xmlSchemaPInternalErr(ctxt, "xmlSchemaParseSchema",
+ "failed to add an import entry", NULL, NULL);
xmlSchemaFree(schema);
schema = NULL;
return (NULL);
@@ -10764,14 +11265,9 @@ xmlSchemaNewParserCtxt(const char *URL)
if (URL == NULL)
return (NULL);
- ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
- if (ret == NULL) {
- xmlSchemaPErrMemory(NULL, "allocating schema parser context",
- NULL);
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaParserCtxt));
- ret->type = XML_SCHEMA_CTXT_PARSER;
+ ret = xmlSchemaParserCtxtCreate();
+ if (ret == NULL)
+ return(NULL);
ret->dict = xmlDictCreate();
ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
ret->includes = 0;
@@ -10795,17 +11291,12 @@ xmlSchemaNewMemParserCtxt(const char *buffer, int size)
if ((buffer == NULL) || (size <= 0))
return (NULL);
-
- ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
- if (ret == NULL) {
- xmlSchemaPErrMemory(NULL, "allocating schema parser context",
- NULL);
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaParserCtxt));
+ ret = xmlSchemaParserCtxtCreate();
+ if (ret == NULL)
+ return(NULL);
ret->buffer = buffer;
ret->size = size;
- ret->dict = xmlDictCreate();
+ ret->dict = xmlDictCreate();
return (ret);
}
@@ -10825,14 +11316,9 @@ xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
if (doc == NULL)
return (NULL);
-
- ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
- if (ret == NULL) {
- xmlSchemaPErrMemory(NULL, "allocating schema parser context",
- NULL);
- return (NULL);
- }
- memset(ret, 0, sizeof(xmlSchemaParserCtxt));
+ ret = xmlSchemaParserCtxtCreate();
+ if (ret == NULL)
+ return(NULL);
ret->doc = doc;
ret->dict = xmlDictCreate();
/* The application has responsibility for the document */
@@ -10866,6 +11352,7 @@ xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
if (ctxt->substGroups != NULL)
xmlHashFree(ctxt->substGroups,
(xmlHashDeallocator) xmlSchemaFreeSubstGroup);
+ xmlSchemaContainerFree(ctxt->compContainer);
xmlDictFree(ctxt->dict);
xmlFree(ctxt);
}
@@ -10878,11 +11365,10 @@ xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
static void
xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
- xmlSchemaParticlePtr particle)
+ xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
{
- xmlAutomataStatePtr start;
+ xmlAutomataStatePtr start, tmp;
xmlSchemaElementPtr elemDecl, member;
- xmlAutomataStatePtr end;
xmlSchemaSubstGroupPtr substGroup;
int i;
@@ -10891,7 +11377,8 @@ xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
* Wrap the substitution group with a CHOICE.
*/
start = pctxt->state;
- end = xmlAutomataNewState(pctxt->am);
+ if (end == NULL)
+ end = xmlAutomataNewState(pctxt->am);
substGroup = xmlSchemaGetElementSubstitutionGroup(pctxt, elemDecl);
if (substGroup == NULL) {
xmlSchemaPErr(pctxt, GET_NODE(particle),
@@ -10901,7 +11388,22 @@ xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
"available.\n", elemDecl->name, NULL);
return;
}
- if (particle->maxOccurs == 1) {
+ if (counter >= 0) {
+ /*
+ * NOTE that we put the declaration in, even if it's abstract,
+ */
+ tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
+ xmlAutomataNewTransition2(pctxt->am, tmp, end,
+ elemDecl->name, elemDecl->targetNamespace, elemDecl);
+ /*
+ * Add subst. group members.
+ */
+ for (i = 0; i < substGroup->members->nbItems; i++) {
+ member = (xmlSchemaElementPtr) substGroup->members->items[i];
+ xmlAutomataNewTransition2(pctxt->am, tmp, end,
+ member->name, member->targetNamespace, member);
+ }
+ } else if (particle->maxOccurs == 1) {
/*
* NOTE that we put the declaration in, even if it's abstract,
*/
@@ -10914,14 +11416,12 @@ xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
*/
for (i = 0; i < substGroup->members->nbItems; i++) {
member = (xmlSchemaElementPtr) substGroup->members->items[i];
- xmlAutomataNewEpsilon(pctxt->am,
- xmlAutomataNewTransition2(pctxt->am,
- start, NULL,
- member->name, member->targetNamespace, member),
- end);
+ tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
+ member->name, member->targetNamespace,
+ 1, 1, member);
+ xmlAutomataNewEpsilon(pctxt->am, tmp, end);
}
} else {
- int counter;
xmlAutomataStatePtr hop;
int maxOccurs = particle->maxOccurs == UNBOUNDED ?
UNBOUNDED : particle->maxOccurs - 1;
@@ -10938,8 +11438,8 @@ xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
elemDecl->name, elemDecl->targetNamespace, elemDecl),
hop);
/*
- * Add subst. group members.
- */
+ * Add subst. group members.
+ */
for (i = 0; i < substGroup->members->nbItems; i++) {
member = (xmlSchemaElementPtr) substGroup->members->items[i];
xmlAutomataNewEpsilon(pctxt->am,
@@ -10965,7 +11465,7 @@ xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
/*
* Substitution groups.
*/
- xmlSchemaBuildContentModelForSubstGroup(ctxt, particle);
+ xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
} else {
xmlSchemaElementPtr elemDecl;
xmlAutomataStatePtr start;
@@ -10977,8 +11477,9 @@ xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
if (particle->maxOccurs == 1) {
start = ctxt->state;
ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
- elemDecl->name, elemDecl->targetNamespace, elemDecl);
- } else if ((particle->maxOccurs >= UNBOUNDED) && (particle->minOccurs < 2)) {
+ elemDecl->name, elemDecl->targetNamespace, elemDecl);
+ } else if ((particle->maxOccurs >= UNBOUNDED) &&
+ (particle->minOccurs < 2)) {
/* Special case. */
start = ctxt->state;
ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
@@ -11013,22 +11514,16 @@ xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
* Generate the automata sequence needed for that type
*/
static void
-xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr ctxt,
+xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
xmlSchemaParticlePtr particle,
const xmlChar * name)
{
if (particle == NULL) {
- xmlSchemaPErr(ctxt, NULL,
- XML_SCHEMAP_INTERNAL,
- "Internal error: xmlSchemaBuildAContentModel, "
- "particle is NULL.\n", NULL, NULL);
+ PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
return;
}
if (particle->children == NULL) {
- xmlSchemaPErr(ctxt, GET_NODE(particle),
- XML_SCHEMAP_INTERNAL,
- "Internal error: xmlSchemaBuildAContentModel, "
- "no term on particle.\n", NULL, NULL);
+ PERROR_INT("xmlSchemaBuildAContentModel", "no term on particle");
return;
}
@@ -11040,8 +11535,8 @@ xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr ctxt,
wild = (xmlSchemaWildcardPtr) particle->children;
- start = ctxt->state;
- end = xmlAutomataNewState(ctxt->am);
+ start = pctxt->state;
+ end = xmlAutomataNewState(pctxt->am);
if (particle->maxOccurs == 1) {
if (wild->any == 1) {
@@ -11050,43 +11545,32 @@ xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr ctxt,
*
* 1. the {"*", "*"} for elements in a namespace.
*/
- ctxt->state =
- xmlAutomataNewTransition2(ctxt->am,
+ pctxt->state =
+ xmlAutomataNewTransition2(pctxt->am,
start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
+ xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
/*
* 2. the {"*"} for elements in no namespace.
*/
- ctxt->state =
- xmlAutomataNewTransition2(ctxt->am,
+ pctxt->state =
+ xmlAutomataNewTransition2(pctxt->am,
start, NULL, BAD_CAST "*", NULL, wild);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
+ xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
} else if (wild->nsSet != NULL) {
ns = wild->nsSet;
do {
- ctxt->state = start;
- ctxt->state = xmlAutomataNewTransition2(ctxt->am,
- ctxt->state, NULL, BAD_CAST "*", ns->value, wild);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
+ pctxt->state = start;
+ pctxt->state = xmlAutomataNewTransition2(pctxt->am,
+ pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
+ xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
ns = ns->next;
} while (ns != NULL);
} else if (wild->negNsSet != NULL) {
-
- /*
- * Lead nodes with the negated namespace to the sink-state
- * {"*", "##other"}.
- */
- ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
- BAD_CAST "*", wild->negNsSet->value, wild);
- /*
- * Open a door for nodes with any other namespace
- * {"*", "*"}
- */
- ctxt->state = xmlAutomataNewTransition2(ctxt->am,
- start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
+ pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
+ start, end, BAD_CAST "*", wild->negNsSet->value,
+ wild);
}
} else {
int counter;
@@ -11096,48 +11580,43 @@ xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr ctxt,
int minOccurs =
particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
- counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
- hop = xmlAutomataNewState(ctxt->am);
+ counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
+ hop = xmlAutomataNewState(pctxt->am);
if (wild->any == 1) {
- ctxt->state =
- xmlAutomataNewTransition2(ctxt->am,
+ pctxt->state =
+ xmlAutomataNewTransition2(pctxt->am,
start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
- ctxt->state =
- xmlAutomataNewTransition2(ctxt->am,
+ xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
+ pctxt->state =
+ xmlAutomataNewTransition2(pctxt->am,
start, NULL, BAD_CAST "*", NULL, wild);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
+ xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
} else if (wild->nsSet != NULL) {
ns = wild->nsSet;
do {
- ctxt->state =
- xmlAutomataNewTransition2(ctxt->am,
+ pctxt->state =
+ xmlAutomataNewTransition2(pctxt->am,
start, NULL, BAD_CAST "*", ns->value, wild);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
+ xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
ns = ns->next;
} while (ns != NULL);
} else if (wild->negNsSet != NULL) {
- xmlAutomataStatePtr deadEnd;
-
- deadEnd = xmlAutomataNewState(ctxt->am);
- ctxt->state = xmlAutomataNewTransition2(ctxt->am,
- start, deadEnd, BAD_CAST "*", wild->negNsSet->value, wild);
- ctxt->state = xmlAutomataNewTransition2(ctxt->am,
- start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
+ pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
+ start, hop, BAD_CAST "*", wild->negNsSet->value,
+ wild);
}
- xmlAutomataNewCountedTrans(ctxt->am, hop, start, counter);
- xmlAutomataNewCounterTrans(ctxt->am, hop, end, counter);
+ xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
+ xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
}
if (particle->minOccurs == 0) {
- xmlAutomataNewEpsilon(ctxt->am, start, end);
+ xmlAutomataNewEpsilon(pctxt->am, start, end);
}
- ctxt->state = end;
+ pctxt->state = end;
break;
}
case XML_SCHEMA_TYPE_ELEMENT:
- xmlSchemaBuildContentModelForElement(ctxt, particle);
+ xmlSchemaBuildContentModelForElement(pctxt, particle);
break;
case XML_SCHEMA_TYPE_SEQUENCE:{
xmlSchemaTreeItemPtr sub;
@@ -11149,50 +11628,61 @@ xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr ctxt,
if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
sub = particle->children->children;
while (sub != NULL) {
- xmlSchemaBuildAContentModel(ctxt,
+ xmlSchemaBuildAContentModel(pctxt,
(xmlSchemaParticlePtr) sub, name);
sub = sub->next;
}
} else {
- xmlAutomataStatePtr oldstate = ctxt->state;
+ xmlAutomataStatePtr oldstate = pctxt->state;
if (particle->maxOccurs >= UNBOUNDED) {
if (particle->minOccurs > 1) {
xmlAutomataStatePtr tmp;
int counter;
- ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
+ pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
oldstate, NULL);
- oldstate = ctxt->state;
+ oldstate = pctxt->state;
- counter = xmlAutomataNewCounter(ctxt->am,
+ counter = xmlAutomataNewCounter(pctxt->am,
particle->minOccurs - 1, UNBOUNDED);
sub = particle->children->children;
while (sub != NULL) {
- xmlSchemaBuildAContentModel(ctxt,
+ xmlSchemaBuildAContentModel(pctxt,
(xmlSchemaParticlePtr) sub, name);
sub = sub->next;
}
- tmp = ctxt->state;
- xmlAutomataNewCountedTrans(ctxt->am, tmp,
+ tmp = pctxt->state;
+ xmlAutomataNewCountedTrans(pctxt->am, tmp,
oldstate, counter);
- ctxt->state =
- xmlAutomataNewCounterTrans(ctxt->am, tmp,
+ pctxt->state =
+ xmlAutomataNewCounterTrans(pctxt->am, tmp,
NULL, counter);
} else {
+ pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
+ oldstate, NULL);
+ oldstate = pctxt->state;
+
sub = particle->children->children;
while (sub != NULL) {
- xmlSchemaBuildAContentModel(ctxt,
+ xmlSchemaBuildAContentModel(pctxt,
(xmlSchemaParticlePtr) sub, name);
sub = sub->next;
}
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state,
+ xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
oldstate);
+ /*
+ * epsilon needed to block previous trans from
+ * being allowed to enter back from another
+ * construct
+ */
+ pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
+ pctxt->state, NULL);
if (particle->minOccurs == 0) {
- xmlAutomataNewEpsilon(ctxt->am,
- oldstate, ctxt->state);
+ xmlAutomataNewEpsilon(pctxt->am,
+ oldstate, pctxt->state);
}
}
} else if ((particle->maxOccurs > 1)
@@ -11200,40 +11690,40 @@ xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr ctxt,
xmlAutomataStatePtr tmp;
int counter;
- ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
+ pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
oldstate, NULL);
- oldstate = ctxt->state;
+ oldstate = pctxt->state;
- counter = xmlAutomataNewCounter(ctxt->am,
+ counter = xmlAutomataNewCounter(pctxt->am,
particle->minOccurs - 1,
particle->maxOccurs - 1);
sub = particle->children->children;
while (sub != NULL) {
- xmlSchemaBuildAContentModel(ctxt,
+ xmlSchemaBuildAContentModel(pctxt,
(xmlSchemaParticlePtr) sub, name);
sub = sub->next;
}
- tmp = ctxt->state;
- xmlAutomataNewCountedTrans(ctxt->am,
+ tmp = pctxt->state;
+ xmlAutomataNewCountedTrans(pctxt->am,
tmp, oldstate, counter);
- ctxt->state =
- xmlAutomataNewCounterTrans(ctxt->am, tmp, NULL,
+ pctxt->state =
+ xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
counter);
if (particle->minOccurs == 0) {
- xmlAutomataNewEpsilon(ctxt->am,
- oldstate, ctxt->state);
+ xmlAutomataNewEpsilon(pctxt->am,
+ oldstate, pctxt->state);
}
} else {
sub = particle->children->children;
while (sub != NULL) {
- xmlSchemaBuildAContentModel(ctxt,
+ xmlSchemaBuildAContentModel(pctxt,
(xmlSchemaParticlePtr) sub, name);
sub = sub->next;
}
if (particle->minOccurs == 0) {
- xmlAutomataNewEpsilon(ctxt->am, oldstate,
- ctxt->state);
+ xmlAutomataNewEpsilon(pctxt->am, oldstate,
+ pctxt->state);
}
}
}
@@ -11243,8 +11733,8 @@ xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaTreeItemPtr sub;
xmlAutomataStatePtr start, end;
- start = ctxt->state;
- end = xmlAutomataNewState(ctxt->am);
+ start = pctxt->state;
+ end = xmlAutomataNewState(pctxt->am);
/*
* iterate over the subtypes and remerge the end with an
@@ -11253,15 +11743,15 @@ xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr ctxt,
if (particle->maxOccurs == 1) {
sub = particle->children->children;
while (sub != NULL) {
- ctxt->state = start;
- xmlSchemaBuildAContentModel(ctxt,
+ pctxt->state = start;
+ xmlSchemaBuildAContentModel(pctxt,
(xmlSchemaParticlePtr) sub, name);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end);
+ xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
sub = sub->next;
}
} else {
int counter;
- xmlAutomataStatePtr hop;
+ xmlAutomataStatePtr hop, base;
int maxOccurs = particle->maxOccurs == UNBOUNDED ?
UNBOUNDED : particle->maxOccurs - 1;
int minOccurs =
@@ -11272,27 +11762,26 @@ xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr ctxt,
* which went through the choice.
*/
counter =
- xmlAutomataNewCounter(ctxt->am, minOccurs,
- maxOccurs);
- hop = xmlAutomataNewState(ctxt->am);
+ xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
+ hop = xmlAutomataNewState(pctxt->am);
+ base = xmlAutomataNewState(pctxt->am);
sub = particle->children->children;
while (sub != NULL) {
- ctxt->state = start;
- xmlSchemaBuildAContentModel(ctxt,
+ pctxt->state = base;
+ xmlSchemaBuildAContentModel(pctxt,
(xmlSchemaParticlePtr) sub, name);
- xmlAutomataNewEpsilon(ctxt->am, ctxt->state, hop);
+ xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
sub = sub->next;
}
- xmlAutomataNewCountedTrans(ctxt->am, hop, start,
- counter);
- xmlAutomataNewCounterTrans(ctxt->am, hop, end,
- counter);
+ xmlAutomataNewEpsilon(pctxt->am, start, base);
+ xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
+ xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
}
if (particle->minOccurs == 0) {
- xmlAutomataNewEpsilon(ctxt->am, start, end);
+ xmlAutomataNewEpsilon(pctxt->am, start, end);
}
- ctxt->state = end;
+ pctxt->state = end;
break;
}
case XML_SCHEMA_TYPE_ALL:{
@@ -11304,16 +11793,14 @@ xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr ctxt,
sub = (xmlSchemaParticlePtr) particle->children->children;
if (sub == NULL)
break;
- start = ctxt->state;
+ start = pctxt->state;
while (sub != NULL) {
- ctxt->state = start;
+ pctxt->state = start;
elemDecl = (xmlSchemaElementPtr) sub->children;
if (elemDecl == NULL) {
- xmlSchemaPErr(ctxt, NULL,
- XML_SCHEMAP_INTERNAL,
- "Internal error: xmlSchemaBuildAContentModel, "
- "<element> particle a NULL term.\n", NULL, NULL);
+ PERROR_INT("xmlSchemaBuildAContentModel",
+ "<element> particle has no term");
return;
};
/*
@@ -11322,37 +11809,59 @@ xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr ctxt,
* already ensured during the parse of the content of
* <all>.
*/
- if ((sub->minOccurs == 1) &&
- (sub->maxOccurs == 1)) {
- xmlAutomataNewOnceTrans2(ctxt->am, ctxt->state,
- ctxt->state,
- elemDecl->name,
- elemDecl->targetNamespace,
- 1, 1, elemDecl);
- } else if ((sub->minOccurs == 0) &&
- (sub->maxOccurs == 1)) {
-
- xmlAutomataNewCountTrans2(ctxt->am, ctxt->state,
- ctxt->state,
- elemDecl->name,
- elemDecl->targetNamespace,
- 0,
- 1,
- elemDecl);
- }
+ if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
+ int counter;
+
+ /*
+ * This is an abstract group, we need to share
+ * the same counter for all the element transitions
+ * derived from the group
+ */
+ counter = xmlAutomataNewCounter(pctxt->am,
+ sub->minOccurs, sub->maxOccurs);
+ xmlSchemaBuildContentModelForSubstGroup(pctxt,
+ sub, counter, pctxt->state);
+ } else {
+ if ((sub->minOccurs == 1) &&
+ (sub->maxOccurs == 1)) {
+ xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
+ pctxt->state,
+ elemDecl->name,
+ elemDecl->targetNamespace,
+ 1, 1, elemDecl);
+ } else if ((sub->minOccurs == 0) &&
+ (sub->maxOccurs == 1)) {
+
+ xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
+ pctxt->state,
+ elemDecl->name,
+ elemDecl->targetNamespace,
+ 0,
+ 1,
+ elemDecl);
+ }
+ }
sub = (xmlSchemaParticlePtr) sub->next;
}
lax = particle->minOccurs == 0;
- ctxt->state =
- xmlAutomataNewAllTrans(ctxt->am, ctxt->state, NULL, lax);
+ pctxt->state =
+ xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, lax);
break;
}
+ case XML_SCHEMA_TYPE_GROUP:
+ /*
+ * If we hit a model group definition, then this means that
+ * it was empty, thus was not substituted for the containing
+ * model group. Just do nothing in this case.
+ */
+ break;
default:
- xmlGenericError(xmlGenericErrorContext,
- "Internal error: xmlSchemaBuildAContentModel, found "
- "unexpected term of type %d in content model of complex "
- "type '%s'.\n",
- particle->children->type, name);
+ xmlSchemaPInternalErr(pctxt, "xmlSchemaBuildAContentModel",
+ "found unexpected term of type '%s' in content model of complex "
+ "type '%s'",
+ xmlSchemaCompTypeToString(particle->children->type), name);
+ xmlGenericError(xmlGenericErrorContext,
+ "Unexpected type: %d\n", particle->children->type);
return;
}
}
@@ -12748,7 +13257,7 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr pctxt,
* declaration}'s {value constraint} .
*/
xmlSchemaGetEffectiveValueConstraint(base->attr,
- &effFixed, &bEffValue, 0);
+ &effFixed, &bEffValue, NULL);
/*
* 2.1.3 ... one of the following must be true
*
@@ -12760,7 +13269,7 @@ xmlSchemaBuildAttributeValidation(xmlSchemaParserCtxtPtr pctxt,
const xmlChar *rEffValue = NULL;
xmlSchemaGetEffectiveValueConstraint(base->attr,
- &effFixed, &rEffValue, 0);
+ &effFixed, &rEffValue, NULL);
/*
* 2.1.3.2 R's ·effective value constraint· is
* fixed with the same string as B's.
@@ -13258,8 +13767,14 @@ xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
((item->type != XML_SCHEMA_TYPE_COMPLEX) &&
(item->type != XML_SCHEMA_TYPE_SIMPLE)))
return;
- xmlSchemaCheckTypeDefCircularInternal(ctxt, item, item->baseType);
-
+ if (item->redef != NULL) {
+ xmlSchemaTypePtr cur = item;
+ do {
+ xmlSchemaCheckTypeDefCircularInternal(ctxt, cur, cur->baseType);
+ cur = cur->redef;
+ } while (cur != NULL);
+ } else
+ xmlSchemaCheckTypeDefCircularInternal(ctxt, item, item->baseType);
}
/**
@@ -14298,7 +14813,7 @@ xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
* SPEC (1) "If the {base type definition} is a complex type definition,
* then all of the following must be true:"
*/
- if (base->type == XML_SCHEMA_TYPE_COMPLEX) {
+ if (IS_COMPLEX_TYPE(base)) {
/*
* SPEC (1.1) "The {final} of the {base type definition} must not
* contain extension."
@@ -15619,7 +16134,7 @@ xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
if (res == -2)
goto internal_error;
- if (res == -1) {
+ if (res == 1) {
xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
}
}
@@ -16036,7 +16551,7 @@ xmlSchemaTypeFixup(xmlSchemaTypePtr type,
snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
content = xmlSchemaAddType(pctxt,
- pctxt->schema, tmpname, tmpname, type->node);
+ pctxt->schema, tmpname, tmpname, type->node, 0);
if (content == NULL)
return;
/*
@@ -18355,8 +18870,6 @@ xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
return (ret);
}
-#define VAL_CREATE_DICT if (vctxt->dict == NULL) vctxt->dict = xmlDictCreate();
-
static const xmlChar *
xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
const xmlChar *prefix)
@@ -18392,7 +18905,6 @@ xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
if (nsName != NULL) {
const xmlChar *ret;
- VAL_CREATE_DICT;
ret = xmlDictLookup(vctxt->dict, nsName, -1);
xmlFree(nsName);
return (ret);
@@ -18488,6 +19000,34 @@ xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
return (ret);
}
+static int
+xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
+ const xmlChar* lname,
+ const xmlChar* nsname)
+{
+ int i;
+
+ lname = xmlDictLookup(vctxt->dict, lname, -1);
+ if (lname == NULL)
+ return(-1);
+ if (nsname != NULL) {
+ nsname = xmlDictLookup(vctxt->dict, nsname, -1);
+ if (nsname == NULL)
+ return(-1);
+ }
+ for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
+ if ((vctxt->nodeQNames->items [i] == lname) &&
+ (vctxt->nodeQNames->items[i +1] == nsname))
+ /* Already there */
+ return(i);
+ }
+ /* Add new entry. */
+ i = vctxt->nodeQNames->nbItems;
+ xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
+ xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
+ return(i);
+}
+
/************************************************************************
* *
* Validation of identity-constraints (IDC) *
@@ -19056,6 +19596,32 @@ xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
}
/**
+ * xmlSchemaXPathPop:
+ * @vctxt: the WXS validation context
+ *
+ * Pops all XPath states.
+ *
+ * Returns 0 on success and -1 on internal errors.
+ */
+static int
+xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
+{
+ xmlSchemaIDCStateObjPtr sto;
+ int res;
+
+ if (vctxt->xpathStates == NULL)
+ return(0);
+ sto = vctxt->xpathStates;
+ do {
+ res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
+ if (res == -1)
+ return (-1);
+ sto = sto->next;
+ } while (sto != NULL);
+ return(0);
+}
+
+/**
* xmlSchemaXPathProcessHistory:
* @vctxt: the WXS validation context
* @type: the simple/complex type of the current node if any at all
@@ -19399,7 +19965,7 @@ create_key:
*keySeq = NULL;
return(-1);
}
- memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
+ memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
/*
* Store the node-table item on global list.
@@ -19411,11 +19977,27 @@ create_key:
*keySeq = NULL;
return (-1);
}
+ ntItem->nodeQNameID = -1;
+ } else {
+ /*
+ * Save a cached QName for this node on the IDC node, to be
+ * able to report it, even if the node is not saved.
+ */
+ ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
+ vctxt->inode->localName, vctxt->inode->nsName);
+ if (ntItem->nodeQNameID == -1) {
+ xmlFree(ntItem);
+ xmlFree(*keySeq);
+ *keySeq = NULL;
+ return (-1);
+ }
}
/*
- * Init the node-table item. Consume the key-sequence.
+ * Init the node-table item: Save the node, position and
+ * consume the key-sequence.
*/
ntItem->node = vctxt->node;
+ ntItem->nodeLine = vctxt->inode->nodeLine;
ntItem->keys = *keySeq;
*keySeq = NULL;
if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1) {
@@ -19886,6 +20468,7 @@ xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
int i, j, k, res;
xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
xmlSchemaPSVIIDCKeyPtr refKey, key;
+ xmlSchemaPSVIIDCNodePtr refNode = NULL;
/*
* Find the referred key/unique.
@@ -19903,8 +20486,9 @@ xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
*/
for (i = 0; i < refbind->nbNodes; i++) {
res = 0;
- if (bind != NULL) {
- refKeys = refbind->nodeTable[i]->keys;
+ refNode = refbind->nodeTable[i];
+ if (bind != NULL) {
+ refKeys = refNode->keys;
for (j = 0; j < bind->nbNodes; j++) {
keys = bind->nodeTable[j]->keys;
for (k = 0; k < bind->definition->nbFields; k++) {
@@ -19928,9 +20512,8 @@ xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
}
if (res == 0) {
xmlChar *str = NULL, *strB = NULL;
- /* TODO: Report the key-sequence. */
- xmlSchemaCustomErr((xmlSchemaAbstractCtxtPtr) vctxt,
- XML_SCHEMAV_CVC_IDC, NULL,
+ xmlSchemaKeyrefErr(vctxt,
+ XML_SCHEMAV_CVC_IDC, refNode,
(xmlSchemaTypePtr) refbind->definition,
"No match found for key-sequence %s of key "
"reference '%s'",
@@ -20011,8 +20594,9 @@ xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
static int
xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
xmlNodePtr attrNode,
+ int nodeLine,
const xmlChar *localName,
- const xmlChar *nsName,
+ const xmlChar *nsName,
int ownedNames,
xmlChar *value,
int ownedValue)
@@ -20026,6 +20610,7 @@ xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
return (-1);
}
attr->node = attrNode;
+ attr->nodeLine = nodeLine;
attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
attr->localName = localName;
attr->nsName = nsName;
@@ -20859,7 +21444,6 @@ xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
* string.
*/
local = xmlSplitQName2(value, &prefix);
- VAL_CREATE_DICT;
if (local == NULL)
*localName = xmlDictLookup(vctxt->dict, value, -1);
else {
@@ -21715,7 +22299,8 @@ eval_idcs:
"calling xmlSchemaXPathEvaluate()");
goto internal_error;
}
- }
+ } else if (vctxt->xpathStates != NULL)
+ xmlSchemaXPathPop(vctxt);
}
/*
@@ -21802,41 +22387,6 @@ xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
return (-1);
}
*skip = 0;
- if (wild->negNsSet != NULL) {
- /*
- * URGENT VAL TODO: Fix the content model to reject
- * "##other" wildcards.
- */
- if (xmlSchemaCheckCVCWildcardNamespace(wild,
- vctxt->inode->nsName) != 0) {
- if ((wild->minOccurs == 1) && (wild->maxOccurs == 1)) {
- xmlSchemaNodeInfoPtr pinode = vctxt->elemInfos[vctxt->depth -1];
- /*
- * VAL TODO: Workaround possible *only* if minOccurs and
- * maxOccurs are 1.
- */
- xmlSchemaComplexTypeErr((xmlSchemaAbstractCtxtPtr) vctxt,
- /* VAL TODO: error code? */
- XML_SCHEMAV_ELEMENT_CONTENT, NULL,
- (xmlSchemaTypePtr) wild,
- "This element is not accepted by the wildcard",
- 0, 0, NULL);
- vctxt->skipDepth = vctxt->depth;
- if ((pinode->flags &
- XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0)
- pinode->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
- vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
- return (XML_SCHEMAV_ELEMENT_CONTENT);
- }
- if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
- *skip = 1;
- return (0);
- }
- vctxt->inode->typeDef =
- xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
- return (0);
- }
- }
if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
/*
* URGENT VAL TODO: Either we need to position the stream to the
@@ -23179,7 +23729,6 @@ internal_error:
* *
************************************************************************/
-#ifdef XML_SCHEMA_SAX_ENABLED
/*
* Process text content.
*/
@@ -23278,6 +23827,10 @@ xmlSchemaSAXHandleStartElementNs(void *ctx,
goto internal_error;
}
ielem = vctxt->inode;
+ /*
+ * TODO: Is this OK?
+ */
+ ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
ielem->localName = localname;
ielem->nsName = URI;
ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
@@ -23345,8 +23898,11 @@ xmlSchemaSAXHandleStartElementNs(void *ctx,
*/
value = xmlStrndup(attributes[j+3],
attributes[j+4] - attributes[j+3]);
+ /*
+ * TODO: Set the node line.
+ */
ret = xmlSchemaValidatorPushAttribute(vctxt,
- NULL, attributes[j], attributes[j+2], 0,
+ NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
value, 1);
if (ret == -1) {
VERROR_INT("xmlSchemaSAXHandleStartElementNs",
@@ -23419,7 +23975,6 @@ internal_error:
xmlStopParser(vctxt->parserCtxt);
return;
}
-#endif
/************************************************************************
* *
@@ -23447,6 +24002,8 @@ xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
}
memset(ret, 0, sizeof(xmlSchemaValidCtxt));
ret->type = XML_SCHEMA_CTXT_VALIDATOR;
+ ret->dict = xmlDictCreate();
+ ret->nodeQNames = xmlSchemaItemListCreate();
ret->schema = schema;
return (ret);
}
@@ -23524,7 +24081,11 @@ xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
break;
xmlSchemaClearElemInfo(ei);
}
- }
+ }
+ xmlSchemaItemListClear(vctxt->nodeQNames);
+ /* Recreate the dict. */
+ xmlDictFree(vctxt->dict);
+ vctxt->dict = xmlDictCreate();
}
/**
@@ -23602,6 +24163,8 @@ xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
}
xmlFree(ctxt->elemInfos);
}
+ if (ctxt->nodeQNames != NULL)
+ xmlSchemaItemListFree(ctxt->nodeQNames);
if (ctxt->dict != NULL)
xmlDictFree(ctxt->dict);
xmlFree(ctxt);
@@ -23648,6 +24211,26 @@ xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
}
/**
+ * xmlSchemaSetValidStructuredErrors:
+ * @ctxt: a schema validation context
+ * @serror: the structured error function
+ * @ctx: the functions context
+ *
+ * Set the structured error callback
+ */
+void
+xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
+ xmlStructuredErrorFunc serror, void *ctx)
+{
+ if (ctxt == NULL)
+ return;
+ ctxt->serror = serror;
+ ctxt->error = NULL;
+ ctxt->warning = NULL;
+ ctxt->userData = ctx;
+}
+
+/**
* xmlSchemaGetValidErrors:
* @ctxt: a XML-Schema validation context
* @err: the error function result
@@ -23758,6 +24341,7 @@ xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
goto internal_error;
ielem = vctxt->inode;
ielem->node = node;
+ ielem->nodeLine = node->line;
ielem->localName = node->name;
if (node->ns != NULL)
ielem->nsName = node->ns->href;
@@ -23777,6 +24361,11 @@ xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
nsName = NULL;
ret = xmlSchemaValidatorPushAttribute(vctxt,
(xmlNodePtr) attr,
+ /*
+ * Note that we give it the line number of the
+ * parent element.
+ */
+ ielem->nodeLine,
attr->name, nsName, 0,
xmlNodeListGetString(attr->doc, attr->children, 1), 1);
if (ret == -1) {
@@ -24246,24 +24835,24 @@ commentSplit(void *ctx, const xmlChar *value)
* Varargs error callbacks to the user application, harder ...
*/
-static void
-warningSplit(void *ctx, const char *msg, ...) {
+static void XMLCDECL
+warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->warning != NULL)) {
TODO
}
}
-static void
-errorSplit(void *ctx, const char *msg, ...) {
+static void XMLCDECL
+errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->error != NULL)) {
TODO
}
}
-static void
-fatalErrorSplit(void *ctx, const char *msg, ...) {
+static void XMLCDECL
+fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
(ctxt->user_sax->fatalError != NULL)) {
@@ -24643,7 +25232,6 @@ xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
const char * filename,
int options ATTRIBUTE_UNUSED)
{
-#ifdef XML_SCHEMA_SAX_ENABLED
int ret;
xmlParserInputBufferPtr input;
@@ -24657,9 +25245,6 @@ xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
NULL, NULL);
return (ret);
-#else
- return (-1);
-#endif /* XML_SCHEMA_SAX_ENABLED */
}
#define bottom_xmlschemas