gpt4 book ai didi

xsd - 如何在不对选择进行排序的情况下扩展选择complexType?

转载 作者:行者123 更新时间:2023-12-03 12:42:37 24 4
gpt4 key购买 nike

我有一个名为abType的选择complexType:

<xs:complexType name="abType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="a"/>
<xs:element name="b"/>
</xs:choice>
</xs:complexType>

此类型可用于以任何顺序创建带有 ab节点的元素,例如:
<ab>
<b/>
<a/>
</ab>

现在,我想创建一个名为 abcType的派生类型,以允许节点 abc任意顺序。因此,我基于 abType创建了一个新的complexType:
<xs:complexType name="abcType">
<xs:complexContent>
<xs:extension base="abType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="c"/>
</xs:choice>
</xs:extension>
</xs:complexContent>
</xs:complexType>

之后,我创建了一个 abc节点:
<abc>
<c/>
<b/>
<a/>
</abc>

但是此节点为 无效!将 ab放在 c之后是无效的。原因是,尽管两种类型都是选择,但从基本类型派生类型会创建隐式序列。 XMLspy通过这种方式进行说明:

这个结果对于选择类型是完全没有用的。

所以我的问题是:如何在不对选择进行排序的情况下扩展选择类型?

这是完整的XSD和XML测试文件,可以重现该问题:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="ab"/>
<xs:element ref="abc"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ab" type="abType"/>
<xs:complexType name="abType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="a"/>
<xs:element name="b"/>
</xs:choice>
</xs:complexType>
<xs:element name="abc" type="abcType"/>
<xs:complexType name="abcType">
<xs:complexContent>
<xs:extension base="abType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="c"/>
</xs:choice>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>

例:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="inherit-choice.xsd">
<ab>
<b/>
<a/>
</ab>
<abc>
<c/>
<b/>
<a/>
</abc>
</root>

最佳答案

不幸的是,简短的答案是“否”,您不能扩展选择合成器。从逻辑上讲,如果a,b和c之间存在某种关系(例如在Java,.NET中,所有东西最终都是对象,那么您可以在XSD中做同样的事情),那么我建议使用替代组(或者,如果您愿意,则基于xsi:type)。

举例说明。 XSD-1:

<?xml version="1.0" encoding="utf-8" ?>
<!--W3C Schema generated by QTAssistant/W3C Schema Refactoring Module (http://www.paschidev.com)-->
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="ab" type="abType"/>

<xsd:complexType name="abType">
<xsd:sequence>
<xsd:element ref="ExtensibleChoice-A" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>

<xsd:element name="ExtensibleChoice-A" type="ExtensibleChoiceBaseType" abstract="true" />

<xsd:complexType name="ExtensibleChoiceBaseType" abstract="true">
<xsd:sequence/>
</xsd:complexType>

<xsd:element name="a" substitutionGroup="ExtensibleChoice-A" type="aType" block="#all"/>
<xsd:element name="b" substitutionGroup="ExtensibleChoice-A" type="bType" block="#all"/>
<xsd:element name="c" substitutionGroup="ExtensibleChoice-A" type="cType" block="#all"/>

<xsd:complexType name="aType">
<xsd:complexContent>
<xsd:extension base="ExtensibleChoiceBaseType">
<xsd:sequence>
<xsd:element name="aChild" type="xsd:string"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="bType">
<xsd:complexContent>
<xsd:extension base="ExtensibleChoiceBaseType">
<xsd:sequence>
<xsd:element name="bChild" type="xsd:int"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="cType">
<xsd:complexContent>
<xsd:extension base="ExtensibleChoiceBaseType">
<xsd:sequence>
<xsd:element name="cChild" type="xsd:string"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>

可扩展性是,在某个时间点,您可能只有 a b c 作为成员。如果您或消费者决定添加某些内容(例如 d 元素),则只需创建引用旧框架的另一个架构,并使用新元素 d ,然后使用该新架构即可。旧的XSD文件不会被触及。生成新的JAXB类(作为示例)将导致向后兼容代码。

因此,XSD-1将验证以下内容:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<ab xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
<a>
<aChild>aChild1</aChild>
</a>
<b>
<bChild>1</bChild>
</b>
<c>
<cChild>cChild1</cChild>
</c>
</ab>

您将需要以下内容(XSD-2):
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema1.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema1.xsd" xmlns:b="http://tempuri.org/XMLSchema.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:import namespace="http://tempuri.org/XMLSchema.xsd" schemaLocation="XSD-1.xsd"/>

<xsd:element name="d" substitutionGroup="b:ExtensibleChoice-A" type="dType" block="#all"/>

<xsd:complexType name="dType">
<xsd:complexContent>
<xsd:extension base="b:ExtensibleChoiceBaseType">
<xsd:sequence>
<xsd:element name="dChild" type="xsd:string"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
  • 该图显示了成员的"new"列表, d 以蓝色突出显示:


  • 要验证这一点:
    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
    <ab xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:d="http://tempuri.org/XMLSchema1.xsd">
    <a>
    <aChild>aChild1</aChild>
    </a>
    <d:d>
    <d:dChild>1</d:dChild>
    </d:d>
    </ab>

    关于xsd - 如何在不对选择进行排序的情况下扩展选择complexType?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9008622/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com