-1

我正在尝试使用 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>
4

1 回答 1

1

多亏了MSDN本页末尾留下的评论,我才知道这一点:

在 MSXML4 中,schemaLocation 和 noNamespaceSchemaLocation 在验证期间从未使用过:您应该使用包含验证文档所依据的架构的 SchemaCache。这很好,因为它允许我使用 XML 文档中引用的模式的“本地”版本。

在 MSXML6 中,这已更改:“使用 xsi:SchemaLocation 从实例引用的内联架构和架构现在添加到包装用户提供的 SchemaCache 的 XML 实例特定缓存中。” 现在,当我使用 SchemaCache 并添加 XML 文档中引用的模式的“本地”版本时,我收到此错误消息:“重复命名:名称 = 'ROOT'”。

在验证期间似乎同时使用了 xsi:schemaLocation 和 SchemaCache,从而导致冲突。我知道我可以使用 ResolveExternal=False 所以 xsi:schemaLocation 不会被使用,但在这种情况下 xsd:import/xsd:include 也不会被解析,所以这不是一个选项。

我发现我可以从输入 xml 中删除 schemaLocation 属性,或者不将 MySchema.xsd 文档显式添加到模式缓存中,并且验证会成功。

最后,我决定删除 schemaLocation 属性,因为它保留了现有行为 - Xml 仅在内部使用,因此不存在破坏现有客户端的风险。

于 2009-10-14T13:35:23.860 回答