Types 子类型仅从父类型重新定义一个元素
在XSD文件中,用户希望定义:Types 子类型仅从父类型重新定义一个元素,types,xsd,overriding,children,Types,Xsd,Overriding,Children,在XSD文件中,用户希望定义: 父类型(包含10个节点) a 7个子类型(每个子类型包含相同的10个节点,但第2个节点的类型不同) 可以通过限制父类型(父类型将是子类型的基类型)来定义子类型。问题是:在子类型中,我必须再次写入父类型的所有节点(不仅仅是第二个节点)。问题:我可以只写我覆盖的节点(第二个节点)吗? 示例:如果我定义以下父类型: <xs:complexType name="Parent"> <xs:sequence> <xs:
- 父类型(包含10个节点)
- a 7个子类型(每个子类型包含相同的10个节点,但第2个节点的类型不同)
<xs:complexType name="Parent">
<xs:sequence>
<xs:element name="Node1" type="type1" />
<xs:element name="Node2" type="type2" />
<xs:element name="Node3" type="type3" />
...
<xs:element name="Node10" type="type10" />
</xs:sequence>
</xs:complexType>
...
然后,我必须通过限制父母来定义孩子:
<xs:complexType name="Child1">
<xs:complexContent>
<xs:restriction base="Parent">
<xs:sequence>
<xs:element name="Node1" type="type1" />
<xs:element name="Node2" type="type2_derived_1" />
<xs:element name="Node3" type="type3" />
...
<xs:element name="Node10" type="type10" />
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Child2">
<xs:complexContent>
<xs:restriction base="Parent">
<xs:sequence>
<xs:element name="Node1" type="type1" />
<xs:element name="Node2" type="type2_derived_2" />
<xs:element name="Node3" type="type3" />
...
<xs:element name="Node10" type="type10" />
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
...
(same for all the 10 childs)
...
...
...
(所有10个孩子的情况相同)
这是大量的写代码和重复代码(对于每个子节点,我必须重新编写已经在父节点上的所有原始节点)。我更愿意只写我要覆盖的节点,如下所示:
<xs:complexType name="Child1">
<xs:complexContent>
<xs:restriction base="Parent">
<xs:changed>
<xs:element name="Node2" type="type2_derived_1" />
</xs:changed>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Child2">
<xs:complexContent>
<xs:restriction base="Parent">
<xs:changed>
<xs:element name="Node2" type="type2_derived_2" />
</xs:changed>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
...
(same for all the 10 childs)
...
(所有10个孩子的情况相同)
有没有办法避免代码重复?我使用的是XSD1.1,所以我可以使用它的所有高级功能
我知道我可以使用扩展而不是限制:例如,我可以从父类型中排除第二个节点,并通过扩展在子类型中添加它。但是,在这种情况下,它不是第二个节点,而是第十个节点。我想重新定义(或添加)子节点上的第二个节点
更新:已解决:我喜欢Sperberg McQueen:模型组提供的解决方案。模型组就像C中的宏,其内容是扩展的。因此,我可以为更改节点之前的节点定义一个模型组,并为更改节点之后的节点定义另一个模型组。例如:
<xs:group name="g_node_1">
<xs:sequence>
<xs:element name="Node1" type="type1"/>
</xs:sequence>
</xs:group>
<xs:group name="g_nodes_3to10">
<xs:sequence>
<xs:element name="Node3" type="type3"/>
<xs:element name="Node4" type="type4"/>
<xs:element name="Node5" type="type5"/>
<xs:element name="Node6" type="type6"/>
<xs:element name="Node7" type="type7"/>
<xs:element name="Node8" type="type8"/>
<xs:element name="Node9" type="type9"/>
<xs:element name="Node10" type="type10"/>
</xs:sequence>
</xs:group>
<xs:complexType name="Parent">
<xs:sequence>
<xs:group ref="g_node_1"/>
<xs:element name="Node2" type="type2"/>
<xs:group ref="g_nodes_3to10"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Child1">
<xs:complexContent>
<xs:restriction base="Parent">
<xs:sequence>
<xs:group ref="g_node_1"/>
<xs:element name="Node2" type="type2_derived_1" />
<xs:group ref="g_nodes_3to10"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Child2">
<xs:complexContent>
<xs:restriction base="Parent">
<xs:sequence>
<xs:group ref="g_node_1"/>
<xs:element name="Node2" type="type2_derived_2" />
<xs:group ref="g_nodes_3to10"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
它需要比理想解决方案多2行(每种类型),但总比没有好。如果不重复内容模型,就无法直接定义所需的关系。有一些可能的解决办法 避免重复的一种方法是:对内容模型的不变部分使用通用实体。(如果您不幸使用的XSD验证器不支持对模式文档使用DTD,那么您需要使用xmllint或rxp之类的工具来扩展实体,或者在将模式文档提供给验证器之前对其运行XSLT标识转换。) 另一种方法:对内容模型的不变部分使用命名模型组 第三种方法有时是可能的,这取决于
type2
、type2\u派生的\u 1
、type2\u派生的\u 2
等如何相互关联:使用断言将第二个孩子强制成您想要的形状