summaryrefslogtreecommitdiff
path: root/xmlschemas.c
diff options
context:
space:
mode:
authorDaniel Veillard <veillard@src.gnome.org>2003-11-22 20:37:51 +0000
committerDaniel Veillard <veillard@src.gnome.org>2003-11-22 20:37:51 +0000
commitbe9c6320d4ed8d5622322014310555bb88b02a85 (patch)
tree78ce5b2cf4b5e4e602c7f28d57bb10bc42819f64 /xmlschemas.c
parent2b7142a1b305dad2131fab4ed2093becc80a2872 (diff)
downloadlibxml2-be9c6320d4ed8d5622322014310555bb88b02a85.tar.gz
lot of bug fixes, cleanup, starting to add proper namespace support too.
* xmlschemas.c xmlschemastypes.c include/libxml/xmlerror.h include/libxml/schemasInternals.h: lot of bug fixes, cleanup, starting to add proper namespace support too. * test/schemas/* result/schemas/*: added a number of tests fixed the result from some regression tests too. Daniel
Diffstat (limited to 'xmlschemas.c')
-rw-r--r--xmlschemas.c727
1 files changed, 453 insertions, 274 deletions
diff --git a/xmlschemas.c b/xmlschemas.c
index 6976cc7f..58a460eb 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -24,6 +24,7 @@
#include <libxml/xmlschemastypes.h>
#include <libxml/xmlautomata.h>
#include <libxml/xmlregexp.h>
+#include <libxml/dict.h>
/* #define DEBUG 1 */
@@ -67,11 +68,14 @@ struct _xmlSchemaParserCtxt {
int nberrors;
xmlStructuredErrorFunc serror;
+ xmlSchemaPtr topschema; /* The main schema */
+ xmlHashTablePtr namespaces; /* Hash table of namespaces to schemas */
+
xmlSchemaPtr schema; /* The schema in use */
- xmlChar *container; /* the current element, group, ... */
+ const xmlChar *container; /* the current element, group, ... */
int counter;
- xmlChar *URL;
+ const xmlChar *URL;
xmlDocPtr doc;
const char *buffer;
@@ -84,6 +88,8 @@ struct _xmlSchemaParserCtxt {
xmlAutomataStatePtr start;
xmlAutomataStatePtr end;
xmlAutomataStatePtr state;
+
+ xmlDictPtr dict; /* dictionnary for interned string names */
};
@@ -150,7 +156,7 @@ struct _xmlSchemaImport {
************************************************************************/
static int xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
xmlSchemaTypePtr type,
- xmlChar * value);
+ const xmlChar * value);
/************************************************************************
* *
@@ -343,6 +349,8 @@ xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
return (NULL);
}
memset(ret, 0, sizeof(xmlSchema));
+ xmlDictReference(ctxt->dict);
+ ret->dict = ctxt->dict;
return (ret);
}
@@ -419,7 +427,6 @@ xmlSchemaFreeImport(xmlSchemaImportPtr import)
return;
xmlSchemaFree(import->schema);
- xmlFree((xmlChar *) import->schemaLocation);
xmlFree(import);
}
@@ -434,8 +441,6 @@ xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
{
if (nota == NULL)
return;
- if (nota->name != NULL)
- xmlFree((xmlChar *) nota->name);
xmlFree(nota);
}
@@ -450,16 +455,6 @@ xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
{
if (attr == NULL)
return;
- if (attr->name != NULL)
- xmlFree((xmlChar *) attr->name);
- if (attr->ref != NULL)
- xmlFree((xmlChar *) attr->ref);
- if (attr->refNs != NULL)
- xmlFree((xmlChar *) attr->refNs);
- if (attr->typeName != NULL)
- xmlFree((xmlChar *) attr->typeName);
- if (attr->typeNs != NULL)
- xmlFree((xmlChar *) attr->typeNs);
xmlFree(attr);
}
@@ -474,12 +469,6 @@ xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attr)
{
if (attr == NULL)
return;
- if (attr->name != NULL)
- xmlFree((xmlChar *) attr->name);
- if (attr->ref != NULL)
- xmlFree((xmlChar *) attr->ref);
- if (attr->refNs != NULL)
- xmlFree((xmlChar *) attr->refNs);
xmlFree(attr);
}
@@ -494,16 +483,6 @@ xmlSchemaFreeElement(xmlSchemaElementPtr elem)
{
if (elem == NULL)
return;
- if (elem->name != NULL)
- xmlFree((xmlChar *) elem->name);
- if (elem->namedType != NULL)
- xmlFree((xmlChar *) elem->namedType);
- if (elem->namedTypeNs != NULL)
- xmlFree((xmlChar *) elem->namedTypeNs);
- if (elem->ref != NULL)
- xmlFree((xmlChar *) elem->ref);
- if (elem->refNs != NULL)
- xmlFree((xmlChar *) elem->refNs);
if (elem->annot != NULL)
xmlSchemaFreeAnnot(elem->annot);
if (elem->contModel != NULL)
@@ -522,10 +501,6 @@ xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
{
if (facet == NULL)
return;
- if (facet->value != NULL)
- xmlFree((xmlChar *) facet->value);
- if (facet->id != NULL)
- xmlFree((xmlChar *) facet->id);
if (facet->val != NULL)
xmlSchemaFreeValue(facet->val);
if (facet->regexp != NULL)
@@ -546,14 +521,6 @@ xmlSchemaFreeType(xmlSchemaTypePtr type)
{
if (type == NULL)
return;
- if (type->name != NULL)
- xmlFree((xmlChar *) type->name);
- if (type->ref != NULL)
- xmlFree((xmlChar *) type->ref);
- if (type->base != NULL)
- xmlFree((xmlChar *) type->base);
- if (type->baseNs != NULL)
- xmlFree((xmlChar *) type->baseNs);
if (type->annot != NULL)
xmlSchemaFreeAnnot(type->annot);
if (type->facets != NULL) {
@@ -581,12 +548,6 @@ xmlSchemaFree(xmlSchemaPtr schema)
if (schema == NULL)
return;
- if (schema->id != NULL)
- xmlFree((xmlChar *) schema->id);
- if (schema->targetNamespace != NULL)
- xmlFree((xmlChar *) schema->targetNamespace);
- if (schema->name != NULL)
- xmlFree((xmlChar *) schema->name);
if (schema->notaDecl != NULL)
xmlHashFree(schema->notaDecl,
(xmlHashDeallocator) xmlSchemaFreeNotation);
@@ -612,6 +573,7 @@ xmlSchemaFree(xmlSchemaPtr schema)
xmlSchemaFreeAnnot(schema->annot);
if (schema->doc != NULL)
xmlFreeDoc(schema->doc);
+ xmlDictFree(schema->dict);
xmlFree(schema);
}
@@ -856,12 +818,168 @@ xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
#endif /* LIBXML_OUTPUT_ENABLED */
/************************************************************************
+ * *
+ * Utilities *
+ * *
+ ************************************************************************/
+/**
+ * numberedString:
+ * @prefix: the string prefix
+ * @number: the number
+ *
+ * Build a new numbered string
+ *
+ * Returns the new string
+ */
+
+/**
+ * xmlSchemaGetProp:
+ * @ctxt: the parser context
+ * @node: the node
+ * @name: the property name
+ *
+ * Read a attribute value and internalize the string
+ *
+ * Returns the string or NULL if not present.
+ */
+static const xmlChar *
+xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
+ const char *name)
+{
+ xmlChar *val;
+ const xmlChar *ret;
+
+ val = xmlGetProp(node, BAD_CAST name);
+ if (val == NULL)
+ return(NULL);
+ ret = xmlDictLookup(ctxt->dict, val, -1);
+ xmlFree(val);
+ return(ret);
+}
+
+/**
+ * xmlSchemaGetNamespace:
+ * @ctxt: the parser context
+ * @schema: the schemas containing the declaration
+ * @node: the node
+ * @qname: the QName to analyze
+ *
+ * Find the namespace name for the given declaration.
+ *
+ * Returns the local name for that declaration, as well as the namespace name
+ */
+static const xmlChar *
+xmlSchemaGetNamespace(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
+ xmlNodePtr node, const xmlChar *qname,
+ const xmlChar **namespace) {
+ int len;
+ const xmlChar *name, *prefix, *def = NULL;
+ xmlNsPtr ns;
+
+ *namespace = NULL;
+
+ if (xmlStrEqual(node->name, BAD_CAST "element") ||
+ xmlStrEqual(node->name, BAD_CAST "attribute") ||
+ xmlStrEqual(node->name, BAD_CAST "simpleType") ||
+ xmlStrEqual(node->name, BAD_CAST "complexType")) {
+ def = xmlSchemaGetProp(ctxt, node, "targetNamespace");
+ }
+
+ qname = xmlDictLookup(ctxt->dict, qname, -1); /* intern the string */
+ name = xmlSplitQName3(qname, &len);
+ if (name == NULL) {
+ if (def == NULL) {
+ if (xmlStrEqual(node->name, BAD_CAST "element")) {
+ if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
+ *namespace = schema->targetNamespace;
+ } else if (xmlStrEqual(node->name, BAD_CAST "attribute")) {
+ if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
+ *namespace = schema->targetNamespace;
+ } else if ((xmlStrEqual(node->name, BAD_CAST "simpleType")) ||
+ (xmlStrEqual(node->name, BAD_CAST "complexType"))) {
+ *namespace = schema->targetNamespace;
+ }
+ } else {
+ *namespace = def;
+ }
+ return(qname);
+ }
+ name = xmlDictLookup(ctxt->dict, name, -1);
+ prefix = xmlDictLookup(ctxt->dict, qname, len);
+ if (def != NULL) {
+ xmlSchemaPErr(ctxt, node, XML_SCHEMAP_DEF_AND_PREFIX,
+ "%s: presence of both prefix %s and targetNamespace\n",
+ node->name, prefix);
+ }
+ ns = xmlSearchNs(node->doc, node, prefix);
+ if (ns == NULL) {
+ xmlSchemaPErr(ctxt, node, XML_SCHEMAP_PREFIX_UNDEFINED,
+ "%s: the QName prefix %s is undefined\n",
+ node->name, prefix);
+ return(name);
+ }
+ *namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
+ return(name);
+}
+
+/************************************************************************
* *
* Parsing functions *
* *
************************************************************************/
/**
+ * xmlSchemaGetElem:
+ * @schema: the schemas context
+ * @name: the element name
+ * @ns: the element namespace
+ *
+ * Lookup a an element in the schemas or the accessible schemas
+ *
+ * Returns the element definition or NULL if not found.
+ */
+static xmlSchemaElementPtr
+xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
+ const xmlChar * namespace)
+{
+ xmlSchemaElementPtr ret;
+ xmlSchemaImportPtr import;
+
+ if ((name == NULL) || (schema == NULL))
+ return (NULL);
+
+ if (namespace == NULL) {
+ ret = xmlHashLookup2(schema->elemDecl, name, namespace);
+ if (ret != NULL)
+ return (ret);
+ } 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)
+ return (ret);
+ } else {
+ ret = xmlHashLookup2(schema->elemDecl, name, namespace);
+ if (ret != NULL)
+ return (ret);
+ }
+ import = xmlHashLookup(schema->schemasImports, namespace);
+ if (import != NULL)
+ ret = xmlSchemaGetElem(import->schema, name, namespace);
+#ifdef DEBUG
+ if (ret == NULL) {
+ if (namespace == NULL)
+ fprintf(stderr, "Unable to lookup type %s", name);
+ else
+ fprintf(stderr, "Unable to lookup type %s:%s", name,
+ namespace);
+ }
+#endif
+ return (ret);
+}
+
+/**
* xmlSchemaGetType:
* @schema: the schemas context
* @name: the type name
@@ -965,7 +1083,7 @@ xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
return (NULL);
}
memset(ret, 0, sizeof(xmlSchemaNotation));
- ret->name = xmlStrdup(name);
+ ret->name = xmlDictLookup(ctxt->dict, name, -1);
val = xmlHashAddEntry2(schema->notaDecl, name, schema->targetNamespace,
ret);
if (val != 0) {
@@ -973,7 +1091,6 @@ xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
XML_SCHEMAP_REDEFINED_NOTATION,
"Notation %s already defined\n",
name, NULL);
- xmlFree((char *) ret->name);
xmlFree(ret);
return (NULL);
}
@@ -986,7 +1103,7 @@ xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
* @ctxt: a schema validation context
* @schema: the schema being built
* @name: the item name
- * @container: the container's name
+ * @namespace: the namespace
*
* Add an XML schema Attrribute declaration
* *WARNING* this interface is highly subject to change
@@ -995,7 +1112,7 @@ xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*/
static xmlSchemaAttributePtr
xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- const xmlChar * name)
+ const xmlChar * name, const xmlChar * namespace)
{
xmlSchemaAttributePtr ret = NULL;
int val;
@@ -1003,6 +1120,12 @@ xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
return (NULL);
+#ifdef DEBUG
+ fprintf(stderr, "Adding attribute %s\n", name);
+ if (namespace != NULL)
+ fprintf(stderr, " target namespace %s\n", namespace);
+#endif
+
if (schema->attrDecl == NULL)
schema->attrDecl = xmlHashCreate(10);
if (schema->attrDecl == NULL)
@@ -1014,7 +1137,8 @@ xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
return (NULL);
}
memset(ret, 0, sizeof(xmlSchemaAttribute));
- ret->name = xmlStrdup(name);
+ ret->name = xmlDictLookup(ctxt->dict, name, -1);
+ ret->targetNamespace = xmlDictLookup(ctxt->dict, namespace, -1);
val = xmlHashAddEntry3(schema->attrDecl, name,
schema->targetNamespace, ctxt->container, ret);
if (val != 0) {
@@ -1022,7 +1146,6 @@ xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
XML_SCHEMAP_REDEFINED_ATTR,
"Attribute %s already defined\n",
name, NULL);
- xmlFree((char *) ret->name);
xmlFree(ret);
return (NULL);
}
@@ -1062,7 +1185,7 @@ xmlSchemaAddAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
return (NULL);
}
memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
- ret->name = xmlStrdup(name);
+ ret->name = xmlDictLookup(ctxt->dict, name, -1);
val = xmlHashAddEntry3(schema->attrgrpDecl, name,
schema->targetNamespace, ctxt->container, ret);
if (val != 0) {
@@ -1070,7 +1193,6 @@ xmlSchemaAddAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
XML_SCHEMAP_REDEFINED_ATTRGROUP,
"Attribute group %s already defined\n",
name, NULL);
- xmlFree((char *) ret->name);
xmlFree(ret);
return (NULL);
}
@@ -1099,6 +1221,12 @@ xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
return (NULL);
+#ifdef DEBUG
+ fprintf(stderr, "Adding element %s\n", name);
+ if (namespace != NULL)
+ fprintf(stderr, " target namespace %s\n", namespace);
+#endif
+
if (schema->elemDecl == NULL)
schema->elemDecl = xmlHashCreate(10);
if (schema->elemDecl == NULL)
@@ -1110,13 +1238,14 @@ xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
return (NULL);
}
memset(ret, 0, sizeof(xmlSchemaElement));
- ret->name = xmlStrdup(name);
+ ret->name = xmlDictLookup(ctxt->dict, name, -1);
+ ret->targetNamespace = xmlDictLookup(ctxt->dict, namespace, -1);
val = xmlHashAddEntry3(schema->elemDecl, name,
namespace, ctxt->container, ret);
if (val != 0) {
char buf[100];
- snprintf(buf, 99, "privatieelem%d", ctxt->counter++ + 1);
+ snprintf(buf, 99, "privatieelem %d", ctxt->counter++ + 1);
val = xmlHashAddEntry3(schema->elemDecl, name, (xmlChar *) buf,
namespace, ret);
if (val != 0) {
@@ -1124,7 +1253,6 @@ xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
XML_SCHEMAP_REDEFINED_ELEMENT,
"Element %s already defined\n",
name, NULL);
- xmlFree((char *) ret->name);
xmlFree(ret);
return (NULL);
}
@@ -1137,6 +1265,7 @@ xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
* @ctxt: a schema validation context
* @schema: the schema being built
* @name: the item name
+ * @namespace: the namespace
*
* Add an XML schema Simple Type definition
* *WARNING* this interface is highly subject to change
@@ -1145,7 +1274,7 @@ xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
*/
static xmlSchemaTypePtr
xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
- const xmlChar * name)
+ const xmlChar * name, const xmlChar * namespace)
{
xmlSchemaTypePtr ret = NULL;
int val;
@@ -1153,6 +1282,12 @@ 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 = xmlHashCreate(10);
if (schema->typeDecl == NULL)
@@ -1164,15 +1299,13 @@ xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
return (NULL);
}
memset(ret, 0, sizeof(xmlSchemaType));
- ret->name = xmlStrdup(name);
- val = xmlHashAddEntry2(schema->typeDecl, name, schema->targetNamespace,
- ret);
+ ret->name = xmlDictLookup(ctxt->dict, name, -1);
+ val = xmlHashAddEntry2(schema->typeDecl, name, namespace, ret);
if (val != 0) {
xmlSchemaPErr(ctxt, (xmlNodePtr) ctxt->doc,
XML_SCHEMAP_REDEFINED_TYPE,
"Type %s already defined\n",
name, NULL);
- xmlFree((char *) ret->name);
xmlFree(ret);
return (NULL);
}
@@ -1213,7 +1346,7 @@ xmlSchemaAddGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
return (NULL);
}
memset(ret, 0, sizeof(xmlSchemaType));
- ret->name = xmlStrdup(name);
+ ret->name = xmlDictLookup(ctxt->dict, name, -1);
val =
xmlHashAddEntry2(schema->groupDecl, name, schema->targetNamespace,
ret);
@@ -1222,7 +1355,6 @@ xmlSchemaAddGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
XML_SCHEMAP_REDEFINED_GROUP,
"Group %s already defined\n",
name, NULL);
- xmlFree((char *) ret->name);
xmlFree(ret);
return (NULL);
}
@@ -1250,24 +1382,26 @@ xmlSchemaAddGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
* Returns the NCName or NULL if not found, and also update @namespace
* with the namespace URI
*/
-static xmlChar *
+static const xmlChar *
xmlGetQNameProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
- const char *name, xmlChar ** namespace)
+ const char *name, const xmlChar ** namespace)
{
- xmlChar *val, *ret, *prefix;
+ const xmlChar *val;
xmlNsPtr ns;
+ const xmlChar *ret, *prefix;
+ int len;
-
- if (namespace != NULL)
- *namespace = NULL;
- val = xmlGetProp(node, (const xmlChar *) name);
+ *namespace = NULL;
+ val = xmlSchemaGetProp(ctxt, node, name);
if (val == NULL)
return (NULL);
- ret = xmlSplitQName2(val, &prefix);
- if (ret == NULL)
+ ret = xmlSplitQName3(val, &len);
+ if (ret == NULL) {
return (val);
- xmlFree(val);
+ }
+ ret = xmlDictLookup(ctxt->dict, ret, -1);
+ prefix = xmlDictLookup(ctxt->dict, val, len);
ns = xmlSearchNs(node->doc, node, prefix);
if (ns == NULL) {
@@ -1275,9 +1409,8 @@ xmlGetQNameProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
"Attribute %s: the QName prefix %s is undefined\n",
(const xmlChar *) name, prefix);
} else {
- *namespace = xmlStrdup(ns->href);
+ *namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
}
- xmlFree(prefix);
return (ret);
}
@@ -1293,16 +1426,15 @@ xmlGetQNameProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
static int
xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
{
- xmlChar *val, *cur;
+ const xmlChar *val, *cur;
int ret = 0;
- val = xmlGetProp(node, (const xmlChar *) "maxOccurs");
+ val = xmlSchemaGetProp(ctxt, node, "maxOccurs");
if (val == NULL)
return (1);
if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
- xmlFree(val);
- return (UNBOUNDED); /* encoding it with -1 might be another option */
+ return (UNBOUNDED); /* encoding it with -1 might be another option */
}
cur = val;
@@ -1317,10 +1449,8 @@ xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
if (*cur != 0) {
xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MAXOCCURS,
"invalid value for maxOccurs: %s\n", val, NULL);
- xmlFree(val);
return (1);
}
- xmlFree(val);
return (ret);
}
@@ -1336,10 +1466,10 @@ xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
static int
xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
{
- xmlChar *val, *cur;
+ const xmlChar *val, *cur;
int ret = 0;
- val = xmlGetProp(node, (const xmlChar *) "minOccurs");
+ val = xmlSchemaGetProp(ctxt, node, "minOccurs");
if (val == NULL)
return (1);
@@ -1355,10 +1485,8 @@ xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
if (*cur != 0) {
xmlSchemaPErr(ctxt, node, XML_SCHEMAP_INVALID_MINOCCURS,
"invalid value for minOccurs: %s\n", val, NULL);
- xmlFree(val);
return (1);
}
- xmlFree(val);
return (ret);
}
@@ -1378,9 +1506,9 @@ static int
xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
const char *name, int def)
{
- xmlChar *val;
+ const xmlChar *val;
- val = xmlGetProp(node, (const xmlChar *) name);
+ val = xmlSchemaGetProp(ctxt, node, name);
if (val == NULL)
return (def);
@@ -1393,7 +1521,6 @@ xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
"Attribute %s: the value %s is not boolean\n",
(const xmlChar *) name, val);
}
- xmlFree(val);
return (def);
}
@@ -1533,7 +1660,7 @@ xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
{
xmlSchemaFacetPtr facet;
xmlNodePtr child = NULL;
- xmlChar *value;
+ const xmlChar *value;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
@@ -1544,7 +1671,7 @@ xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
return (NULL);
}
facet->node = node;
- value = xmlGetProp(node, (const xmlChar *) "value");
+ value = xmlSchemaGetProp(ctxt, node, "value");
if (value == NULL) {
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
"Facet %s has no value\n", node->name, NULL);
@@ -1581,7 +1708,7 @@ xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlSchemaFreeFacet(facet);
return (NULL);
}
- facet->id = xmlGetProp(node, (const xmlChar *) "id");
+ facet->id = xmlSchemaGetProp(ctxt, node, "id");
facet->value = value;
child = node->children;
@@ -1619,7 +1746,7 @@ xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
snprintf((char *) name, 30, "any %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
+ type = xmlSchemaAddType(ctxt, schema, name, NULL);
if (type == NULL)
return (NULL);
type->node = node;
@@ -1656,13 +1783,13 @@ static xmlSchemaNotationPtr
xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node)
{
- xmlChar *name;
+ const xmlChar *name;
xmlSchemaNotationPtr ret;
xmlNodePtr child = NULL;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
- name = xmlGetProp(node, (const xmlChar *) "name");
+ name = xmlSchemaGetProp(ctxt, node, "name");
if (name == NULL) {
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
"Notation has no name\n", NULL, NULL);
@@ -1670,7 +1797,6 @@ xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
}
ret = xmlSchemaAddNotation(ctxt, schema, name);
if (ret == NULL) {
- xmlFree(name);
return (NULL);
}
child = node->children;
@@ -1702,22 +1828,24 @@ static xmlSchemaAttributePtr
xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPtr schema, xmlNodePtr node)
{
- xmlChar *processContents;
+ const xmlChar *processContents;
xmlSchemaAttributePtr ret;
xmlNodePtr child = NULL;
char name[100];
+ const xmlChar *local, *ns;
+
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
snprintf(name, 99, "anyattr %d", ctxt->counter++ + 1);
- ret = xmlSchemaAddAttribute(ctxt, schema, (xmlChar *) name);
+ local = xmlSchemaGetNamespace(ctxt, schema, node, BAD_CAST "anyattr", &ns);
+ ret = xmlSchemaAddAttribute(ctxt, schema, BAD_CAST name, ns);
if (ret == NULL) {
return (NULL);
}
- ret->id = xmlGetProp(node, (const xmlChar *) "id");
- processContents =
- xmlGetProp(node, (const xmlChar *) "processContents");
+ ret->id = xmlSchemaGetProp(ctxt, node, "id");
+ processContents = xmlSchemaGetProp(ctxt, node, "processContents");
if ((processContents == NULL)
|| (xmlStrEqual(processContents, (const xmlChar *) "strict"))) {
ret->occurs = XML_SCHEMAS_ANYATTR_STRICT;
@@ -1732,8 +1860,6 @@ xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
processContents, NULL);
ret->occurs = XML_SCHEMAS_ANYATTR_STRICT;
}
- if (processContents != NULL)
- xmlFree(processContents);
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
@@ -1767,15 +1893,15 @@ static xmlSchemaAttributePtr
xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node)
{
- xmlChar *name, *refNs = NULL, *ref = NULL;
+ const xmlChar *name, *refNs = NULL, *ref = NULL;
xmlSchemaAttributePtr ret;
xmlNodePtr child = NULL;
+ char buf[100];
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
- name = xmlGetProp(node, (const xmlChar *) "name");
+ name = xmlSchemaGetProp(ctxt, node, "name");
if (name == NULL) {
- char buf[100];
ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
if (ref == NULL) {
@@ -1784,20 +1910,29 @@ xmlSchemaParseAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
"Attribute has no name nor ref\n", NULL, NULL);
return (NULL);
}
- snprintf(buf, 99, "anonattr%d", ctxt->counter++ + 1);
- name = xmlStrdup((xmlChar *) buf);
+ if (refNs == NULL)
+ refNs = schema->targetNamespace;
+ snprintf(buf, 99, "anonattr %d", ctxt->counter++ + 1);
+ name = (const xmlChar *) buf;
+ ret = xmlSchemaAddAttribute(ctxt, schema, name, NULL);
+ } else {
+ const xmlChar *local, *ns;
+
+ local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns);
+ ret = xmlSchemaAddAttribute(ctxt, schema, local, ns);
}
- ret = xmlSchemaAddAttribute(ctxt, schema, name);
if (ret == NULL) {
- xmlFree(name);
- if (ref != NULL)
- xmlFree(ref);
return (NULL);
}
- xmlFree(name);
ret->ref = ref;
ret->refNs = refNs;
+ if ((ret->targetNamespace != NULL) &&
+ ((schema->flags & XML_SCHEMAS_QUALIF_ATTR) == 0) &&
+ (xmlStrEqual(ret->targetNamespace, schema->targetNamespace)))
+ ret->flags |= XML_SCHEMAS_ATTR_NSDEFAULT;
ret->typeName = xmlGetQNameProp(ctxt, node, "type", &(ret->typeNs));
+ if ((ret->typeName != NULL) && (ret->typeNs == NULL))
+ ret->typeNs = schema->targetNamespace;
ret->node = node;
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
@@ -1832,18 +1967,18 @@ static xmlSchemaAttributeGroupPtr
xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
xmlSchemaPtr schema, xmlNodePtr node)
{
- xmlChar *name, *refNs = NULL, *ref = NULL;
+ const xmlChar *name, *refNs = NULL, *ref = NULL;
xmlSchemaAttributeGroupPtr ret;
xmlSchemaAttributePtr last = NULL, attr;
xmlNodePtr child = NULL;
- xmlChar *oldcontainer;
+ const xmlChar *oldcontainer;
+ char buf[100];
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
oldcontainer = ctxt->container;
- name = xmlGetProp(node, (const xmlChar *) "name");
+ name = xmlSchemaGetProp(ctxt, node, "name");
if (name == NULL) {
- char buf[100];
ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
if (ref == NULL) {
@@ -1853,8 +1988,10 @@ xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
NULL);
return (NULL);
}
- snprintf(buf, 99, "anonattrgroup%d", ctxt->counter++ + 1);
- name = xmlStrdup((xmlChar *) buf);
+ if (refNs == NULL)
+ refNs = schema->targetNamespace;
+ snprintf(buf, 99, "anonattrgroup %d", ctxt->counter++ + 1);
+ name = (const xmlChar *) buf;
if (name == NULL) {
xmlSchemaPErrMemory(ctxt, "creating attribute group", node);
return (NULL);
@@ -1862,9 +1999,6 @@ xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
}
ret = xmlSchemaAddAttributeGroup(ctxt, schema, name);
if (ret == NULL) {
- xmlFree(name);
- if (ref != NULL)
- xmlFree(ref);
return (NULL);
}
ret->ref = ref;
@@ -1898,7 +2032,8 @@ xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
child = child->next;
}
if (IS_SCHEMA(child, "anyAttribute")) {
- TODO child = child->next;
+ TODO
+ child = child->next;
}
if (child != NULL) {
xmlSchemaPErr2(ctxt, node, child,
@@ -1906,9 +2041,7 @@ xmlSchemaParseAttributeGroup(xmlSchemaParserCtxtPtr ctxt,
"attribute group %s has unexpected content\n", name,
NULL);
}
-
ctxt->container = oldcontainer;
- xmlFree(name);
return (ret);
}
@@ -1928,17 +2061,18 @@ static xmlSchemaElementPtr
xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlNodePtr node, int toplevel)
{
- xmlChar *name, *refNs = NULL, *ref = NULL, *namespace, *fixed;
+ const xmlChar *name, *fixed;
+ const xmlChar *refNs = NULL, *ref = NULL;
xmlSchemaElementPtr ret;
xmlNodePtr child = NULL;
- xmlChar *oldcontainer;
+ const xmlChar *oldcontainer;
+ char buf[100];
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
oldcontainer = ctxt->container;
- name = xmlGetProp(node, (const xmlChar *) "name");
+ name = xmlSchemaGetProp(ctxt, node, "name");
if (name == NULL) {
- char buf[100];
ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
if (ref == NULL) {
@@ -1947,23 +2081,20 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
"Element has no name nor ref\n", NULL, NULL);
return (NULL);
}
- snprintf(buf, 99, "anonelem%d", ctxt->counter++ + 1);
- name = xmlStrdup((xmlChar *) buf);
- }
- namespace = xmlGetProp(node, (const xmlChar *) "targetNamespace");
- if (namespace == NULL)
- ret =
- xmlSchemaAddElement(ctxt, schema, name,
- schema->targetNamespace);
- else
- ret = xmlSchemaAddElement(ctxt, schema, name, namespace);
- ret->node = node;
- if (namespace != NULL)
- xmlFree(namespace);
+ if (refNs == NULL)
+ refNs = schema->targetNamespace;
+ snprintf(buf, 99, "anonelem %d", ctxt->counter++ + 1);
+ name = (const xmlChar *) buf;
+ ret = xmlSchemaAddElement(ctxt, schema, name, NULL);
+ } else {
+ const xmlChar *local, *ns;
+
+ local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns);
+ ret = xmlSchemaAddElement(ctxt, schema, local, ns);
+ }
+ if (ret != NULL)
+ ret->node = node;
if (ret == NULL) {
- xmlFree(name);
- if (ref != NULL)
- xmlFree(ref);
return (NULL);
}
ret->type = XML_SCHEMA_TYPE_ELEMENT;
@@ -1979,22 +2110,23 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
ret->flags |= XML_SCHEMAS_ELEM_NILLABLE;
ctxt->container = name;
- ret->id = xmlGetProp(node, BAD_CAST "id");
+ ret->id = xmlSchemaGetProp(ctxt, node, "id");
ret->namedType =
xmlGetQNameProp(ctxt, node, "type", &(ret->namedTypeNs));
+ if ((ret->namedType != NULL) && (ret->namedTypeNs == NULL))
+ ret->namedTypeNs = schema->targetNamespace;
ret->substGroup =
xmlGetQNameProp(ctxt, node, "substitutionGroup",
&(ret->substGroupNs));
- fixed = xmlGetProp(node, BAD_CAST "fixed");
+ fixed = xmlSchemaGetProp(ctxt, node, "fixed");
ret->minOccurs = xmlGetMinOccurs(ctxt, node);
ret->maxOccurs = xmlGetMaxOccurs(ctxt, node);
- ret->value = xmlGetProp(node, BAD_CAST "default");
+ ret->value = xmlSchemaGetProp(ctxt, node, "default");
if ((ret->value != NULL) && (fixed != NULL)) {
xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_ELEM_DEFAULT_FIXED,
"Element %s has both default and fixed\n",
ret->name, NULL);
- xmlFree(fixed);
} else if (fixed != NULL) {
ret->flags |= XML_SCHEMAS_ELEM_FIXED;
ret->value = fixed;
@@ -2022,7 +2154,6 @@ xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
}
ctxt->container = oldcontainer;
- xmlFree(name);
return (ret);
}
@@ -2051,13 +2182,13 @@ xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
snprintf((char *) name, 30, "union %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
+ type = xmlSchemaAddType(ctxt, schema, name, NULL);
if (type == NULL)
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_LIST;
- type->id = xmlGetProp(node, BAD_CAST "id");
- type->ref = xmlGetProp(node, BAD_CAST "memberTypes");
+ type->id = xmlSchemaGetProp(ctxt, node, "id");
+ type->ref = xmlSchemaGetProp(ctxt, node, "memberTypes");
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
@@ -2111,13 +2242,15 @@ xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
return (NULL);
snprintf((char *) name, 30, "list %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
+ type = xmlSchemaAddType(ctxt, schema, name, NULL);
if (type == NULL)
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_LIST;
- type->id = xmlGetProp(node, BAD_CAST "id");
+ type->id = xmlSchemaGetProp(ctxt, node, "id");
type->ref = xmlGetQNameProp(ctxt, node, "ref", &(type->refNs));
+ if ((type->ref != NULL) && (type->refNs == NULL))
+ type->refNs = schema->targetNamespace;
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
@@ -2157,31 +2290,29 @@ xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
{
xmlSchemaTypePtr type, subtype;
xmlNodePtr child = NULL;
- xmlChar *name;
+ const xmlChar *name;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
- name = xmlGetProp(node, (const xmlChar *) "name");
+ name = xmlSchemaGetProp(ctxt, node, "name");
if (name == NULL) {
char buf[100];
- snprintf(buf, 99, "simpletype%d", ctxt->counter++ + 1);
- name = xmlStrdup((xmlChar *) buf);
- }
- if (name == NULL) {
- xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_SIMPLETYPE_NONAME,
- "simpleType has no name\n", NULL, NULL);
- return (NULL);
+ snprintf(buf, 99, "simpletype %d", ctxt->counter++ + 1);
+ type = xmlSchemaAddType(ctxt, schema, (const xmlChar *)buf, NULL);
+ } else {
+ const xmlChar *local, *ns;
+
+ local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns);
+ type = xmlSchemaAddType(ctxt, schema, local, ns);
}
- type = xmlSchemaAddType(ctxt, schema, name);
- xmlFree(name);
if (type == NULL)
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_SIMPLE;
- type->id = xmlGetProp(node, BAD_CAST "id");
+ type->id = xmlSchemaGetProp(ctxt, node, "id");
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
@@ -2232,15 +2363,16 @@ xmlSchemaParseGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
{
xmlSchemaTypePtr type, subtype;
xmlNodePtr child = NULL;
- xmlChar *name, *ref = NULL, *refNs = NULL;
+ const xmlChar *name;
+ const xmlChar *ref = NULL, *refNs = NULL;
+ char buf[100];
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
- name = xmlGetProp(node, (const xmlChar *) "name");
+ name = xmlSchemaGetProp(ctxt, node, "name");
if (name == NULL) {
- char buf[100];
ref = xmlGetQNameProp(ctxt, node, "ref", &refNs);
if (ref == NULL) {
@@ -2249,17 +2381,18 @@ xmlSchemaParseGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
"Group has no name nor ref\n", NULL, NULL);
return (NULL);
}
- snprintf(buf, 99, "anongroup%d", ctxt->counter++ + 1);
- name = xmlStrdup((xmlChar *) buf);
+ if (refNs == NULL)
+ refNs = schema->targetNamespace;
+ snprintf(buf, 99, "anongroup %d", ctxt->counter++ + 1);
+ name = (const xmlChar *) buf;
}
type = xmlSchemaAddGroup(ctxt, schema, name);
- xmlFree(name);
if (type == NULL)
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_GROUP;
- type->id = xmlGetProp(node, BAD_CAST "id");
+ type->id = xmlSchemaGetProp(ctxt, node, "id");
type->ref = ref;
type->refNs = refNs;
type->minOccurs = xmlGetMinOccurs(ctxt, node);
@@ -2319,12 +2452,12 @@ xmlSchemaParseAll(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
snprintf((char *) name, 30, "all%d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
+ type = xmlSchemaAddType(ctxt, schema, name, NULL);
if (type == NULL)
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_ALL;
- type->id = xmlGetProp(node, BAD_CAST "id");
+ type->id = xmlSchemaGetProp(ctxt, node, "id");
type->minOccurs = xmlGetMinOccurs(ctxt, node);
type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
@@ -2393,7 +2526,7 @@ xmlSchemaImportSchema(xmlSchemaParserCtxtPtr ctxt,
}
memset(import, 0, sizeof(xmlSchemaImport));
- import->schemaLocation = xmlStrdup(schemaLocation);
+ import->schemaLocation = xmlDictLookup(ctxt->dict, schemaLocation, -1);
import->schema = xmlSchemaParse(newctxt);
if (import->schema == NULL) {
@@ -2432,8 +2565,8 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
{
xmlNodePtr child = NULL;
xmlSchemaImportPtr import = NULL;
- xmlChar *namespace;
- xmlChar *schemaLocation;
+ const xmlChar *namespace;
+ const xmlChar *schemaLocation;
const xmlChar *previous;
xmlURIPtr check;
@@ -2441,7 +2574,7 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (-1);
- namespace = xmlGetProp(node, BAD_CAST "namespace");
+ namespace = xmlSchemaGetProp(ctxt, node, "namespace");
if (namespace != NULL) {
check = xmlParseURI((const char *) namespace);
if (check == NULL) {
@@ -2449,13 +2582,12 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI,
"Import namespace attribute is not an URI: %s\n",
namespace, NULL);
- xmlFree(namespace);
return (-1);
} else {
xmlFreeURI(check);
}
}
- schemaLocation = xmlGetProp(node, BAD_CAST "schemaLocation");
+ schemaLocation = xmlSchemaGetProp(ctxt, node, "schemaLocation");
if (schemaLocation != NULL) {
xmlChar *base = NULL;
xmlChar *URI = NULL;
@@ -2465,9 +2597,6 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI,
"Import schemaLocation attribute is not an URI: %s\n",
schemaLocation, NULL);
- if (namespace != NULL)
- xmlFree(namespace);
- xmlFree(schemaLocation);
return (-1);
} else {
xmlFreeURI(check);
@@ -2477,11 +2606,11 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
URI = xmlBuildURI(schemaLocation, node->doc->URL);
} else {
URI = xmlBuildURI(schemaLocation, base);
+ xmlFree(base);
}
- if (base != NULL) xmlFree(base);
if (URI != NULL) {
- xmlFree(schemaLocation);
- schemaLocation = URI;
+ schemaLocation = xmlDictLookup(ctxt->dict, URI, -1);
+ xmlFree(URI);
}
}
if (schema->schemasImports == NULL) {
@@ -2491,10 +2620,6 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
XML_SCHEMAP_FAILED_BUILD_IMPORT,
"Internal: failed to build import table\n",
NULL, NULL);
- if (namespace != NULL)
- xmlFree(namespace);
- if (schemaLocation != NULL)
- xmlFree(schemaLocation);
return (-1);
}
}
@@ -2517,17 +2642,12 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
} else {
import = xmlSchemaImportSchema(ctxt, schemaLocation);
if (import == NULL) {
- if (schemaLocation != NULL)
- xmlFree(schemaLocation);
- if (namespace != NULL)
- xmlFree(namespace);
return (-1);
}
xmlHashAddEntry(schema->schemasImports,
XML_SCHEMAS_DEFAULT_NAMESPACE,
import);
}
- xmlFree(schemaLocation);
}
} else {
import = xmlHashLookup(schema->schemasImports, namespace);
@@ -2547,20 +2667,13 @@ xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
} else {
import = xmlSchemaImportSchema(ctxt, schemaLocation);
if (import == NULL) {
- if (schemaLocation != NULL)
- xmlFree(schemaLocation);
- if (namespace != NULL)
- xmlFree(namespace);
return (-1);
}
xmlHashAddEntry(schema->schemasImports,
namespace, import);
}
}
- xmlFree(namespace);
}
- if (schemaLocation != NULL)
- xmlFree(schemaLocation);
child = node->children;
while (IS_SCHEMA(child, "annotation")) {
@@ -2602,12 +2715,12 @@ xmlSchemaParseChoice(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
snprintf((char *) name, 30, "choice %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
+ type = xmlSchemaAddType(ctxt, schema, name, NULL);
if (type == NULL)
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_CHOICE;
- type->id = xmlGetProp(node, BAD_CAST "id");
+ type->id = xmlSchemaGetProp(ctxt, node, "id");
type->minOccurs = xmlGetMinOccurs(ctxt, node);
type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
@@ -2680,12 +2793,12 @@ xmlSchemaParseSequence(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
snprintf((char *) name, 30, "sequence %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
+ type = xmlSchemaAddType(ctxt, schema, name, NULL);
if (type == NULL)
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_SEQUENCE;
- type->id = xmlGetProp(node, BAD_CAST "id");
+ type->id = xmlSchemaGetProp(ctxt, node, "id");
type->minOccurs = xmlGetMinOccurs(ctxt, node);
type->maxOccurs = xmlGetMaxOccurs(ctxt, node);
@@ -2754,7 +2867,7 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlSchemaFacetPtr facet, lastfacet = NULL;
xmlNodePtr child = NULL;
xmlChar name[30];
- xmlChar *oldcontainer;
+ const xmlChar *oldcontainer;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
@@ -2762,12 +2875,12 @@ xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
oldcontainer = ctxt->container;
snprintf((char *) name, 30, "restriction %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
+ type = xmlSchemaAddType(ctxt, schema, name, NULL);
if (type == NULL)
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_RESTRICTION;
- type->id = xmlGetProp(node, BAD_CAST "id");
+ type->id = xmlSchemaGetProp(ctxt, node, "id");
type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
if ((!simple) && (type->base == NULL)) {
xmlSchemaPErr2(ctxt, node, child,
@@ -2867,7 +2980,7 @@ xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
xmlSchemaTypePtr type, subtype;
xmlNodePtr child = NULL;
xmlChar name[30];
- xmlChar *oldcontainer;
+ const xmlChar *oldcontainer;
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
@@ -2875,12 +2988,12 @@ xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
oldcontainer = ctxt->container;
snprintf((char *) name, 30, "extension %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
+ type = xmlSchemaAddType(ctxt, schema, name, NULL);
if (type == NULL)
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_EXTENSION;
- type->id = xmlGetProp(node, BAD_CAST "id");
+ type->id = xmlSchemaGetProp(ctxt, node, "id");
ctxt->container = name;
type->base = xmlGetQNameProp(ctxt, node, "base", &(type->baseNs));
@@ -2945,12 +3058,12 @@ xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
snprintf((char *) name, 30, "complexContent %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
+ type = xmlSchemaAddType(ctxt, schema, name, NULL);
if (type == NULL)
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_SIMPLE_CONTENT;
- type->id = xmlGetProp(node, BAD_CAST "id");
+ type->id = xmlSchemaGetProp(ctxt, node, "id");
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
@@ -3001,12 +3114,12 @@ xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
snprintf((char *) name, 30, "complexContent %d", ctxt->counter++ + 1);
- type = xmlSchemaAddType(ctxt, schema, name);
+ type = xmlSchemaAddType(ctxt, schema, name, NULL);
if (type == NULL)
return (NULL);
type->node = node;
type->type = XML_SCHEMA_TYPE_COMPLEX_CONTENT;
- type->id = xmlGetProp(node, BAD_CAST "id");
+ type->id = xmlSchemaGetProp(ctxt, node, "id");
child = node->children;
if (IS_SCHEMA(child, "annotation")) {
@@ -3050,34 +3163,32 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
{
xmlSchemaTypePtr type, subtype;
xmlNodePtr child = NULL;
- xmlChar *name;
- xmlChar *oldcontainer;
+ const xmlChar *name;
+ const xmlChar *oldcontainer;
+ char buf[100];
if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
return (NULL);
oldcontainer = ctxt->container;
- name = xmlGetProp(node, (const xmlChar *) "name");
+ name = xmlSchemaGetProp(ctxt, node, "name");
if (name == NULL) {
- char buf[100];
- snprintf(buf, 99, "anontype%d", ctxt->counter++ + 1);
- name = xmlStrdup((xmlChar *) buf);
- }
- if (name == NULL) {
- xmlSchemaPErr2(ctxt, node, child,
- XML_SCHEMAP_COMPLEXTYPE_NONAME_NOREF,
- "complexType has no name\n", NULL, NULL);
- return (NULL);
+ snprintf(buf, 99, "anontype %d", ctxt->counter++ + 1);
+ name = (const xmlChar *)buf;
+ type = xmlSchemaAddType(ctxt, schema, name, NULL);
+ } else {
+ const xmlChar *local, *ns;
+
+ local = xmlSchemaGetNamespace(ctxt, schema, node, name, &ns);
+ type = xmlSchemaAddType(ctxt, schema, local, ns);
}
- type = xmlSchemaAddType(ctxt, schema, name);
if (type == NULL) {
- xmlFree(name);
return (NULL);
}
type->node = node;
type->type = XML_SCHEMA_TYPE_COMPLEX;
- type->id = xmlGetProp(node, BAD_CAST "id");
+ type->id = xmlSchemaGetProp(ctxt, node, "id");
ctxt->container = name;
child = node->children;
@@ -3118,7 +3229,6 @@ xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
type->name, NULL);
}
ctxt->container = oldcontainer;
- xmlFree(name);
return (type);
}
@@ -3140,7 +3250,7 @@ xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
xmlSchemaPtr schema = NULL;
xmlSchemaAnnotPtr annot;
xmlNodePtr child = NULL;
- xmlChar *val;
+ const xmlChar *val;
int nberrors;
if ((ctxt == NULL) || (node == NULL))
@@ -3152,11 +3262,15 @@ xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
schema = xmlSchemaNewSchema(ctxt);
if (schema == NULL)
return (NULL);
- schema->targetNamespace =
- xmlGetProp(node, BAD_CAST "targetNamespace");
- schema->id = xmlGetProp(node, BAD_CAST "id");
- schema->version = xmlGetProp(node, BAD_CAST "version");
- val = xmlGetProp(node, BAD_CAST "elementFormDefault");
+ val = xmlSchemaGetProp(ctxt, node, "targetNamespace");
+ if (val != NULL) {
+ schema->targetNamespace = xmlDictLookup(ctxt->dict, val, -1);
+ } else {
+ schema->targetNamespace = NULL;
+ }
+ schema->id = xmlSchemaGetProp(ctxt, node, "id");
+ schema->version = xmlSchemaGetProp(ctxt, node, "version");
+ val = xmlSchemaGetProp(ctxt, node, "elementFormDefault");
if (val != NULL) {
if (xmlStrEqual(val, BAD_CAST "qualified"))
schema->flags |= XML_SCHEMAS_QUALIF_ELEM;
@@ -3166,9 +3280,10 @@ xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
"Invalid value %s for elementFormDefault\n",
val, NULL);
}
- xmlFree(val);
- }
- val = xmlGetProp(node, BAD_CAST "attributeFormDefault");
+ } else {
+ schema->flags |= XML_SCHEMAS_QUALIF_ELEM;
+ }
+ val = xmlSchemaGetProp(ctxt, node, "attributeFormDefault");
if (val != NULL) {
if (xmlStrEqual(val, BAD_CAST "qualified"))
schema->flags |= XML_SCHEMAS_QUALIF_ATTR;
@@ -3178,8 +3293,7 @@ xmlSchemaParseSchema(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
"Invalid value %s for attributeFormDefault\n",
val, NULL);
}
- xmlFree(val);
- }
+ }
child = node->children;
while ((IS_SCHEMA(child, "include")) ||
@@ -3290,7 +3404,8 @@ xmlSchemaNewParserCtxt(const char *URL)
return (NULL);
}
memset(ret, 0, sizeof(xmlSchemaParserCtxt));
- ret->URL = xmlStrdup((const xmlChar *) URL);
+ ret->dict = xmlDictCreate();
+ ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
return (ret);
}
@@ -3364,10 +3479,9 @@ xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
{
if (ctxt == NULL)
return;
- if (ctxt->URL != NULL)
- xmlFree(ctxt->URL);
if (ctxt->doc != NULL)
xmlFreeDoc(ctxt->doc);
+ xmlDictFree(ctxt->dict);
xmlFree(ctxt);
}
@@ -3769,7 +3883,8 @@ xmlSchemaBuildContentModel(xmlSchemaElementPtr elem,
}
if (elem->subtypes->type != XML_SCHEMA_TYPE_COMPLEX)
return;
- if (elem->subtypes->contentType == XML_SCHEMA_CONTENT_BASIC)
+ if ((elem->subtypes->contentType == XML_SCHEMA_CONTENT_BASIC) ||
+ (elem->subtypes->contentType == XML_SCHEMA_CONTENT_SIMPLE))
return;
#ifdef DEBUG_CONTENT
@@ -3832,8 +3947,7 @@ xmlSchemaRefFixupCallback(xmlSchemaElementPtr elem,
name, NULL);
return;
}
- elemDecl = xmlHashLookup2(ctxt->schema->elemDecl,
- elem->ref, elem->refNs);
+ elemDecl = xmlSchemaGetElem(ctxt->schema, elem->ref, elem->refNs);
if (elemDecl == NULL) {
xmlSchemaPErr(ctxt, elem->node, XML_SCHEMAP_UNKNOWN_REF,
@@ -3906,9 +4020,13 @@ xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl,
}
typeDecl->baseType = baseType;
}
- if (typeDecl->subtypes == NULL)
- /* 1.1.1 */
- typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
+ if (typeDecl->subtypes == NULL)
+ if (typeDecl->baseType != NULL)
+ typeDecl->contentType =
+ typeDecl->baseType->contentType;
+ else
+ /* 1.1.1 */
+ typeDecl->contentType = XML_SCHEMA_CONTENT_EMPTY;
else if ((typeDecl->subtypes->subtypes == NULL) &&
((typeDecl->subtypes->type ==
XML_SCHEMA_TYPE_ALL)
@@ -4055,6 +4173,8 @@ xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl,
case XML_SCHEMA_FACET_MAXLENGTH:
case XML_SCHEMA_FACET_MINLENGTH:
typeDecl->contentType = XML_SCHEMA_CONTENT_SIMPLE;
+ if (typeDecl->subtypes != NULL)
+ xmlSchemaTypeFixup(typeDecl->subtypes, ctxt, NULL);
break;
}
}
@@ -4608,7 +4728,7 @@ xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
static int
xmlSchemaValidateFacets(xmlSchemaValidCtxtPtr ctxt,
xmlSchemaTypePtr base,
- xmlSchemaFacetPtr facets, xmlChar * value)
+ xmlSchemaFacetPtr facets, const xmlChar * value)
{
int ret = 0;
int tmp = 0;
@@ -4661,7 +4781,7 @@ xmlSchemaValidateFacets(xmlSchemaValidCtxtPtr ctxt,
*/
static int
xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
- xmlSchemaTypePtr type, xmlChar * value)
+ xmlSchemaTypePtr type, const xmlChar * value)
{
int ret = 0;
@@ -4691,8 +4811,9 @@ xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
if (base != NULL) {
ret = xmlSchemaValidateSimpleValue(ctxt, base, value);
} else if (type->subtypes != NULL) {
-
+ TODO
}
+
/*
* Do not validate facets when working on building the Schemas
*/
@@ -4712,7 +4833,8 @@ xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
TODO}
} else if (type->type == XML_SCHEMA_TYPE_LIST) {
xmlSchemaTypePtr base;
- xmlChar *cur, *end, tmp;
+ const xmlChar *cur, *end;
+ xmlChar *tmp;
int ret2;
base = type->subtypes;
@@ -4731,16 +4853,16 @@ xmlSchemaValidateSimpleValue(xmlSchemaValidCtxtPtr ctxt,
end++;
if (end == cur)
break;
- tmp = *end;
- *end = 0;
- ret2 = xmlSchemaValidateSimpleValue(ctxt, base, cur);
+ tmp = xmlStrndup(cur, end - cur);
+ ret2 = xmlSchemaValidateSimpleValue(ctxt, base, tmp);
+ xmlFree(tmp);
if (ret2 != 0)
ret = 1;
- *end = tmp;
cur = end;
} while (*cur != 0);
} else {
- TODO}
+ TODO
+ }
return (ret);
}
@@ -4871,8 +4993,13 @@ xmlSchemaValidateSimpleContent(xmlSchemaValidCtxtPtr ctxt,
}
break;
}
+ case XML_SCHEMA_TYPE_EXTENSION:{
+ TODO
+ break;
+ }
default:
- TODO}
+ TODO
+ }
if (value != NULL)
xmlFree(value);
@@ -5278,7 +5405,8 @@ xmlSchemaValidateComplexType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
switch (type->contentType) {
case XML_SCHEMA_CONTENT_EMPTY:
- if (child != NULL) {
+ if (type->baseType != NULL) {
+ } else if (child != NULL) {
xmlSchemaVErr(ctxt, node, XML_SCHEMAS_ERR_NOTEMPTY, "Element %s is supposed to be empty\n", node->name, NULL);
}
if (type->attributes != NULL) {
@@ -5334,6 +5462,22 @@ xmlSchemaValidateComplexType(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr node)
ctxt->type = type;
break;
}
+ case XML_SCHEMA_CONTENT_SIMPLE:{
+ if (type->subtypes != NULL) {
+ ctxt->type = type->subtypes;
+ xmlSchemaValidateComplexType(ctxt, node);
+ }
+ if (type->baseType != NULL) {
+ ctxt->type = type->baseType;
+ xmlSchemaValidateComplexType(ctxt, node);
+ }
+ if (type->attributes != NULL) {
+ xmlSchemaValidateAttributes(ctxt, node,
+ type->attributes);
+ }
+ ctxt->type = type;
+ break;
+ }
default:
TODO xmlGenericError(xmlGenericErrorContext,
"unimplemented content type %d\n",
@@ -5577,10 +5721,23 @@ xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem,
if (!xmlStrEqual(attr->name, attributes->name))
continue;
/*
- * TODO: handle the mess about namespaces here.
+ * handle the namespaces checks here
*/
- if ((attr->ns != NULL) /* || (attributes->ns != NULL) */ ) {
- TODO}
+ if (attr->ns == NULL) {
+ /*
+ * accept an unqualified attribute only if the declaration
+ * is unqualified or if the schemas allowed it.
+ */
+ if ((attributes->targetNamespace != NULL) &&
+ ((attributes->flags & XML_SCHEMAS_ATTR_NSDEFAULT) == 0))
+ continue;
+ } else {
+ if (attributes->targetNamespace == NULL)
+ continue;
+ if (!xmlStrEqual(attributes->targetNamespace,
+ attr->ns->href))
+ continue;
+ }
}
ctxt->cur = (xmlNodePtr) attributes;
if (attributes->subtypes == NULL) {
@@ -5620,12 +5777,24 @@ xmlSchemaValidateElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
xmlSchemaElementPtr elemDecl;
int ret, attrBase;
- if (elem->ns != NULL)
+ if (elem->ns != NULL) {
elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
elem->name, elem->ns->href, NULL);
- else
+ } else {
+ elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
+ elem->name, NULL, NULL);
+ }
+ /*
+ * special case whe elementFormDefault is unqualified for top-level elem.
+ */
+ if ((elemDecl == NULL) && (elem->ns != NULL) &&
+ (elem->parent != NULL) && (elem->parent->type != XML_ELEMENT_NODE) &&
+ (xmlStrEqual(ctxt->schema->targetNamespace, elem->ns->href)) &&
+ ((ctxt->schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0)) {
elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
elem->name, NULL, NULL);
+ }
+
/*
* 3.3.4 : 1
*/
@@ -5713,6 +5882,16 @@ xmlSchemaValidateDocument(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
else
elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
root->name, NULL, NULL);
+ /*
+ * special case whe elementFormDefault is unqualified for top-level elem.
+ */
+ if ((elemDecl == NULL) && (root->ns != NULL) &&
+ (xmlStrEqual(ctxt->schema->targetNamespace, root->ns->href)) &&
+ ((ctxt->schema->flags & XML_SCHEMAS_QUALIF_ELEM) == 0)) {
+ elemDecl = xmlHashLookup3(ctxt->schema->elemDecl,
+ root->name, NULL, NULL);
+ }
+
if (elemDecl == NULL) {
xmlSchemaVErr(ctxt, root, XML_SCHEMAS_ERR_UNDECLAREDELEM, "Element %s not declared\n", root->name, NULL);
} else if ((elemDecl->flags & XML_SCHEMAS_ELEM_TOPLEVEL) == 0) {