我第一次被错误地问了一下,我有点重复这个问题。
我有这个:
<xsd:complexType name="A">
<xsd:sequence>
<xsd:element name="options" type="options"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="B">
<xsd:complexContent>
<xsd:element name="options" type="ex_options"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="options">
<xsd:sequence>
...some options
</xsd:sequence>
</xsd:element>
<xsd:complexType name="ex_options">
<xsd:complexContent>
<xsd:extension base="options">
<xsd:sequence>
...some more options
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:element>
所以基本上我有一个带有内部类选项的类A,类B继承自A类,我希望B.options继承自A.options,这样当我们做webservices时我们只需要传递一个,当我们调用getOptions时它会返回正确的对象B.options。目前使用xsd的方式我得到一个错误,说明模型组中出现了具有不同类型名称选项的多个元素。错误是B类型。
只需坚持使用类型B的元素然后使用然后使用适当的xsi:type
属性值装饰您的实例文档元素,如下所述。
<xsd:complexType name="B">
<xsd:complexContent>
<xsd:element name="options" type="ex_options"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="options">
<xsd:sequence>
...some options
</xsd:sequence>
</xsd:element>
<xsd:complexType name="ex_options">
<xsd:complexContent>
<xsd:extension base="options">
<xsd:sequence>
...some more options
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:element>
然后将你的实例元素“装饰”为
<options xsi:type="ex_options"> ... (this will work)
要么
<options xsi:type="options"> ... (I think you can do this as long as the base xsi:type is not abstract)
如果事实证明你无法使用基础xsi:type
进行装饰,那么你总是可以通过创建一个空基类型来“欺骗”,然后通过仔细构造来扩展以达到你想要的两种格式。
有关详细信息和链接,请参阅this post。
您可以使options
序列开放,这样您就可以拥有任意数量的选项,然后根据属性值验证现有选项。例如,在以下模式中,options
列表具有type
或A
的B
属性,指示应实际列出哪些选项:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xs"
elementFormDefault="qualified"
xmlns="http://tempuri.org/XMLSchema.xs"
xmlns:mstns="http://tempuri.org/XMLSchema.xs"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Elements for document structure. -->
<!-- This section is just for validating my example file to -->
<!-- demonstrate the schema. -->
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="elementA" type="A" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="elementB" type="A" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- The important part of the schema. -->
<!-- Types -->
<!-- A has options of type options. -->
<xs:complexType name="A">
<xs:sequence>
<xs:element name="options" type="options"/>
</xs:sequence>
</xs:complexType>
<!-- Options specifies a options with a type attribute specifying which options will be available. -->
<xs:complexType name="options">
<xs:sequence>
<xs:element name="option" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="type" use="optional" default="A">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="A"/>
<xs:enumeration value="B"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:schema>
以下是此架构的XML示例。
<?xml version="1.0" encoding="utf-8"?>
<root xmlns="http://tempuri.org/XMLSchema.xs">
<elementA>
<options type="A">
<option>Test-A</option>
<option>Test2-A</option>
</options>
</elementA>
<elementB>
<options type="B">
<option>Test-B</option>
<option>Test2-B</option>
<option>Test3-B</option>
<option>Test4-B</option>
</options>
</elementB>
</root>
您也可以使用限制而不是扩展,但这不是最佳解决方案,因为限制会删除所有基本定义。更好的情况是在运行时使用xsi:type(在元素的XML实例中),如其他答案中所述。 使用xsi:type的更多一个例子是:http://www.xfront.com/ElementHierarchy.html
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- Root element -->
<xsd:element name="root" type="B"/>
<!-- Base abstract type -->
<xsd:complexType name="A" abstract="true">
<xsd:sequence>
<!-- Option that we will override -->
<xsd:element name="options" type="options"/>
</xsd:sequence>
</xsd:complexType>
<!-- Derived type -->
<xsd:complexType name="B">
<xsd:complexContent>
<!--Overriding -->
<xsd:restriction base="A">
<xsd:sequence>
<xsd:element name="options" type="ex_options"/>
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
<!-- Base included class -->
<xsd:complexType name="options">
<xsd:sequence>
<xsd:element name="baseOption"/>
</xsd:sequence>
</xsd:complexType>
<!-- Overriding of included class -->
<xsd:complexType name="ex_options">
<xsd:complexContent>
<xsd:restriction base="options">
<xsd:sequence>
<xsd:element name="overridedOption"/>
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
在伪CiXML中,它将类似于:
{
B root;
abstract class A
{
options options;
}
class B override A
{
ex_options options;
}
class options
{
empty baseOption;
}
class ex_option override options
{
empty overridedOption
}
}
这里是示例XML:
<?xml version="1.0" encoding="UTF-8"?>
<root xsi:noNamespaceSchemaLocation="polymorphism.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<options>
<overridedOption/>
</options>
</root>