我有两个xsd文件。第一个文件是common.xsd
,另一个是node.xsd
。 node.xsd
和common.xsd
都共享相同的targetNamespace
。 common.xsd
使用element
属性引用node.xsd
中定义的ref
。但是,使用node.xsd
或common.xsd
的{{1}}中未包含include
。但是我使用这些xsd文件验证的XML传递了验证(尝试了所有角落的用例)。
我想知道这是怎么回事。这是因为,它们共享相同的命名空间吗?还引用了import
而没有在XSD中包含/导入合法内容?
修改
简化的代码片段(实际的xsd更加复杂,并且出于更大的原因以这种格式编写):
common.xsd
element
node.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允许我在任何次数内嵌套元素。 E.g
<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>
您可以观察到<my:node>
<my:node />
<my:node>
<my:node />
</my:node>
</my:node>
中引用my:node
而未包括common.xsd
。 (好奇这是如何工作的。)
答案 0 :(得分:2)
我可以让这看起来更加邪恶......您可以移除xsd:include
中的node.xsd
并仍然验证您的XML!看一下这个Xerces API,了解如何做到这一点。
这个想法是从规范角度来看,XML Schema处理器可以通过多种方式解析模式位置。这也意味着单独查看时某些XSD文件可能由于悬空引用而无效,但是当通过上面的API将放在一起时,或者自定义解析器(例如支持“目录”文件)时结果是一个有效的等效架构。
XSD处理器通常的工作方式是,它将可以通过它可以解析的引用加载的所有模式组件放在一起,然后它将结果作为一个整体查看,而不管这些组件来自何处。在您的情况下, node.xsd 会带来 common.xsd ;结果是一个有效的模式,因为common.xsd
中的组件所需的全部内容都可以在node.xsd
引入的组件中找到。
在您的情况下,好像common.xsd
中xsd:schema标记的内部内容替换xsd:include
中的node.xsd
。如果你手工完成,结果是正确的,对吗?
正如我所注意的那样,我要指出您所展示的片段并未说明common
替换组的使用情况。提醒一下,如果您希望替换组,则必须引用替换组的头。