如何在不排序选择的情况下扩展选择 complexType? [英] How to extend a choice complexType without sequencing the choice?

查看:18
本文介绍了如何在不排序选择的情况下扩展选择 complexType?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a choice complexType named abType:

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

此类型可用于创建具有 ab 节点的元素,例如:

This type can be used to create elements with a and b nodes in any order like this for example:

<ab>
    <b/>
    <a/>
</ab>

现在我想创建一个名为 abcType 的派生类型,以允许节点 abc以任何顺序.因此,我基于 abType 创建了一个新的 complexType:

Now I want to create a derived type called abcType to allow the nodes a, b and c in any order. Therefore I created a new complexType based on abType:

<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 节点:

After that I created a abc node:

<abc>
    <c/>
    <b/>
    <a/>
</abc>

但是这个节点无效!在 c 之后放置任何 ab 均无效.原因是,从基类型派生类型会创建一个隐式序列,尽管这两种类型都是选择.XMLspy 是这样说明的:

But this node is invalid! It is not valid to put any a or b after a c. The reason is, that deriving a type from a base type creates an implicite sequence although both types are choices. XMLspy illustrates it in this way:

这个结果对于选择类型来说是毫无用处的.

This result is quite useless for choice types.

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

这里是完整的 XSD 和重现问题的 XML 测试文件:

Here is the complete XSD and an XML test file to reproduce the problem:

<?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 的东西).

Unfortunately, the short answer is NO, you can't extend a choice compositor. Logically, if there is some sort of relationship between a, b, and c (as in Java, .NET, everything is ultimately an Object, you could do the same in XSD) then I suggest the use of substitution groups instead (or, if you prefer, something based on xsi:type).

更新一个例子.XSD-1:

UPDATE with an example. The 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>

可扩展性是在某个时间点,您可能只有 abc 作为成员.如果您或消费者决定添加一些东西(比如 d 元素),那么您只需创建另一个引用旧模式的模式,并使用新元素 d,然后改用该新架构.旧的 XSD 文件不会被触及;生成新的 JAXB 类(例如)将产生向后兼容的代码.

The extensibility is that at a point in time, you may have only a, b and c as members. If you, or a consumer, decide to add something (say a d element), then you simply create another schema that references the old one, with the new element d, and then use that new schema instead. The old XSD file doesn't get touched; generating new JAXB classes (as an example) will result in backward compatible code.

因此,XSD-1 将验证如下内容:

So, XSD-1 will validate something like this:

<?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):

You would need something like this (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>

  • 图表显示了新"成员列表,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>
    

    这篇关于如何在不排序选择的情况下扩展选择 complexType?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆