Added validation for the attribute "id" in the schemata; doing this needed
* xmlschemas.c: Added validation for the attribute "id" in the
schemata; doing this needed error report fixes for notations,
facets and group. Changed NOTATION validation to work with the
declared NOTATIONs in the schema; this does have no impact on
the validation via the relaxng module.
* xmlschemastypes.c include/libxml/xmlschemastypes.h:
Added xmlSchemaNewNOTATIONValue to the API to be able to do
the NOTATION validation described above.
* test/schemas/element-err_0.xsd test/schemas/annot-err_0.xsd:
Fixed the values of the "id" attributes, which were not validated
previously.
diff --git a/xmlschemas.c b/xmlschemas.c
index 4852b6c..6cffc4f 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -54,7 +54,7 @@
#define ELEM_INFO_ENABLED 1
-/* #define IDC_ENABLED 1 */
+/* #define IDC_ENABLED 1 */
/* #define IDC_VALUE_SUPPORT 1 */
@@ -92,6 +92,10 @@
"simple type";
static const xmlChar *xmlSchemaElemDesCT = (const xmlChar *)
"complex type";
+static const xmlChar *xmlSchemaElemModelGrDef = (const xmlChar *)
+ "Model group";
+static const xmlChar *xmlSchemaElemModelGrRef = (const xmlChar *)
+ "Model group ref.";
#define IS_SCHEMA(node, type) \
((node != NULL) && (node->ns != NULL) && \
@@ -129,14 +133,6 @@
/*
-* XML_SCHEMA_VAL_XSI_ASSEMBLE_TNS_COMPOSE
-* allow to assemble schemata with
-* the same target namespace from
-* different sources; otherwise, the first
-* encountered schema with a specific target
-* namespace will be used only *
-
-*
* XML_SCHEMA_VAL_LOCATE_BY_NSNAME = 1<<2
* locate schemata to be imported
* using the namespace name; otherwise
@@ -155,15 +151,6 @@
} xmlSchemaParserOption;
*/
-/*
-XMLPUBFUN int XMLCALL
- xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
- int options);
-XMLPUBFUN int XMLCALL
- xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt);
-
-*/
-
typedef struct _xmlSchemaAssemble xmlSchemaAssemble;
typedef xmlSchemaAssemble *xmlSchemaAssemblePtr;
struct _xmlSchemaAssemble {
@@ -496,7 +483,6 @@
typedef xmlSchemaInclude *xmlSchemaIncludePtr;
struct _xmlSchemaInclude {
xmlSchemaIncludePtr next;
-
const xmlChar *schemaLocation;
xmlDocPtr doc;
};
@@ -543,7 +529,7 @@
static void
xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl,
xmlSchemaParserCtxtPtr ctxt, const xmlChar * name);
-static const char *
+static const xmlChar *
xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
static int
xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
@@ -922,6 +908,28 @@
}
/**
+ * xmlSchemaWildcardPCToString:
+ * @pc: the type of processContents
+ *
+ * Returns a string representation of the type of
+ * processContents.
+ */
+static const xmlChar *
+xmlSchemaWildcardPCToString(int pc)
+{
+ switch (pc) {
+ case XML_SCHEMAS_ANY_SKIP:
+ return (BAD_CAST "skip");
+ case XML_SCHEMAS_ANY_LAX:
+ return (BAD_CAST "lax");
+ case XML_SCHEMAS_ANY_STRICT:
+ return (BAD_CAST "strict");
+ default:
+ return (BAD_CAST "invalid process contents");
+ }
+}
+
+/**
* xmlSchemaFormatItemForReport:
* @buf: the string buffer
* @itemDes: the designation of the item
@@ -1003,7 +1011,7 @@
xmlSchemaAttributePtr attr;
attr = (xmlSchemaAttributePtr) item;
- if ((attr->flags & XML_SCHEMAS_TYPE_GLOBAL) ||
+ if ((attr->flags & XML_SCHEMAS_ATTR_GLOBAL) ||
(attr->ref == NULL)) {
*buf = xmlStrdup(xmlSchemaElemDesAttrDecl);
*buf = xmlStrcat(*buf, BAD_CAST " '");
@@ -1023,7 +1031,7 @@
xmlSchemaElementPtr elem;
elem = (xmlSchemaElementPtr) item;
- if ((elem->flags & XML_SCHEMAS_TYPE_GLOBAL) ||
+ if ((elem->flags & XML_SCHEMAS_ELEM_GLOBAL) ||
(elem->ref == NULL)) {
*buf = xmlStrdup(xmlSchemaElemDesElemDecl);
*buf = xmlStrcat(*buf, BAD_CAST " '");
@@ -1052,7 +1060,41 @@
*buf = xmlStrcat(*buf, BAD_CAST "'");
break;
case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
- TODO
+ *buf = xmlStrdup(xmlSchemaWildcardPCToString(
+ ((xmlSchemaWildcardPtr) item)->processContents));
+ *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
+ break;
+ case XML_SCHEMA_FACET_MININCLUSIVE:
+ case XML_SCHEMA_FACET_MINEXCLUSIVE:
+ case XML_SCHEMA_FACET_MAXINCLUSIVE:
+ case XML_SCHEMA_FACET_MAXEXCLUSIVE:
+ case XML_SCHEMA_FACET_TOTALDIGITS:
+ case XML_SCHEMA_FACET_FRACTIONDIGITS:
+ case XML_SCHEMA_FACET_PATTERN:
+ case XML_SCHEMA_FACET_ENUMERATION:
+ case XML_SCHEMA_FACET_WHITESPACE:
+ case XML_SCHEMA_FACET_LENGTH:
+ case XML_SCHEMA_FACET_MAXLENGTH:
+ case XML_SCHEMA_FACET_MINLENGTH:
+ *buf = xmlStrdup(BAD_CAST "facet '");
+ *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ break;
+ case XML_SCHEMA_TYPE_NOTATION:
+ *buf = xmlStrdup(BAD_CAST "notation");
+ break;
+ case XML_SCHEMA_TYPE_GROUP:
+ if (item->flags & XML_SCHEMAS_TYPE_GLOBAL) {
+ *buf = xmlStrdup(xmlSchemaElemModelGrDef);
+ *buf = xmlStrcat(*buf, BAD_CAST " '");
+ *buf = xmlStrcat(*buf, item->name);
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ } else {
+ *buf = xmlStrdup(xmlSchemaElemModelGrRef);
+ *buf = xmlStrcat(*buf, BAD_CAST " '");
+ *buf = xmlStrcat(*buf, item->ref);
+ *buf = xmlStrcat(*buf, BAD_CAST "'");
+ }
break;
default:
named = 0;
@@ -1188,7 +1230,7 @@
*/
} else
facetType = facet->type;
- msg = xmlStrcat(msg, BAD_CAST xmlSchemaFacetTypeToString(facetType));
+ msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
msg = xmlStrcat(msg, BAD_CAST "']: ");
if (message == NULL) {
/*
@@ -1774,7 +1816,7 @@
xmlSchemaPErrExt(ctxt, item->node, error, NULL, NULL, NULL,
"%s: The facet '%s' is not allowed on types derived from the "
"type %s.\n",
- BAD_CAST des, BAD_CAST xmlSchemaFacetTypeToString(facet->type),
+ BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
xmlSchemaFormatItemForReport(&strT, NULL, baseItem, NULL, 1),
NULL, NULL);
if (itemDes == NULL)
@@ -1804,7 +1846,7 @@
xmlSchemaPAquireDes(&des, itemDes, item, item->node);
xmlSchemaPErr(ctxt, item->node, error,
"%s: The facet '%s' is not allowed.\n",
- BAD_CAST des, BAD_CAST xmlSchemaFacetTypeToString(facet->type));
+ BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
if (itemDes == NULL)
FREE_AND_NULL(des);
FREE_AND_NULL(strT);
@@ -2076,28 +2118,6 @@
}
/**
- * xmlSchemaWildcardPCToString:
- * @pc: the type of processContents
- *
- * Returns a string representation of the type of
- * processContents.
- */
-static const char *
-xmlSchemaWildcardPCToString(int pc)
-{
- switch (pc) {
- case XML_SCHEMAS_ANY_SKIP:
- return ("skip");
- case XML_SCHEMAS_ANY_LAX:
- return ("lax");
- case XML_SCHEMAS_ANY_STRICT:
- return ("strict");
- default:
- return ("invalid process contents");
- }
-}
-
-/**
* xmlSchemaVWildcardErr:
* @ctxt: the schema validation context
* @error: the error code
@@ -2118,7 +2138,7 @@
xmlSchemaFormatItemForReport(&des, NULL, NULL, node, 0);
msg = xmlStrdup(BAD_CAST "%s [");
- msg = xmlStrcat(msg, BAD_CAST xmlSchemaWildcardPCToString(wild->processContents));
+ msg = xmlStrcat(msg, xmlSchemaWildcardPCToString(wild->processContents));
msg = xmlStrcat(msg, BAD_CAST " wildcard]: ");
msg = xmlStrcat(msg, (const xmlChar *) message);
msg = xmlStrcat(msg, BAD_CAST ".\n");
@@ -3468,7 +3488,7 @@
*/
static xmlSchemaNotationPtr
xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- const xmlChar * name)
+ const xmlChar *name)
{
xmlSchemaNotationPtr ret = NULL;
int val;
@@ -4123,6 +4143,82 @@
}
/**
+ * xmlSchemaPValAttrID:
+ * @ctxt: a schema parser context
+ * @schema: the schema context
+ * @ownerDes: the designation of the parent element
+ * @ownerItem: the owner as a schema object
+ * @ownerElem: the parent node of the attribute
+ * @name: the name of the attribute
+ *
+ * Extracts and validates the ID of an attribute value.
+ *
+ * Returns 0, in case the ID is valid, a positive error code
+ * if not valid and -1 if an internal error occurs.
+ */
+static int
+xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
+ xmlChar **ownerDes,
+ xmlSchemaTypePtr ownerItem,
+ xmlNodePtr ownerElem,
+ const xmlChar *name)
+{
+ int ret;
+ xmlChar *value;
+ xmlAttrPtr attr;
+
+ value = xmlGetNoNsProp(ownerElem, name);
+ if (value == NULL)
+ return (0);
+
+ attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
+ if (attr == NULL)
+ return (-1);
+
+ ret = xmlValidateNCName(BAD_CAST value, 1);
+ if (ret == 0) {
+ /*
+ * NOTE: the IDness might have already be declared in the DTD
+ */
+ if (attr->atype != XML_ATTRIBUTE_ID) {
+ xmlIDPtr res;
+ xmlChar *strip;
+
+ /*
+ * TODO: Use xmlSchemaStrip here; it's not exported at this
+ * moment.
+ */
+ strip = xmlSchemaCollapseString(BAD_CAST value);
+ if (strip != NULL)
+ value = strip;
+ res = xmlAddID(NULL, ownerElem->doc, BAD_CAST value, attr);
+ if (res == NULL) {
+ ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+ ownerDes, ownerItem, (xmlNodePtr) attr,
+ xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
+ NULL, NULL, "The ID '%s' already defined",
+ BAD_CAST value, NULL);
+ } else
+ attr->atype = XML_ATTRIBUTE_ID;
+ if (strip != NULL)
+ xmlFree(strip);
+ }
+ } else if (ret > 0) {
+ ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
+ xmlSchemaPSimpleTypeErr(ctxt,
+ XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
+ ownerDes, ownerItem, (xmlNodePtr) attr,
+ xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
+ NULL, BAD_CAST value, NULL, NULL, NULL);
+ }
+ xmlFree(value);
+
+ return (ret);
+}
+
+/**
* xmlGetMaxOccurs:
* @ctxt: a schema validation context
* @node: a subtree containing XML Schema informations
@@ -4696,8 +4792,7 @@
}
attr = attr->next;
}
- /* TODO: Check id. */
-
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
/*
* And now for the children...
*/
@@ -4839,7 +4934,8 @@
xmlSchemaFreeFacet(facet);
return (NULL);
}
- facet->id = xmlSchemaGetProp(ctxt, node, "id");
+ xmlSchemaPValAttrID(ctxt, NULL,
+ (xmlSchemaTypePtr) facet, node, BAD_CAST "id");
facet->value = value;
if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
@@ -5189,7 +5285,8 @@
}
attr = attr->next;
}
- /* ret->id = xmlSchemaGetProp(ctxt, node, "id"); */
+ xmlSchemaPValAttrID(ctxt, NULL, (xmlSchemaTypePtr) ret,
+ node, BAD_CAST "id");
/*
* Parse the namespace list.
*/
@@ -5431,9 +5528,9 @@
}
xmlSchemaPValAttrQName(ctxt, schema, &repName, (xmlSchemaTypePtr) ret,
node, "type", &ret->typeNs, NULL, &ret->typeName);
- }
- /* TODO: Check ID. */
- ret->id = xmlSchemaGetProp(ctxt, node, "id");
+ }
+ xmlSchemaPValAttrID(ctxt, NULL, (xmlSchemaTypePtr) ret,
+ node, BAD_CAST "id");
/*
* Attribute "fixed".
*/
@@ -6513,9 +6610,9 @@
}
/*
* Extract/validate common attributes.
- */
- /* TODO: Check ID: */
- ret->id = xmlSchemaGetProp(ctxt, node, "id");
+ */
+ xmlSchemaPValAttrID(ctxt, NULL, (xmlSchemaTypePtr) ret,
+ node, BAD_CAST "id");
ret->minOccurs = minOccurs;
ret->maxOccurs = maxOccurs;
if (topLevel != 1)
@@ -6663,7 +6760,7 @@
}
attr = attr->next;
}
- type->id = xmlSchemaGetProp(ctxt, node, "id");
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
/*
* Attribute "memberTypes". This is a list of QNames.
* TODO: Validate the QNames.
@@ -6731,7 +6828,7 @@
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_LIST;
- type->id = xmlSchemaGetProp(ctxt, node, "id");
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
/*
* Check for illegal attributes.
*/
@@ -6912,8 +7009,7 @@
}
}
type->targetNamespace = schema->targetNamespace;
- /* TODO: Check id. */
- type->id = xmlSchemaGetProp(ctxt, node, "id");
+ xmlSchemaPValAttrID(ctxt, NULL, type, node, BAD_CAST "id");
/*
* And now for the children...
*/
@@ -7012,7 +7108,7 @@
type->type = XML_SCHEMA_TYPE_GROUP;
if (topLevel)
type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
- type->id = xmlSchemaGetProp(ctxt, node, "id");
+ xmlSchemaPValAttrID(ctxt, NULL, type, node, BAD_CAST "id");
type->ref = ref;
type->refNs = refNs;
type->minOccurs = minOccurs;
@@ -7080,7 +7176,8 @@
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_ALL;
- type->id = xmlSchemaGetProp(ctxt, node, "id");
+
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
type->minOccurs = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
type->maxOccurs = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
@@ -8155,7 +8252,7 @@
/*
* Extract and validate attributes.
*/
- type->id = xmlSchemaGetProp(ctxt, node, "id");
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
type->minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger");
type->maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
"(nonNegativeInteger | unbounded)");
@@ -8265,7 +8362,7 @@
/*
* Extract and validate attributes.
*/
- type->id = xmlSchemaGetProp(ctxt, node, "id");
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
type->minOccurs = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "nonNegativeInteger");
type->maxOccurs = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
"(nonNegativeInteger | unbounded)");
@@ -8373,7 +8470,7 @@
/*
* Extract and validate attributes.
*/
- type->id = xmlSchemaGetProp(ctxt, node, "id");
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
/*
* Attribute "base".
*/
@@ -8573,7 +8670,9 @@
return (NULL);
type->type = XML_SCHEMA_TYPE_EXTENSION;
type->node = node;
- type->id = xmlSchemaGetProp(ctxt, node, "id");
+
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
+
ctxt->container = name;
type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
@@ -8651,7 +8750,8 @@
return (NULL);
type->type = XML_SCHEMA_TYPE_SIMPLE_CONTENT;
type->node = node;
- type->id = xmlSchemaGetProp(ctxt, node, "id");
+
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
@@ -8730,7 +8830,9 @@
}
attr = attr->next;
}
- type->id = xmlSchemaGetProp(ctxt, node, "id");
+
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
+
/*
* Handle attribute 'mixed'.
*/
@@ -8852,7 +8954,8 @@
/*
* Attribute "id".
*/
- type->id = xmlSchemaGetProp(ctxt, node, "id");
+ xmlSchemaPValAttrID(ctxt, NULL, type, node,
+ BAD_CAST "id");
} else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
/*
* Attribute "mixed".
@@ -9077,8 +9180,7 @@
* import->doc = ctxt->doc;
*/
- /* TODO: Check id. */
- schema->id = xmlSchemaGetProp(ctxt, node, "id");
+ xmlSchemaPValAttrID(ctxt, NULL, NULL, node, BAD_CAST "id");
xmlSchemaPValAttr(ctxt, NULL, NULL, node, "version",
xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &(schema->version));
@@ -13792,7 +13894,7 @@
"Type definition '%s': The value '%s' of the "
"facet '%s' is not valid.\n",
name, facet->value,
- BAD_CAST xmlSchemaFacetTypeToString(facet->type),
+ xmlSchemaFacetTypeToString(facet->type),
NULL, NULL);
}
ret = -1;
@@ -13804,7 +13906,7 @@
"failed to validate the value '%s' name of the "
"facet '%s' against the base type '%s'.\n",
facet->value,
- BAD_CAST xmlSchemaFacetTypeToString(facet->type),
+ xmlSchemaFacetTypeToString(facet->type),
base->name, NULL, NULL);
ret = -1;
}
@@ -13843,7 +13945,7 @@
"Type definition '%s': The value '%s' of the "
"facet '%s' is not valid.\n",
name, facet->value,
- BAD_CAST xmlSchemaFacetTypeToString(facet->type),
+ xmlSchemaFacetTypeToString(facet->type),
NULL, NULL);
}
ret = -1;
@@ -13894,10 +13996,22 @@
if (typeDecl->facets != NULL) {
xmlSchemaFacetPtr facet = typeDecl->facets;
+ /*
+ * Temporarily assign the "schema" to the validation context
+ * of the parser context. This is needed for NOTATION validation.
+ */
+ if (ctxt->vctxt == NULL) {
+ if (xmlSchemaCreateVCtxtOnPCtxt(ctxt) == -1)
+ return;
+ }
+ ctxt->vctxt->schema = ctxt->schema;
+
while (facet != NULL) {
xmlSchemaCheckFacet(facet, typeDecl, ctxt, name);
facet = facet->next;
}
+
+ ctxt->vctxt->schema = NULL;
}
}
@@ -14747,38 +14861,38 @@
* Returns the char string representation of the facet type if the
* type is a facet and an "Internal Error" string otherwise.
*/
-static const char *
+static const xmlChar *
xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
{
switch (type) {
case XML_SCHEMA_FACET_PATTERN:
- return ("pattern");
+ return (BAD_CAST "pattern");
case XML_SCHEMA_FACET_MAXEXCLUSIVE:
- return ("maxExclusive");
+ return (BAD_CAST "maxExclusive");
case XML_SCHEMA_FACET_MAXINCLUSIVE:
- return ("maxInclusive");
+ return (BAD_CAST "maxInclusive");
case XML_SCHEMA_FACET_MINEXCLUSIVE:
- return ("minExclusive");
+ return (BAD_CAST "minExclusive");
case XML_SCHEMA_FACET_MININCLUSIVE:
- return ("minInclusive");
+ return (BAD_CAST "minInclusive");
case XML_SCHEMA_FACET_WHITESPACE:
- return ("whiteSpace");
+ return (BAD_CAST "whiteSpace");
case XML_SCHEMA_FACET_ENUMERATION:
- return ("enumeration");
+ return (BAD_CAST "enumeration");
case XML_SCHEMA_FACET_LENGTH:
- return ("length");
+ return (BAD_CAST "length");
case XML_SCHEMA_FACET_MAXLENGTH:
- return ("maxLength");
+ return (BAD_CAST "maxLength");
case XML_SCHEMA_FACET_MINLENGTH:
- return ("minLength");
+ return (BAD_CAST "minLength");
case XML_SCHEMA_FACET_TOTALDIGITS:
- return ("totalDigits");
+ return (BAD_CAST "totalDigits");
case XML_SCHEMA_FACET_FRACTIONDIGITS:
- return ("fractionDigits");
+ return (BAD_CAST "fractionDigits");
default:
break;
}
- return ("Internal Error");
+ return (BAD_CAST "Internal Error");
}
static int
@@ -15641,6 +15755,68 @@
ctxt->node = oldnode;
}
+static int
+xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
+ const xmlChar *value,
+ xmlSchemaValPtr *val,
+ xmlNodePtr node)
+{
+ int ret;
+
+ ret = xmlValidateQName(value, 1);
+ if (ret != 0)
+ return (ret);
+
+ {
+ xmlChar *uri = NULL;
+ xmlChar *local = NULL;
+ xmlChar *prefix;
+
+ local = xmlSplitQName2(value, &prefix);
+ if (prefix != NULL) {
+ xmlNsPtr ns;
+
+ /*
+ * TODO: Make this streamable.
+ */
+ if ((node == NULL) || (node->doc == NULL)) {
+ xmlFree(prefix);
+ xmlFree(local);
+ return (3);
+ }
+
+ ns = xmlSearchNs(node->doc, node, prefix);
+ if (ns == NULL) {
+ xmlFree(prefix);
+ xmlFree(local);
+ return (1);
+ }
+ }
+ if (prefix != NULL) {
+ if (xmlHashLookup2(vctxt->schema->notaDecl, local, uri) == NULL)
+ ret = 1;
+ } else if (xmlHashLookup2(vctxt->schema->notaDecl, value,
+ NULL) == NULL)
+ ret = 1;
+
+ if ((ret == 0) && (val != NULL)) {
+ if (prefix != NULL) {
+ (*val) = xmlSchemaNewNOTATIONValue(BAD_CAST local,
+ BAD_CAST xmlStrdup(uri));
+ local = NULL;
+ } else
+ (*val) = xmlSchemaNewNOTATIONValue(BAD_CAST xmlStrdup(value),
+ NULL);
+ if (*val == NULL)
+ ret = -1;
+ }
+ if (local != NULL)
+ xmlFree(local);
+ }
+
+ return (ret);
+}
+
/**
* xmlSchemaValidateSimpleTypeValue:
* @ctxt: a schema validation context
@@ -15801,7 +15977,15 @@
/*
* STREAM-READ-CHILDREN.
*/
- ret = xmlSchemaValPredefTypeNodeNoNorm(type, value, &(ctxt->value), node);
+ if ((type->builtInType == XML_SCHEMAS_NOTATION) &&
+ (ctxt->schema != NULL)) {
+ /*
+ * NOTATIONs need to be processed here, since they need
+ * to lookup in the hashtable of NOTATION declarations.
+ */
+ ret = xmlSchemaValidateNotation(ctxt, value, &(ctxt->value), node);
+ } else
+ ret = xmlSchemaValPredefTypeNodeNoNorm(type, value, &(ctxt->value), node);
if (ret > 0) {
if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;