0

2つの異なるxmlに対して1つのスキーマファイルを作成したい(2つのスキーマに分割できますが、ルート要素が同じであるため、1つのファイルに保持したい)。

今私は2つの異なるXMLを持っています。

<orderStatus shipStatus="SHIPPED/PENDING">
    <orderId>1234</orderId>
    <orderedBy>userName</orderedBy>
    <orderedOn>2012-07-23T11:35:51.000-04:00</orderedOn>
</orderStatus>

2番目のXMLは

<orderStatus modifyShipStatus="SUSPENDED/PENDING">
    <shipStatus>101</shipStatus>
</orderStatus>

これらの2つのxmlに対して1つのxsdを使用するにはどうすればよいですか?1つのタイプでルート要素を作成しようとすると正常に動作しますが、別のタイプを追加しようとすると、JAXBは要素がすでに定義されているというエラーをスローします。センセーションを起こします。

4

1 に答える 1

2

答えは、正確に何を言いたいかによって異なります。また、使用しているスキーマ言語によっても異なります: DTD? XSD1.0? XSD1.1? リラックスNG? 他の ...?ああ、そうです、質問に XSD というタグが付いていることがわかりました。そのため、XSD ソリューションを探していると仮定します。

orderStatus要素がシーケンス、、またはシーケンスいずれかを子として持つことができ、属性およびはオプションであると言いたい場合、コンテンツ モデルでそう言うのは簡単です。orderIdorderedByorderedOn shipStatusshipStatusmodifyShipStatus

DTD 記法 (簡潔にするためにここで使用します) では、次のように記述します。

<!ELEMENT orderStatus ((orderId, orderedBy, orderedOn) | shipStatus) >
<!ATTLIST orderStatus
          shipStatus CDATA #IMPLIED
          modifyShipStatus CDATA #IMPLIED
>

または XSD 表記で、次のように記述します。

<xs:element name="orderStatus" type="my:orderStatus"/>  
<xs:complexType name="orderStatus">
  <xs:choice>
    <xs:sequence>
      <xs:element ref="my:orderId"/>
      <xs:element ref="my:orderedBy"/>
      <xs:element ref="my:orderedOn"/>
    </xs:sequence>
    <xs:element ref="my:shipStatus"/>
  </xs:choice>
  <xs:attribute name="shipStatus"/>
  <xs:attribute name="modifyShipStatus"/>
</xs:complexType>

その後、完了です。

2 つの属性のうちの 1 つだけを許可したい場合、または正当な子をどちらかの属性が存在するかどうかに依存させたい場合、事態はさらに複雑になります。(一部のドキュメント デザイナーは、必要に応じて、同じ名前で呼び出すことを主張している 2 つのまったく異なる要素タイプがあり、検証が不必要に困難になると言うでしょう。)

その場合、次の選択肢があります。

  • 上記のように DTD および/または XSD 1.0 スキーマを使用し、追加の制約をドキュメントで表現するか、Schematron を使用するか、または他の方法で表現します。

  • XSD 1.1 を使用し、上記のようにコンテンツ モデルと属性を定義し、それを示すアサーションを追加します。

    • 属性の 1 つだけであり、表示する必要がshipStatusありmodifyShipStatusます。
    • shipStatusという名前の子が表示される場合にのみ、属性を表示する必要がありorderIdます。
    • modifyShipStatusという名前の子が表示される場合にのみ、属性を表示する必要がありshipStatusます。
  • XSD 1.1 を使用し、要素の 2 つの形式に対して 2 つの異なる型を定義し、orderStatus条件付きの型割り当てを使用して、次の場合にどの型が適用されるかを示します。

XSD は次のようになります。

   <xs:complexType name="orderStatus1">
      <xs:sequence>
        <xs:element ref="my:orderId"/>
        <xs:element ref="my:orderedBy"/>
        <xs:element ref="my:orderedOn"/>
      </xs:sequence>
      <xs:attribute name="shipStatus"/>
    </xs:complexType>  
    <xs:complexType name="orderStatus2">
      <xs:element ref="my:shipStatus"/>
      <xs:attribute name="modifyShipStatus"/>
    </xs:complexType>

    <xs:element name="orderStatus">
      <xs:alternative test="@shipStatus" type="my:orderStatus1"/> 
      <xs:alternative test="@modifyShipStatus" type="my:orderStatus2"/>
    </xs:element>
  • ついでに言うと、Relax NG の強みの 1 つとして、この種の制約を定式化できることを、熱心なユーザーがよく挙げています。
于 2012-08-16T20:30:22.490 に答える