0

次のようなxmlドキュメントでの作業を想定しましょう。

<Item>
  <Price>10</Price>
  <Ratio>1.5</Ratio>
  <MaxPrice>18<MaxPrice>
</Item>

<Item>
  <Price>12</Price>
</Item>

データの意味は次のとおりです。アイテムには、反復的な価格変更のための価格とオプションの比率、および超えてはならない最大価格が必要です。明確にするために:{}のみまたは3つのPrice要素すべて{ Price、、}。他のオプションは許可されていません。RatioMaxPrice

定期的に、XSDでは、を使用して要素をオプションにすることができるため、次のようminOccurs="0"に定義できます。Item

<xs:element name="Item">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="Price" type="xs:integer" />
            <xs:element name="Ratio" type="xs:float" minOccurs="0" />
            <xs:element name="MaxPrice" type="xs:integer" minOccurs="0" />
        </xs:sequence>
    </xs:complexType>
</xs:element>

しかし、それだけでは十分ではありません。これにより、たとえば、Item{PriceRatio}のみから-までが正しくなりません。

これはどのように行うことができますか?

4

1 に答える 1

0

xs:sequenceここで重要なのはとの組み合わせxs:choiceです。この2つを組み合わせる方法は重要であることに注意してください(理由は以下を参照)。正しい方法(少なくとも私が見つけたものに基づく)は、次のようにXSDを表現ビルドすることです。

<xs:complexType name="itemType">
    <xs:sequence>
        <xs:element name="Price" type="xs:integer" />
        <xs:choice minOccurs="0">
            <xs:sequence>
                <xs:element name="Ratio" type="xs:float" />
                <xs:element name="MaxPrice" type="xs:integer" />
            </xs:sequence>
        </xs:choice>
    </xs:sequence>
</xs:complexType>

<xs:element name="Item" type="my:itemType" />

そうすれば、オプションで要素の固定シーケンスを含めることができます。これはまさに私たちが探していたものです。

(探しているものが見つかった場合は、ここで読むのをやめることができます。以下は、他のアプローチがどのように見えるか、およびそれらが機能しない理由を説明するだけです)

2つの固定シーケンスの固定選択も機能し、広く再利用可能なパターンとして機能するのではないかと思う人もいるかもしれません(これは他の場所から発想を得た私の最初のアイデアでもあります)。特定の場合に当てはまるかもしれませんが、これはたまたまその1つではありません。観察:

<xs:complexType name="itemType">
    <xs:choice>
        <xs:sequence>
            <xs:element name="Price" type="xs:integer" />
        </xs:sequence>
        <xs:sequence>
            <xs:element name="Price" type="xs:integer" />
            <xs:element name="Ratio" type="xs:float" />
            <xs:element name="MaxPrice" type="xs:integer" />
        </xs:sequence>
    </xs:choice>
</xs:complexType>

<xs:element name="Item" type="my:itemType" />

大丈夫そうですね まあ、明らかにそうではありません-完全なアイテムは通過しません!バリデーターは繰り返し最初の選択肢に分類され、要素を検証し、次の要素が予期Priceしないものであると述べて失敗します。Ratio

さて、状況を改善するための明白な試みが現れます-選択肢を切り替えましょう:

<xs:complexType>
    <xs:choice>
        <xs:sequence>
            <xs:element name="Price" type="xs:integer" />
            <xs:element name="Ratio" type="xs:float" />
            <xs:element name="MaxPrice" type="xs:integer" />
        </xs:sequence>
        <xs:sequence>
            <xs:element name="Price" type="xs:integer" />
        </xs:sequence>
    </xs:choice>
</xs:complexType>

<xs:element name="Item" type="my:itemType" />

貧弱な要素を拡張することを決定するまで、これは正常に機能しているように見えますItem(おそらく、Item要素の他の使用法も問題を引き起こす可能性があります)。

私は例を試しました:

<xs:complexType name="DiscountedItem">
    <xs:complexContent>
        <xs:extension base="my:itemType">
            <xs:sequence>
                <xs:element name="Discount" type="xs:integer" />
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

これを試してみると、選択肢を切り替えたかどうかに応じて、{ 、 }サブ要素DiscountedItemがある場合とない場合のどちらかで失敗します。RatioMaxPrice

それにもかかわらず、これは、このユースケースでは、最初に述べた「固定シーケンスを含めるためのオプションの選択」を使用する方がはるかに優れていると結論付けています。私はこれを難しい方法だと思ったので、あなたはそうする必要はありません:)

于 2013-03-26T16:02:44.393 に答える