我有一个包含以下类型的模式,它本质上包含与游戏mods相对应的元素列表:
<xs:complexType name="OrderedModTemplateType">
<xs:sequence minOccurs="1" maxOccurs="1">
...
<xs:element name="Mods" type="mods:ModsType" minOccurs="1">
<xs:key name="modKey">
<xs:selector xpath="Mods"/>
<xs:field xpath="@id"/>
</xs:key>
</xs:element>
</xs:sequence>
...
</xs:complexType>包含mods列表的ModsType类型如下所示:
<xs:complexType name="ModsType">
<xs:sequence>
<xs:element name="Mod" type="ModType" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType> 这是ModType类型,ModsType希望它作为子类型:
<xs:complexType name="ModType">
<xs:sequence minOccurs="0" maxOccurs="1">
...
</xs:sequence>
...
<xs:anyAttribute/>
</xs:complexType>我想创建一个更具体的OrderedModTemplateType,与上面发布的完全相同,但Mods元素中的Mod元素必须是更具体的派生类型的Mod,特别是Fallout3ModType:
<xs:complexType name="Fallout3ModType">
<xs:complexContent>
<xs:extension base="mods:ModType">
<xs:attribute name="requiresFose" type="xs:integer" default="0" />
<xs:attribute name="foseVersion" type="xs:string" />
</xs:extension>
</xs:complexContent>
</xs:complexType>因此,我知道我可以通过在元素中指定xsi:type来使用Fallout3ModType类型的Mod元素,但是如果我希望元素只包含Fallout3ModType类型的元素,而不是包含特定类型的元素,比如ModType (默认情况下是接受的类型)呢?
我不想这么做:
<Mods>
<Mod xsi:type="Fallout3ModType" ...>
...
</Mod>
<Mod xsi:type="Fallout3ModType" ...>
...
</Mod>
</Mods>我是否可以将ModsType扩展到Fallout3ModsType,它只接受Fallout3ModType的Mod元素,而不仅仅是ModType?如果是这样的话,我可以使用这样的东西:
<Mods xsi:type="Fallout3ModsType">
<Mod ...>
...
</Mod>
<Mod ...>
...
</Mod>
</Mods>或者,我可以以某种方式将OrderedModTemplateType扩展为Fallout3ModsType类型的Mods元素而不是ModsType吗?在这种情况下,我可以使用新类型来简化XML中的使用:
<Mods>
<Mod ...>
...
</Mod>
<Mod ...>
...
</Mod>
</Mods>我真的很想弄清楚我是在用正确的方式做这件事,还是错过了什么.
更新
这似乎证实了这一点,但我有一种感觉,这是不对的:
<xs:complexType name="Fallout3ModsType">
<xs:complexContent>
<xs:extension base="mods:ModsType">
<xs:sequence>
<xs:element name="Mod" type="Fallout3ModType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>这不是本质上定义了另一个单独的Mod元素,它的类型仅与原始Mod元素不同吗?如果这是合法的,解析器如何知道我指的是哪个元素而不深入研究嵌套元素?
还是我偶然发现了用更具体类型覆盖类型的正确方法?我怀疑..。
更新2删除了一些与问题无关的模式信息。还有点长抱歉..。
发布于 2011-04-05 23:50:06
如果使用substitutionGroup并可能使用抽象元素,则应该能够执行以下操作:
<Mods>
<Mod />
<Fallout3Mod />
<Mod />
</Mods>示例xsd:
<xs:complexType name="ModsType">
<xs:sequence>
<xs:element ref="mods:ModAbstract" maxOccurs="unbounded" ></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ModType">
<xs:sequence minOccurs="0" maxOccurs="1"> </xs:sequence>
<xs:anyAttribute/>
</xs:complexType>
<xs:complexType name="Fallout3ModType">
<xs:complexContent>
<xs:extension base="mods:ModType" />
</xs:complexContent>
</xs:complexType>
<xs:element name="ModAbstract" abstract="true" type="mods:ModType" />
<xs:element name="Mod" type="mods:ModType" substitutionGroup="mods:ModAbstract" ></xs:element>
<xs:element name="Fallout3Mod" type="mods:Fallout3ModType" substitutionGroup="mods:ModAbstract"></xs:element>https://stackoverflow.com/questions/5532635
复制相似问题