这完全取决于您将如何定义处理模型。以下是您需要首先考虑的一些事项。
any
粒子不能被类型约束。它带有一个名为skipprocessContents
、lax和默认值strict的属性。一旦您确切理解了它的含义,那么使用skip仅仅意味着您将无法强制执行您的强制属性 - 处理器将执行此操作,“跳过”。如果你设置它lax,那么它只会在描述内容的 XSD 实际可用时才处理它,否则它会跳过;第三个选项strict,要求描述此额外内容的 XSD 可用 - period。
因此,any
只有在验证期间描述“任何”的 XSD 可用时,才能使粒子工作。我想到的选项有点限制,但它的优点是最接近 any 的“精神”,因为它不必从特定的基本类型派生或引用某些属性;为此,类似于您的要求的关键约束:
<xsd:key name="ofid">
<xsd:selector xpath="*"/>
<xsd:field xpath="@id"/>
</xsd:key>
实际上,键使属性成为必需。缺点可能是每个值也必须是唯一的。也许有一个名为 的属性id
,这是预期的;相反,如果您希望将模式应用于诸如 之类的东西age
,那么它就行不通了。
如果您认为 XSD 在运行时可用是可以接受的,那么其他替代方案可能包括使用抽象元素或具有抽象类型的元素。好消息是它会带来更严格的方法(您将从一开始就明确设置约束),并且不会设置值约束的唯一性。不利的一面可能是它创建了与另一个描述“合同”的 XSD 的耦合 - 您的强制属性。
更新:根据您的评论,以下是基于替代组的替代方案。我尝试尽可能多地保留旧的 XSD 组件名称。
Contract.xsd:这包含您的合同的组成部分。它基本上描述了您的替代小组的负责人;它表明需要一个 id 属性。
<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="AnyChildType" abstract="true">
<xsd:attribute name="id" use="required"/>
</xsd:complexType>
<xsd:element name="AnyElement" abstract="true" type="AnyChildType"/>
</xsd:schema>
GenericInstance.xsd:它描述了“通用”文档的根。它在您定义的根元素的上下文中“集成”您的合同。
<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:include schemaLocation="Contract.xsd"/>
<xsd:element name="AnyElements" type="AnyRootType"/>
<xsd:complexType name="AnyRootType">
<xsd:sequence>
<xsd:element ref="AnyElement" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
SpecificInstance1.xsd:特定合约。
<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:include schemaLocation="Contract.xsd"/>
<xsd:element name="SomeElement1" substitutionGroup="AnyElement">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="AnyChildType">
<xsd:annotation>
<xsd:documentation>Any content goes.</xsd:documentation>
</xsd:annotation>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
SpecificInstance2.xsd:另一个合同(显示不同的创作风格)。
<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:include schemaLocation="Contract.xsd"/>
<xsd:element name="SomeElement2" substitutionGroup="AnyElement" type="SomeElement2Type"/>
<xsd:complexType name="SomeElement2Type">
<xsd:complexContent>
<xsd:extension base="AnyChildType">
<xsd:annotation>
<xsd:documentation>Any content goes.</xsd:documentation>
</xsd:annotation>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
从视觉上看,这就是它们是如何联系在一起的。您可以看到 XSD 之间的耦合保持在最低限度。
一个示例 XML,在您的通用实例和特定实例定义的范围内有效。
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<AnyElements xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SomeElement1 id="1"/>
<SomeElement2 id="1"/>
</AnyElements>
如果您仅限于使用一个 XSD 验证您的 XML,那么下面将是一个 XSD:
<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:include schemaLocation="GenericInstance.xsd"/>
<xsd:include schemaLocation="SpecificInstance1.xsd"/>
<xsd:include schemaLocation="SpecificInstance2.xsd"/>
</xsd:schema>
我已经使用在 .NET 上运行的 XSD 1.0 测试了上述内容;能够在 XSD 1.1 或其他 XSD 处理器中的特定功能上运行将使我所说的某些内容无效。