[xml] XML Schema QNames



I've seen what appears to be a bug in the handling of type names in XML
schema handler of libxml2. These type names are referred to as QNames in the XML
schema standard.

See:
http://www.w3.org/TR/xmlschema-1/#section-Constraints-on-XML-Representations-of-Schemas

The issue can be illustrated with the schema:

<schema xmlns='http://www.w3.org/2001/XMLSchema'
  targetNamespace='http://my.ns/'>
<element name='my' type='string'/>
</schema>

Here, the omitted prefix in 'string' is treated as NS http://my.ns/, when it should really be http://www.w3.org/2001/XMLSchema

Attached is a patch.ns + 2 new tests which modifies xmlschemas.c:xmlGetQNameProp so that it returns default namespace if prefix is omitted for Qname. The patch also _removes_ 'fallback' to targetNamespace, which IMHO is not to be used.

Removing this fallback made test po1_0.xsd fail. It turned out that this schema had two bad type references with omitted prefixes (when that was not allowed). Patch for po1_0.xsd is part of patch.ns.

-- Adam

Index: xmlschemas.c
===================================================================
RCS file: /cvs/gnome/gnome-xml/xmlschemas.c,v
retrieving revision 1.51
diff -u -r1.51 xmlschemas.c
--- xmlschemas.c        24 Jan 2004 08:31:28 -0000      1.51
+++ xmlschemas.c        4 Mar 2004 23:08:35 -0000
@@ -1492,6 +1492,13 @@
     if (val == NULL)
         return (NULL);
 
+    if (!strchr(val, ':')) {
+       ns = xmlSearchNs(node->doc, node, 0);
+       if (ns) {
+           *namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
+           return (val);
+       }
+    }
     ret = xmlSplitQName3(val, &len);
     if (ret == NULL) {
         return (val);
@@ -2006,8 +2013,6 @@
                            "Attribute has no name nor ref\n", NULL, NULL);
             return (NULL);
         }
-       if (refNs == NULL)
-           refNs = schema->targetNamespace;
         snprintf(buf, 99, "anonattr %d", ctxt->counter++ + 1);
         name = (const xmlChar *) buf;
        ret = xmlSchemaAddAttribute(ctxt, schema, name, NULL);
@@ -2027,8 +2032,6 @@
        (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")) {
@@ -2084,8 +2087,6 @@
                            NULL);
             return (NULL);
         }
-       if (refNs == NULL)
-           refNs = schema->targetNamespace;
         snprintf(buf, 99, "anonattrgroup %d", ctxt->counter++ + 1);
         name = (const xmlChar *) buf;
         if (name == NULL) {
@@ -2177,8 +2178,6 @@
                            "Element has no name nor ref\n", NULL, NULL);
             return (NULL);
         }
-       if (refNs == NULL)
-           refNs = schema->targetNamespace;
         snprintf(buf, 99, "anonelem %d", ctxt->counter++ + 1);
         name = (const xmlChar *) buf;
        ret = xmlSchemaAddElement(ctxt, schema, name, NULL);
@@ -2209,8 +2208,6 @@
     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));
@@ -2345,8 +2342,6 @@
     type->type = XML_SCHEMA_TYPE_LIST;
     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")) {
Index: test/schemas/po1_0.xsd
===================================================================
RCS file: /cvs/gnome/gnome-xml/test/schemas/po1_0.xsd,v
retrieving revision 1.1
diff -u -r1.1 po1_0.xsd
--- test/schemas/po1_0.xsd      11 May 2003 20:16:09 -0000      1.1
+++ test/schemas/po1_0.xsd      4 Mar 2004 23:08:42 -0000
@@ -17,7 +17,7 @@
       <xsd:element name="shipTo" type="po:USAddress"/>
       <xsd:element name="billTo" type="po:USAddress"/>
       <xsd:element ref="comment" minOccurs="0"/>
-      <xsd:element name="items" type="Items"/>
+      <xsd:element name="items" type="po:Items"/>
     </xsd:sequence>
     <xsd:attribute name="orderDate" type="xsd:date"/>
   </xsd:complexType>
@@ -48,7 +48,7 @@
             <xsd:element ref="comment" minOccurs="0"/>
             <xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
           </xsd:sequence>
-          <xsd:attribute name="partNum" type="SKU" use="required"/>
+          <xsd:attribute name="partNum" type="po:SKU" use="required"/>
         </xsd:complexType>
       </xsd:element>
     </xsd:sequence>
<my xmlns='http://my.ns/'
some</my>
<schema xmlns='http://www.w3.org/2001/XMLSchema' targetNamespace='http://my.ns/'>
 <element name='my' type='string'/>
</schema>
<m:my xmlns:m='http://my.ns/' m:other='1'>content</m:my>
<schema xmlns:my='http://my.ns/'
        xmlns='http://www.w3.org/2001/XMLSchema'
        targetNamespace='http://my.ns/'
        >
 <attribute name='other' type='string'/>
 <element name='my'>
   <complexType>
     <simpleContent>
       <extension base='string'>
         <attribute ref='my:other'/>
       </extension>
     </simpleContent>
   </complexType>
 </element>
</schema>
./test/schemas/ns1_0.xml validates
./test/schemas/ns2_0.xml validates


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]