扩展类型可以互换使用吗?
Can extended types be used interchangeably?
扩展类型是否可以与其基本元素互换使用,反之亦然?
例如,我有一个 WSDL,它指定了几个元素:
<s:complexType name="Original">
<s:sequence>
<s:element name="basic" type="s:string"/>
</s:sequence>
</s:complexType>
<s:complexType name="Extended">
<s:complexContent mixed="false">
<s:extension base="tns:Original">
<s:sequence>
<s:element name="extra" type="s:string"/>
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
是否可以使用这些元素中的任何一个来代替另一个?
当然,不同的applications/implementations会接受不同的东西,所以这个问题主要是看对不对,有标准。
为了进一步扩展我的原始示例,如果 WSDL 指定消息包含 Original
,如下所示:
<s:complexType name="Other">
<s:sequence>
<s:element name="Original" type="tns:Original"/>
</s:sequence>
</s:complexType>
是否可以给它一个 Extended
,同时仍然遵循惯例?或者换个方式呢?
如果您尝试了一些有点 hacky 的东西,例如:
<Original xsi:type="Extended">
<basic>foo</basic>
<extra>bar</extra>
</Original>
谢谢!
您所描述的完全正确。事实上,您必须添加 'block' 属性以防止它发生。
因此,在引用 'Original' 的地方,您可以在 XML 文档中使用 xsi:type='Extended' 并使用 'Extended' 定义的定义.然而,反之则不然,在您的示例中, 'Extended' 类型的元素不能仅包含 'Original' 类型。
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2017 Developer Bundle Edition 15.0.0.6978 (https://www.liquid-technologies.com)-->
<s:schema elementFormDefault="qualified" xmlns:s="http://www.w3.org/2001/XMLSchema">
<s:element name="Root">
<s:complexType>
<s:sequence>
<s:element name="OriginalElm" type="Original" minOccurs="0" maxOccurs="unbounded" />
<s:element name="ExtendedElm" type="Extended" minOccurs="0" maxOccurs="unbounded" />
<s:element name="OriginalBlocked" type="Original" block="extension" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="Original">
<s:sequence>
<s:element name="basic" type="s:string" />
</s:sequence>
</s:complexType>
<s:complexType name="Extended">
<s:complexContent mixed="false">
<s:extension base="Original">
<s:sequence>
<s:element name="extra" type="s:string" />
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
</s:schema>
以下XML 对架构有效
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid XML 2017 Developer Bundle Edition 15.0.0.6978 (https://www.liquid-technologies.com) -->
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="D:\Development2017\Liquid\Applications\XmlStudio\Tests\UserSamples\xsiType\XSDFile3.xsd">
<OriginalElm>
<basic>string</basic>
</OriginalElm>
<OriginalElm xsi:type="Extended">
<basic>string</basic>
<extra>string</extra>
</OriginalElm>
<ExtendedElm>
<basic>string</basic>
<extra>string</extra>
</ExtendedElm>
<OriginalBlocked>
<basic>string</basic>
</OriginalBlocked>
</Root>
然而,由于 'block' 属性,此版本的 'OriginalBlocked' 无法扩展。
<OriginalBlocked xsi:type="Extended">
<basic>INVALID</basic>
<extra>INVALID</extra>
</OriginalBlocked>
关于兼容性的说明。
大多数验证 XML 解析器将正确处理这些(我在 Xerces 和 .Net 上测试过)但是大多数客户端应用程序不会寻找 xsi:type 属性。他们很可能会忽略这些额外的数据,但这取决于它们的编码方式。
另外一个小点,complexTypes和simpleTypes以XxxxType的形式命名是一个很好的约定。解析器可以处理所有具有相同名称的元素属性和类型,但它会让我们感到困惑!
扩展类型是否可以与其基本元素互换使用,反之亦然?
例如,我有一个 WSDL,它指定了几个元素:
<s:complexType name="Original">
<s:sequence>
<s:element name="basic" type="s:string"/>
</s:sequence>
</s:complexType>
<s:complexType name="Extended">
<s:complexContent mixed="false">
<s:extension base="tns:Original">
<s:sequence>
<s:element name="extra" type="s:string"/>
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
是否可以使用这些元素中的任何一个来代替另一个?
当然,不同的applications/implementations会接受不同的东西,所以这个问题主要是看对不对,有标准。
为了进一步扩展我的原始示例,如果 WSDL 指定消息包含 Original
,如下所示:
<s:complexType name="Other">
<s:sequence>
<s:element name="Original" type="tns:Original"/>
</s:sequence>
</s:complexType>
是否可以给它一个 Extended
,同时仍然遵循惯例?或者换个方式呢?
如果您尝试了一些有点 hacky 的东西,例如:
<Original xsi:type="Extended">
<basic>foo</basic>
<extra>bar</extra>
</Original>
谢谢!
您所描述的完全正确。事实上,您必须添加 'block' 属性以防止它发生。
因此,在引用 'Original' 的地方,您可以在 XML 文档中使用 xsi:type='Extended' 并使用 'Extended' 定义的定义.然而,反之则不然,在您的示例中, 'Extended' 类型的元素不能仅包含 'Original' 类型。
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2017 Developer Bundle Edition 15.0.0.6978 (https://www.liquid-technologies.com)-->
<s:schema elementFormDefault="qualified" xmlns:s="http://www.w3.org/2001/XMLSchema">
<s:element name="Root">
<s:complexType>
<s:sequence>
<s:element name="OriginalElm" type="Original" minOccurs="0" maxOccurs="unbounded" />
<s:element name="ExtendedElm" type="Extended" minOccurs="0" maxOccurs="unbounded" />
<s:element name="OriginalBlocked" type="Original" block="extension" />
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="Original">
<s:sequence>
<s:element name="basic" type="s:string" />
</s:sequence>
</s:complexType>
<s:complexType name="Extended">
<s:complexContent mixed="false">
<s:extension base="Original">
<s:sequence>
<s:element name="extra" type="s:string" />
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
</s:schema>
以下XML 对架构有效
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid XML 2017 Developer Bundle Edition 15.0.0.6978 (https://www.liquid-technologies.com) -->
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="D:\Development2017\Liquid\Applications\XmlStudio\Tests\UserSamples\xsiType\XSDFile3.xsd">
<OriginalElm>
<basic>string</basic>
</OriginalElm>
<OriginalElm xsi:type="Extended">
<basic>string</basic>
<extra>string</extra>
</OriginalElm>
<ExtendedElm>
<basic>string</basic>
<extra>string</extra>
</ExtendedElm>
<OriginalBlocked>
<basic>string</basic>
</OriginalBlocked>
</Root>
然而,由于 'block' 属性,此版本的 'OriginalBlocked' 无法扩展。
<OriginalBlocked xsi:type="Extended">
<basic>INVALID</basic>
<extra>INVALID</extra>
</OriginalBlocked>
关于兼容性的说明。 大多数验证 XML 解析器将正确处理这些(我在 Xerces 和 .Net 上测试过)但是大多数客户端应用程序不会寻找 xsi:type 属性。他们很可能会忽略这些额外的数据,但这取决于它们的编码方式。
另外一个小点,complexTypes和simpleTypes以XxxxType的形式命名是一个很好的约定。解析器可以处理所有具有相同名称的元素属性和类型,但它会让我们感到困惑!