diff options
Diffstat (limited to 'xmlschemas.c')
-rw-r--r-- | xmlschemas.c | 727 |
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) { |