You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XML Schema中实现多态以兼容两种polly XML结构

用同一XML Schema表示两种XML结构的问题

需求说明

需要用同一个XML Schema定义两种<polly>元素的结构:

  1. 直接包含文本内容的结构:
<polly> wibble </polly>
  1. 包含多个子<element>元素的结构:
<polly>
  <element> foo </element>
  <element> bar </element>
  <element> baz </element>
</polly>

注:示例中元素为string类型,需支持其他类型扩展

尝试的实现方式

我尝试通过基类层级来实现:

  1. 定义基类型:
<xsd:complexType name="polly"/>
  1. 定义字符串子类型:
<xsd:complexType name="polly_string">
  <xsd:complexContent>
    <xsd:extension base="tns:polly"/>
  </xsd:complexContent>
</xsd:complexType>
  1. 定义数组子类型:
<xsd:complexType name="polly_array">
  <xsd:complexContent>
    <xsd:extension base="tns:polly">
      <xsd:sequence>
        <xsd:element maxOccurs="unbounded" minOccurs="0" name="element" type="tns:polly_array_element"/>
      </xsd:sequence>
    </xsd:extension>
  </xsd:complexContent>
</xsd:complexType>
<xsd:simpleType name="polly_array_element">
  <xsd:restriction base="xsd:string"/>
</xsd:simpleType>
  1. 实例化元素:
<xsd:element minOccurs="0" name="polly" type="tns:polly"/>

遇到的问题

目前的定义无法让polly_string成为简单类型,也无法为其添加restriction——因为extension和restriction互斥。我用VS Code验证时遇到报错,尝试了几种写法都失败:

尝试1:在extension内添加restriction

<xsd:complexType name="polly_string">
  <xsd:complexContent>
    <xsd:extension base="tns:polly">
      <xsd:restriction base="xs:string"/>
    </xsd:extension>
  </xsd:complexContent>
</xsd:complexType>

报错:

The content of 'polly_string' is invalid. Element 'restriction' is invalid, misplaced, or occurs too often.

尝试2:使用simpleContent扩展基类型

<xsd:complexType name="polly_string">
  <xsd:simpleContent>
    <xsd:extension base="tns:polly">
    </xsd:extension>
  </xsd:simpleContent>
</xsd:complexType>

报错:

Complex Type Definition Representation Error for type 'polly_string'. When is used, the base type must be a complexType whose content type is simple, or, only if restriction is specified, a complex type with mixed content and emptiable particle, or, only if extension is specified, a simple type. 'polly' satisfies none of these conditions.

尝试3:多重extension

<xsd:complexType name="polly_string">
  <xsd:complexContent>
    <xsd:extension base="tns:polly"/>
    <xsd:extension base="xs:string"/>
  </xsd:complexContent>
</xsd:complexType>

报错:

The content of 'polly_string' is invalid. Element 'extension' is invalid, misplaced, or occurs too often.

解决方案

要实现需求,需要调整基类型的定义,让polly_string能够包含简单文本内容,同时继承基类型。以下是两种可行方案:

方案1:使用xsd:choice定义多态结构

直接在基类型中定义可选的内容模型,让<polly>可以选择是文本内容还是子元素序列,无需子类:

<xsd:complexType name="polly">
  <xsd:choice>
    <!-- 文本内容 -->
    <xsd:element name="text" type="xsd:string" minOccurs="0"/>
    <!-- 子元素序列 -->
    <xsd:sequence minOccurs="0">
      <xsd:element maxOccurs="unbounded" name="element" type="tns:polly_array_element"/>
    </xsd:sequence>
  </xsd:choice>
</xsd:complexType>

<xsd:simpleType name="polly_array_element">
  <xsd:restriction base="xsd:string"/>
</xsd:simpleType>

<xsd:element name="polly" type="tns:polly"/>

方案2:调整基类型为可扩展的简单内容类型

如果需要保持子类层级,把基类型定义为支持简单内容的complexType,这样polly_string可以通过simpleContent扩展并添加restriction:

<!-- 基类型定义为带有简单内容的complexType -->
<xsd:complexType name="polly">
  <xsd:simpleContent>
    <xsd:extension base="xsd:anyType"/>
  </xsd:simpleContent>
</xsd:complexType>

<!-- 字符串子类型:通过simpleContent扩展基类型,并添加restriction -->
<xsd:complexType name="polly_string">
  <xsd:simpleContent>
    <xsd:restriction base="tns:polly">
      <xsd:simpleType>
        <xsd:restriction base="xsd:string">
          <!-- 可在此添加自定义restriction规则,如长度、正则等 -->
        </xsd:restriction>
      </xsd:simpleType>
    </xsd:restriction>
  </xsd:simpleContent>
</xsd:complexType>

<!-- 数组子类型:通过complexContent扩展基类型,添加子元素 -->
<xsd:complexType name="polly_array">
  <xsd:complexContent>
    <xsd:extension base="tns:polly">
      <xsd:sequence>
        <xsd:element maxOccurs="unbounded" name="element" type="tns:polly_array_element"/>
      </xsd:sequence>
    </xsd:extension>
  </xsd:complexContent>
</xsd:complexType>

<xsd:simpleType name="polly_array_element">
  <xsd:restriction base="xsd:string"/>
</xsd:simpleType>

<!-- 使用基类型实例化,XML中通过xsi:type指定具体子类型 -->
<xsd:element name="polly" type="tns:polly"/>

使用该方案时,XML实例需通过xsi:type指定具体子类型:

  • 字符串结构:
<polly xsi:type="tns:polly_string">wibble</polly>
  • 数组结构:
<polly xsi:type="tns:polly_array">
  <element>foo</element>
  <element>bar</element>
</polly>

内容的提问来源于stack exchange,提问作者andreasmartens

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:29:59