XSD 架构 - 多次使用相同的命名空间

XSD Schema - same namespace used multiple times

我正在尝试理解 XSD 架构。我不能 post 原始模式,但它有点如下。 我遇到的问题是我不明白为什么同一个命名空间(http://www.test.com/test)被引用两次,一次有前缀,一次没有前缀。这有效吗?如果是,它有什么作用?

此外,在为此 XSD 生成 XML 时,我是否使用前缀?

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.test.com/test" 
xmlns:pre="http://www.test.com/test" targetNamespace="http://www.test.com/test" 
elementFormDefault="qualified" attributeFormDefault="unqualified"> 
  <xs:complexType name="StudentType">
    <xs:sequence>
      <xs:element name="studentId" type="xs:token" />
      <xs:element name="firstName" type="xs:token"/>
      <xs:element name="middleName" type="xs:token" minOccurs="0"/>
      <xs:element name="lastName" type="xs:token"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element name="students">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="student" type="StudentType" minOccurs="0" maxOccurs="unbounded">
          <xs:unique name="uniqueStudentId">
            <xs:selector xpath="pre:studentId"/>
            <xs:field xpath="."/>
          </xs:unique>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

不带前缀的命名空间成为默认命名空间,因此它下面的所有元素自动属于该命名空间,除非它们被明确地限定为不同的。

现在是带前缀的命名空间 - 我看不出有任何理由不允许它。至于它的用途,我不确定,但我猜想这可能与层次结构中其他覆盖命名空间的可能性有关?

我想再次强调,这是猜测,但想象一下你有这样的事情:

<root xmlns="http://my.default.ns" xmlns:def="http://my.default.ns">
    <class id="1">
        <student>
            This will automatically belong to https://my.default.ns
        </student>
    </class>
    <class id="2" xmlns="http://especially.bright.pupils">
        <student>
            This will belong to http://especially.bright.pupils
        </student>
        <def:student>
          NOTE: THIS student should still belong to https://my.default.ns, 
          since the element prefix relates to the namespace in the root element,
          which has not been overridden. The DEFAULT namespace (without prefix),
          has been overridden at this point, by the namespace defined in the 
          second <class>-element. 
        </def:student>
     </class>
</root>

在这里,"default" 学生使用 <def:student> 的显式命名阻止了它被下面的新默认命名空间覆盖。

请注意,如果下面重新定义 xmlns:def,它仍然可以被覆盖 - 它不会被默认命名空间覆盖。


更新以回应下面的评论(希望我正确理解你的问题):

命名空间本身由URI定义,所以是同一个命名空间;这两个对该名称空间的引用的作用是明确指定:

  • 默认情况下,此点以下的所有元素都属于命名空间 http://www.test.com/test(即,除非它们被覆盖,或者有一些链接到不同命名空间的前缀)
  • 此点以下具有 前缀 pre: 的元素将属于命名空间 http://www.test.com/test

换句话说,这是两个(完全有效的)命名空间声明,它们恰好引用同一个命名空间。

请记住,命名空间本质上只是一个名称,它用于sorting/organizing 在其他方面可能看起来相同的事物。

至于 TargetNamespaces 的用途,请参阅 this question

这种事情在XSD中很常见。

targetNamespace 定义架构文档中定义的顶级元素、类型等的名称空间。这些声明的 "name" 属性是本地名称(不能加前缀),定义关联命名空间的唯一方法是使用 targetNamespace 声明。

xmlns="http://www.test.com/test" 声明影响没有前缀的名称引用,例如 type="StudentType":这隐含地引用了本地名称为 "StudentType" 的类型命名空间“http://www.test.com/test”。

xmlns:pre="http://www.test.com/test" 声明影响带有显式前缀 "pre" 的名称引用。这是必需的,因为架构在 xs:selector 和 xs:field 中包含 XPath 表达式。 XPath 规范说,如果没有前缀,名称将引用不在名称空间中的名称,因此在名称空间中引用名称的唯一方法是分配前缀。

所以您得到了三个影响模式文档中出现的不同名称的声明。