缺少 targetNamespace 导致架构异常

Absense of targetNamespace causing exceptions to schema

我试图理解为什么缺少 targetNamespace 会导致示例 XML 架构中出现以下错误。如果我删除 targetNamespace (targetNamespace="http://tempuri.org/XMLSchema1.xsd"),我会收到以下错误:

Namespace 'http://tempuri.org/XMLSchema1.xsd' is not available to be referenced in this schema. XMLSchema1.xsd 30

The 'http://tempuri.org/XMLSchema1.xsd:ChildNamePK' identity constraint is not declared. XMLSchema1.xsd 30

如果我重新添加 targetNamespace,这些错误就会消失,但这实际上是来自 sql 注释模式的示例,我为了这个 post 的目的缩短了它。由于所有元素都是本地元素,因此我想删除真实模式中的 targetNamespace。如何在不添加 targetNamespace 的情况下更正模式?

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="XMLSchema1"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/XMLSchema1.xsd"
    xmlns:mstns="http://tempuri.org/XMLSchema1.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Parent">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Child" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Name" type="xs:string" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="OldestChild">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Name" type="xs:string" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
    <xs:key name="ChildNamePK">
      <xs:selector xpath=".//Child" />
      <xs:field xpath="Name" />
    </xs:key>
    <xs:keyref name="OldestChildFK" refer="ChildNamePK">
      <xs:selector xpath=".//OldestChild" />
      <xs:field xpath="Name" />
    </xs:keyref>
  </xs:element>
</xs:schema>

这里的问题是行:

xmlns="http://tempuri.org/XMLSchema1.xsd"

这一行表示任何没有命名空间前缀的 QName 都应被视为命名空间 http://tempuri.org/XMLSchema1.xsd。这称为默认命名空间。

xs:keyref 元素中的 refer 属性是这些 QName 之一,您设置的值是 ChildNamePK,它没有命名空间前缀。由于没有名称空间前缀,并且您已经定义了默认名称空间,因此 XML 架构有效地将其视为

refer="{http://tempuri.org/XMLSchema1.xsd}ChildNamePK"

即就好像它引用了 http://tempuri.org/XMLSchema1.xsd 命名空间中的 ChildNamePK 元素。

但是,通过删除 targetNamespace,您表示您的元素(包括 ChildNamePK 键)不在命名空间中。所以 refer 属性引用实际上并不存在。这就是第二个错误试图告诉你的——它正在寻找 http://tempuri.org/XMLSchema1.xsd:ChildNamePK' 但它不存在。

此处正确的解决方案可能是只删除 xmlns="..." 行,这样就没有默认名称空间了。这样,refer 属性将引用不在命名空间中的 QName,这正是您删除 targetNamespace 行时的 ChildNamePK。