在XSD文件中,想要定义:
可以通过限制父类型来定义子类型(父类型将是子类型的基类型)来完成。问题:在子类型中,我必须再次写入父类型的所有节点(不仅是第二个节点)。问题:我是否只能编写我要覆盖的节点(第二个节点)?
示例:如果我定义以下父类型:
<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)
这是很多写和DUPLICATED代码(对于每个孩子,我必须写AGAIN所有原始节点,已经在父节点)。我更愿意只编写我要覆盖的节点,如下所示:
<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)
有没有办法避免重复代码?我正在使用XSD 1.1,所以我可以使用它的所有高级功能。
我知道我可以使用扩展而不是限制:例如,我可以从父类型中排除第二个节点,并在子节点上通过扩展名添加它。但是,在这种情况下,它不会是第二个节点,它将是第10个节点。我想重新定义(或添加)孩子们的第二个节点。
更新:已解决:我喜欢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行(每种类型),但它总比没有好。
答案 0 :(得分:1)
没有重复内容模型,没有直接的方法来定义您想要的关系。有一些可能的解决方法。
避免重复的一种方法:将一般实体用于内容模型的不变部分。 (如果您不幸使用不支持将DTD用于架构文档的XSD验证器,您需要使用xmllint或rxp等工具扩展实体,或者运行XSLT在将模式文档提供给验证器之前,对模式文档进行身份转换。)
另一种方法:将命名模型组用于内容模型的不变部分。
有时可能采用第三种方式,具体取决于type2
,type2_derived_1
,type2_derived_2
等相互关联的方式:使用断言强制第二个孩子进入您想要的形状。