我正在尝试使用IXMLDOMDocument2接口(C ++)来针对某些架构验证Xml文档,我收到以下错误:
Duplicate named <element> : name = '{http://www.site.com/MySchema}envelope'.
我很难理解这意味着什么 - 我的架构是否有问题,或者这是Xml的问题?我已经检查了架构和Xml,它们几乎都没有包含“信封”这个词两次!
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>
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>
答案 0 :(得分:1)
我想通过MSDN上this page末尾留下的评论来解决这个问题:
在MSXML4中,在验证期间从未使用schemaLocation和noNamespaceSchemaLocation:您应该使用包含验证文档的模式的SchemaCache。这很好,因为它允许我使用XML文档中引用的模式的“本地”版本。
在MSXML6中,这被改变了:“使用xsi:SchemaLocation从实例引用的内联模式和模式现在被添加到一个特定于XML实例的缓存中,该缓存包装了用户提供的SchemaCache。”现在,当我使用SchemaCache并添加XML文档中引用的模式的“本地”版本时,我收到以下错误消息:“Duplicate named:name ='ROOT'”。
似乎在验证过程中使用xsi:schemaLocation和SchemaCache导致冲突。我知道我可以使用ResolveExternal = False,因此不会使用xsi:schemaLocation,但是在这种情况下xsd:import / xsd:include也没有被解析,所以这不是一个选项。
我发现我可以从输入xml中删除schemaLocation属性,或者不将MySchema.xsd文档显式添加到模式缓存中,并且valiation会成功。
最后,我决定删除schemaLocation属性,因为它保留了现有行为 - Xml仅在内部使用,因此不存在破坏现有客户端的风险。