我有这样的XML:
<type>
<mainType>...</mainType>
<subtype>...<subtype>
</type>
mainTypes是受限制的xs:strings(它们的列表)。每个mainType都有一个可能的子类型列表。 IE:
mainTypeA有可能的子类型:subtype1,subtype2,subtype3
mainTypeB有可能的子类型:subtype4,subtype5
如何在XSD中表示这一点,以便每个子类型枚举都专门与其主要类型相关联? 有没有更好的方法来表示这两个字段,使XSD更简单?我并不反对更改XML文档结构。
答案 0 :(得分:6)
(这可能是@hughadick的答案中的另一个评论,但对于这样的话太长了。)
初始设计中存在两个问题,这会使结构复杂化:
<subType>
只有在<mainType>
出现时才能显示<type>
的孩子们)<mainType>
)<subType>
元素)。在XML Schema 1.0中,没有一般方法可以使这些功能成为可能,尽管在某些情况下和/或某些方法可以实现这些功能。模糊类型问题的一种可能的解决方法是在实例文档中使用xsi:type
属性来确定使用的模式类型(示例1)。
我建议你不要使用一些可能的解决方法来解决这些问题,而是要关注@hughadick的answer,并为所有主要类型创建不同名称的元素,这些元素对于不同的子类型将再次具有不同的元素。如果您不喜欢将类型名称作为元素名称(或者它不是对XML元素名称有效),您可以将其放在属性中,可能使用默认值或固定值(<myType1 typeName="Type 1 name">
)(例2)。如果子类型是互斥的,您可以将它们放在属性(<myType1 subType="subType2">
)中。如果你真的想在元素内容(<mainType1>Type 1 name</mainType1>
)中有类型名称,那么最好将<subType>
元素作为以下兄弟而不是<mainType1>
的子元素,因为那样会导致混合内容容易导致空白和文本节点位置相关的问题(例3)。
是的,替换组也可以与@hughadick的答案一起使用。您将拥有一个抽象的<mainType>
元素,并且所有主要类型元素定义都具有substitutionGroup="mainType"
属性。您仍然需要为不同的主要类型元素使用不同的名称,因为它们允许不同的允许元素/值集合。这些元素的类型必须从它们替换的抽象<mainType>
元素的类型派生(例4)。
<xs:element name="type">
<xs:complexType>
<xs:choice>
<xs:element name="mainType" type="mainType1"/>
<xs:element name="mainType" type="mainType2"/>
<xs:element name="mainType" type="mainType3"/>
</xs:choice>
</xs:complexType>
</xs:element>
<type>
<mainType xsi:type="mainType1"/>
</type>
<xs:element name="mainType1">
<xs:complexType>
<xs:choice>
<xs:element ref="subType1"/>
<xs:element ref="subType2"/>
<xs:element ref="subType3"/>
</xs:choice>
<xs:attribute name="typeName" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="type">
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element name="mainType" type="mainType1"/>
<xs:choice>
<xs:element ref="subType1"/>
<xs:element ref="subType2"/>
<xs:element ref="subType3"/>
</xs:choice>
</xs:sequence>
<!-- repeat similarily for other main types -->
<xs:sequence>
<!-- ... -->
</xs:sequence>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="type">
<xs:complexType>
<xs:sequence>
<xs:element ref="mainType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="mainType" type="mainType" abstract="true"/>
<xs:element name="mainType1" type="typeForMainType1" substitutionGroup="mainType"/>
<xs:element name="mainType2" type="typeForMainType2" substitutionGroup="mainType"/>
<xs:complexType name="mainType">
<!-- definition for mainType -->
</xs:complexType>
<xs:complexType name="typeForMainType1">
<xs:complexContent>
<xs:restriction base="mainType">
<!-- definition for mainType1 -->
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="typeForMainType2">
<xs:complexContent>
<xs:restriction base="mainType">
<!-- definition for mainType1 -->
</xs:restriction>
</xs:complexContent>
</xs:complexType>
答案 1 :(得分:3)
您需要明确将类型定义为包含主类型和子类型。在每个关键时刻,您明确定义该点的可能性:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:choice>
<xs:element name="MyType1" type="MyType1Type" />
<xs:element name="MyType2" type="MyType2Type" />
</xs:choice>
</xs:complexType>
</xs:element>
<!-- MainType definitiions -->
<xs:complexType name="MyType1Type>
<xs:all minOccurs="1">
<xs:element name="MyType1SubType1" type="MyType1SubType1Type" />
<xs:element name="MyType1SubType2" type="MyType1SubType2Type" />
<xs:element name="MyType1SubType3" type="MyType1SubType3Type" />
</xs:all>
</xs:complexType>
<xs:complexType name="MyType2Type>
<xs:all minOccurs="1">
<xs:element name="MyType2SubType4" type="MyType2SubType4Type" />
<xs:element name="MyType2SubType5" type="MyType2SubType5Type" />
</xs:all>
</xs:complexType>
<!-- SubType definitions -->
<xs:complexType name="MyType1SubType1Type>
<xs:sequence>
<xs:element name="MyType1SubType1TypeValue" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="MyType1SubType2Type>
<xs:sequence>
<xs:element name="MyType1SubType2TypeValue" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="MyType1SubType3Type>
<xs:sequence>
<xs:element name="MyType1SubType3TypeValue" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="MyType2SubType4Type>
<xs:sequence>
<xs:element name="MyType2SubType4TypeValue" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="MyType2SubType5Type>
<xs:sequence>
<xs:element name="MyType2SubType5TypeValue" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
所以它有点长,但在XSD中几乎没有捷径。您需要确定所有类型的定义。希望这会有所帮助。
答案 2 :(得分:0)
XML有很多不同的选择。你只需要根据自己的需要来构建它。对我来说,我喜欢在可能的情况下使用属性,这只是个人偏好。这只是一个建议。
<types>
<type name="mainTypeA">
<subType name="subType1"></subType>
<subType name="subType2"></subType>
<subType name="subType3"></subType>
</type>
<type name="mainTypeB">
<subType name="subType4"></subType>
<subType name="subType5"></subType>
<subType name="subType6"></subType>
</type>
</types>
另一个建议:
<type name="MainTypeA">
<type name="subType1"></type>
<type name="subtype2"></type>
</type>
<type name="MainTypeB">
<type name="subType3">
<type name="subSubType1"></type>
</type>
<type name="subtype4"></type>
</type>
答案 3 :(得分:0)
<type>
<name>MainTypeA</name>
<type>
<name>subtype1</name>
</type>
<type>
<name>subtype1</name>
</type>
</type>
或
<type name="MainTypeA">
...
<type name="subtype1">
...
</type>
<type name="subtype2">
...
</type>
</type>
这无限地允许子类型等。子类型本质上与类型不同吗?如果没有,则无需为它们创建单独的subType
标记。任何深度的所有类型的统一标签名称都可以使分析更容易。