7

XSD 1.1を使用してスキーマ定義を作成しようとしています。この定義では、1つの要素の結果が他の要素に依存しています。たとえば、国のリストと各国の州のリストのドロップダウンがあります。人が国を選択する場合、その国の州のみを選択できます。私が達成しようとしているものの擬似コードは、次のようになります。

<xs:schema xmlns:ie="http://www.interviewexchange.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="country">       
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:enumeration value="USA" />
            <xs:enumeration value="UK" />
            <xs:enumeration value="India" />
        </xs:restriction>
    </xs:simpleType>
</xs:element>
<xs:element name="state">       
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <assert test="if (country eq 'USA')">
            <xs:enumeration value="MA" />
            <xs:enumeration value="AR" />
            <xs:enumeration value="NY" />
            </assert">
            <assert test="if (country eq 'India')">
            <xs:enumeration value="AP" />
            <xs:enumeration value="TN" />
            <xs:enumeration value="MP" />
            </assert">
        </xs:restriction>
    </xs:simpleType>
</xs:element>

私が正しいアプローチに従っているかどうかを教えてください。正しいアプローチに従っている場合、この制限をどのように達成できるかについてのコードを誰かに教えてもらえますか?前もって感謝します...

4

1 に答える 1

10

あなたは近づいています。

XSD 1.1では、アサーションはサブツリーのみを見下ろすことができ、上または上には見下ろすことができないため、ここでアサーションを使用する場合は、「state」のタイプではなく「address」のタイプにアサーションを配置する必要があります。

<xs:element name="address">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="street"/>
      <xs:element ref="city"/>
      <xs:element ref="state" minOccurs="0"/>
      <xs:element ref="country"/>
    </xs:sequence>
    <xs:assert test="(country = 'UK' and not(state))
      or
      (country = 'US' and state = ('MA', 'AR', 'NY'))
      or
      (country = 'IN' and state = ('AP', 'TN', 'MP'))
      "/>
  </xs:complexType>
</xs:element>

別のアプローチ(XSD 1.1でも)は、条件付き型の割り当てを使用することです。これにより、要素を参照できる(子は参照できない)XPath式に基づいて、要素にさまざまなタイプを割り当てることができます。国と州を属性に移動する場合(そして、一貫性を保つために、通りと都市も属性に移動する場合)、この方法で条件付き型の割り当てを使用できます。まず、状態に必要なさまざまな単純型を定義します。

<xs:simpleType name="US-states">
  <xs:restriction base="xs:NMTOKEN">
    <xs:enumeration value="MA" />
    <xs:enumeration value="AR" />
    <xs:enumeration value="NY" />      
  </xs:restriction>
</xs:simpleType>

<xs:simpleType name="IN-states">
  <xs:restriction base="xs:NMTOKEN">
    <xs:enumeration value="AP" />
    <xs:enumeration value="TN" />
    <xs:enumeration value="MP" />   
  </xs:restriction>
</xs:simpleType>

次に、必要な3種類のアドレスに対して3つの異なる複合型を定義します。説明のために、英国の住所には「state」属性がないことを前提としています。

<xs:complexType name="US-address">
  <xs:attribute name="street" type="xs:string" use="required"/>
  <xs:attribute name="city" type="xs:string" use="required"/>
  <xs:attribute name="state" type="US-states"/>
  <xs:attribute name="country" type="xs:NMTOKEN" use="required"/>
</xs:complexType>
<xs:complexType name="UK-address">
  <xs:attribute name="street" type="xs:string" use="required"/>
  <xs:attribute name="city" type="xs:string" use="required"/>
  <xs:attribute name="country" type="xs:NMTOKEN" use="required"/>
</xs:complexType>
<xs:complexType name="IN-address">
  <xs:attribute name="street" type="xs:string" use="required"/>
  <xs:attribute name="city" type="xs:string" use="required"/>
  <xs:attribute name="state" type="IN-states"/>
  <xs:attribute name="country" type="xs:NMTOKEN" use="required"/>
</xs:complexType>

address次に、'country'の値に基づいて、要素をこれらの正しいものにバインドします。

<xs:element name="address">
  <xs:alternative test="@country='US'" type="US-address"/>
  <xs:alternative test="@country='IN'" type="IN-address"/>
  <xs:alternative test="@country='UK'" type="UK-address"/>
  <xs:alternative type="xs:error"/>
</xs:element>

選択肢は順番にテストされ、テストがtrueと評価された最初の選択肢がタイプを割り当てます。最後の選択肢(テスト属性なし)はデフォルトを提供します。この場合はエラータイプです(エラータイプに対して有効な要素または属性はありません)。

于 2012-12-12T17:59:25.710 に答える