Встроенные дочерние элементы элемента, если есть только один элемент этого типа - PullRequest
0 голосов
/ 17 июня 2020

Допустим, я хочу смоделировать <Product>. У продукта могут быть варианты (например, футболка разных цветов) или один вариант, например, свитер одного цвета.

Я хочу создать схему, которая позволяет оба этих синтаксиса действительны:

<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>

xs:choice между <Variant> или <Variants> позволяет мне получить избавиться от уровня вложенности <Variants>, но <Name> и <Description> по-прежнему должны быть отнесены к одному <Variant>.

Есть ли способ сообщить XML -схеме ожидать либо элемента (<Variant>), либо встроенных членов элемента (<Name>, <Description> из <Variant>, без необходимости фактически заключать в <Variant>)? Обратите внимание, что <Name> и `

1 Ответ

1 голос
/ 18 июня 2020

Я думаю, это то, к чему вы стремитесь:

<?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 Schema, я думаю, что было бы проще представить одновариантный продукт следующим образом:

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

That значительно упростит схему XML - просто установите minOccurs = 1 в элементе Variant.

...