tags:

views:

251

answers:

1

I'm trying to use the IXMLDOMDocument2 interface (C++) to validate an Xml document against some schema and I'm getting the following error:

Duplicate named <element> : name = '{http://www.site.com/MySchema}envelope'.

I'm struggling to understand what this means - is there a problem with my schema, or is this a problem with the Xml? I've checked both the schema and the Xml and they both hardly even contain the word "envelope" twice!

The Xml:

<id:envelope xmlns:id="http://www.site.com/MySchema" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:schemaLocation="http://www.site.com/MySchema MySchema.xsd">
  <id/>
  <!-- Load of unimportant elements -->
</id:envelope>

The XSD:

<xsd:schema targetNamespace="http://www.site.com/MySchema" 
            xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
            xmlns="http://www.site.com/MySchema" elementFormDefault="unqualified">
    <xsd:element name="envelope" type="envelopeType">
        <!-- etc... -->
    </xsd:element>
    <xsd:complexType name="envelopeType">
        <!-- etc... -->
    </xsd:complexType>
    <!-- load of other types... -->
</xsd:schema>
A: 

I figured this out thanks to a comment left at the end of this page on MSDN:

In MSXML4, schemaLocation and noNamespaceSchemaLocation were never used during validation: you should use a SchemaCache containing the schemas against which the document was validated. This was fine, because it allowed me to use 'local' versions of the schemas that were referenced in the XML document.

In MSXML6, this was changed: "Inline schemas and schemas referenced from an instance using xsi:SchemaLocation are now added to an XML instance-specific cache which wraps the user-supplied SchemaCache." Now, when i use the SchemaCache and add the 'local' version of the schemas that were referenced in the XML document, i get this error message: "Duplicate named : name = 'ROOT'".

It seems both xsi:schemaLocation and the SchemaCache are used during validation resulting in a conflict. Ik know i can use ResolveExternal=False so xsi:schemaLocation won't be used, but in that case xsd:import/xsd:include are not resolved either, so that's not an option.

I found I could either remove the schemaLocation attribute from the input xml, or not explicitly add the MySchema.xsd document to the schema cache and valiation would succeed.

In the end I decided to remove the schemaLocation attribute as it preserves the existing behaviour - the Xml is only used internally and so there is no risk of breaking existing clients.

Kragen