1

我有两个 xsd 文件。第一个文件是common.xsd,另一个是node.xsd. 两者node.xsdcommon.xsd共享相同targetNamespacecommon.xsd引用使用属性element中定义的。但是,不包括在using或. 但是我使用这些 xsd 文件验证的 XML 通过了验证(尝试了所有角落用例)。node.xsdrefnode.xsdcommon.xsdincludeimport

我想知道这怎么可能。这是因为它们共享相同的命名空间吗?在 XSD中引用一个element不包括/导入的合法吗?

编辑:

简化的代码片段(实际的 xsd 要复杂得多,出于更大的原因,它们以这种格式编写):

常见的.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:my="my-namespace"
        xmlns:xml="http://www.w3.org/XML/1998/namespace"
        targetNamespace="my-namespace"
        elementFormDefault="qualified">
  <xsd:element name="common" type="my:commonType" />
  <xsd:complexType name="commonType">
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="my:node"/>
      <!-- few other elements -->
    </xsd:choice>
  </xsd:complexType>
</xsd:schema>

节点.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:my="my-namespace"
        xmlns:xml="http://www.w3.org/XML/1998/namespace"
        targetNamespace="my-namespace"
        elementFormDefault="qualified">
  <xsd:include schemaLocation=common.xsd"/>
  <xsd:element name="node" type="my:nodeType"
           substitutionGroup="my:common" />
  <xsd:complexType name="nodeType">
    <xsd:complexContent>
      <xsd:extension base="my:commonType">
        <!-- some 5-7 attributes -->
        <xsd:anyAttribute/>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
</xsd:schema>

这些 xsd 让我可以在其自身内多次嵌套元素。例如

<my:node>
  <my:node />
  <my:node>
    <my:node />
  </my:node>
</my:node>

您可以观察到my:nodecommon.xsd不包括node.xsd. (好奇这甚至是如何工作的。)

4

1 回答 1

2

我可以让这看起来更邪恶...您可以删除xsd:includeinnode.xsd并仍然验证您的 XML!看看这个Xerces API,你可以如何做到这一点。

这个想法是,从规范的角度来看,XML Schema 处理器可以通过多种方式解析模式位置。这也意味着某些 XSD 文件在单独查看时可能由于悬空引用而无效,但是当通过上述 API 或自定义解析器(例如支持“目录”文件)组合在一起时,结果是一个等效的模式,即有效的。

XSD 处理器通常的工作方式是将所有可以通过它可以解析的引用加载的模式组件放在一起,然后将结果作为一个整体来查看,而不管这些组件来自何处。在您的情况下,node.xsd带来了common.xsdcommon.xsd结果是一个有效的模式,因为可以在已经引入的组件中找到组件 in 所需的所有内容node.xsd

在您的情况下,就好像 xsd:schema 标记 in 的内部内容common.xsd替换了xsd:includein node.xsd。如果您手动执行此操作,结果是正确的,对吗?

正如我旁注的那样,我要指出您显示的片段并未说明common替换组的使用。提醒一下,如果您希望进行替换,则必须参考替换组的负责人。

于 2012-10-08T19:04:23.520 回答