一个元素的内联 children,如果只有一个该类型的元素

Inline children of an element, if there's only one elements of that type

假设我想建模 <Product>。一件商品可以有多个变体(例如 T-shirt 有不同颜色),也可以有一个变体,例如只有一种颜色的毛衣。

我想创建一个允许这两种语法都有效的模式:

<MyXMLDoc>

<Product>
  <Variants>  
    <Variant>
      <Name>Red T-Shirt</Name>
      <Description>A red t-shirt</Description>
    </Variant>

    <Variant>
      <Name>Green T-Shirt</Name>
      <Description>A green t-shirt</Description>
    </Variant>

    <Variant>
      <Name>Blue T-Shirt</Name>
      <Description>A blue t-shirt</Description>
    </Variant>

  </Variants>
</Product>

<Product>
  <Name>Black sweater</Name>
  <Description>A plain ol' black sweater</Description>
</Product>

</MyXMLDoc>

我能得到的最接近的是:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="MyXMLDoc">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" ref="Product"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="Product">
        <xs:complexType>
            <xs:choice>
                <xs:element ref="Variant"/>
                <xs:element ref="Variants"/>
            </xs:choice>
        </xs:complexType>
    </xs:element>

    <xs:element name="Variants">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" ref="Variant"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="Variant">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="Name"/>
                <xs:element ref="Description"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="Name" type="xs:string"/>
    <xs:element name="Description" type="xs:string"/>
</xs:schema>

<Variant><Variants> 之间的 xs:choice 让我摆脱了 <Variants> 层级的嵌套,但是 <Name><Description> 仍然需要在单个 <Variant>.

下作为父母

有没有办法告诉 XML-schema 期望元素 (<Variant>) 或元素的 in-lined 成员(<Name><Description> 来自 <Variant>,而不需要实际包裹在 <Variant>) 中? 请注意 <Name> 和 `

我认为这就是您的目标:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="MyXMLDoc">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" ref="Product"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="Product">
        <xs:complexType>
            <xs:choice>
                <xs:group ref="VariantGroup"/>
                <xs:element ref="Variant"  maxOccurs="unbounded"/>
            </xs:choice>
        </xs:complexType>
    </xs:element>

    <xs:element name="Variant">
        <xs:complexType>
            <xs:group ref="variantGroup"/> 
        </xs:complexType>
    </xs:element>

    <xs:group name="VariantGroup">
        <xs:sequence>
            <xs:element name="Name" type="xs:string"/>
            <xs:element name="Description" type="xs:string"/>
        </xs:sequence>
    </xs:group>

</xs:schema>

我删除了 <Variants> 级别,因为您的评论似乎表明您想避免它 - 尽管您的 XML 示例确实包含它。

虽然您建议的 XML 可以使用 XML 架构来描述,但我认为像这样表示单变体产品会更简单:

<Product>
  <Variant>
    <Name>Black sweater</Name>
    <Description>A plain ol' black sweater</Description>
  </Variant>
</Product>

这将使 XML 架构更加简单 - 只需在 Variant 元素上设置 minOccurs=1。