web-dev-qa-db-ja.com

XSD-任意の順序で要素を何回でも許可する方法は?

私はXSDを作成しようとしていますが、次の要件で定義を書き込もうとしています:

  • 指定した子要素を何度でも表示できるようにします(0から無制限)
  • 子要素を任意の順序にすることができます

私は周りを見て、 this のようなさまざまな解決策を見つけました。

<xs:element name="foo">
  <xsl:complexType>
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element name="child1" type="xs:int"/>
      <xs:element name="child2" type="xs:string"/>
    </xs:choice>
  </xs:complexType>
</xs:element>

しかし、私が理解していることから、xs:choiceはまだ単一要素の選択のみを許可しています。したがって、このようにMaxOccursをunboundedに設定するということは、子要素の「いずれか」が複数回出現する可能性があることを意味するだけです。これは正確ですか?

上記の解決策が間違っている場合、要件で上記の内容を達成するにはどうすればよいですか?

[〜#〜] edit [〜#〜]:要件が次の場合はどうなりますか?

  • 要素child1 child2は何回でも出現できます(0から無制限)
  • 任意の順序の要素
  • 要素child3およびchild4は、一度だけ表示されます。

たとえば、次のxmlは有効です。

<foo>
<child1> value </child1>
<child1> value </child1>
<child3> value </child3>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>

しかし、これはありません(child3がありません)

<foo>
<child1> value </child1>
<child1> value </child1>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>
101
jvtech

質問にあるスキーマでは、child1 または child2は、任意の順序で何回でも出現できます。これはあなたが探しているもののように聞こえます。

編集:そのうちの1つだけを無制限に表示したい場合は、代わりに無制限の要素を選択する必要があります。

編集: XMLの固定タイプ。

編集: maxOccursの大文字のO

<xs:element name="foo">
   <xs:complexType>
     <xs:choice maxOccurs="unbounded">
       <xs:element name="child1" type="xs:int" maxOccurs="unbounded"/>
       <xs:element name="child2" type="xs:string" maxOccurs="unbounded"/>
     </xs:choice>
   </xs:complexType>
</xs:element>
57
xcut

後の編集で追加された質問の代替定式化は未解決のようです:要素の子の間で、child3という名前の1つ、child4という名前の1つ、および任意の数がなければならないことを指定する方法child1またはchild2という名前で、子が表示される順序に制約はありません。

これは簡単に定義できる正規言語であり、必要なコンテンツモデルは、数字「3」と「4」がそれぞれ1回だけ出現し、数字「1」と「2」が含まれる文字列のセットを定義する正規表現と同型です'何度も発生します。これの書き方が明らかでない場合は、そのような言語を認識するためにどのような有限状態マシンを構築するかを考えると役立つかもしれません。少なくとも4つの異なる状態があります。

  • 「3」も「4」も見られない初期状態
  • 「3」は表示されているが「4」は表示されていない中間状態
  • 「4」は表示されているが「3」は表示されていない中間状態
  • 「3」と「4」の両方が見られた最終状態

オートマトンの状態に関係なく、「1」と「2」が読み取られます。マシンの状態は変更されません。初期状態では、「3」または「4」も受け入れられます。中間状態では、「4」または「3」のみが受け入れられます。最終状態では、「3」も「4」も受け入れられません。正規表現の構造は、「3」と「4」のみが発生する言語のサブセットの正規表現を最初に定義すると理解しやすくなります。

(34)|(43)

特定の場所で「1」または「2」を何度でも発生させるには、(1|2)*(または正規表現言語がその表記を受け入れる場合は[12]*)を挿入できます。利用可能なすべての場所にこの式を挿入すると、

(1|2)*((3(1|2)*4)|(4(1|2)*3))(1|2)*

これをコンテンツモデルに変換するのは簡単です。基本構造は正規表現(34)|(43)と同等です:

<xsd:complexType name="paul0">
  <xsd:choice>
    <xsd:sequence>
      <xsd:element ref="child3"/>
      <xsd:element ref="child4"/>
    </xsd:sequence>
    <xsd:sequence>
      <xsd:element ref="child4"/>
      <xsd:element ref="child3"/>
    </xsd:sequence>
  </xsd:choice>
</xsd:complexType>

child1child2のゼロ以上の選択肢を挿入するのは簡単です:

<xsd:complexType name="paul1">
  <xsd:sequence>
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="child1"/>
      <xsd:element ref="child2"/>
    </xsd:choice>      
    <xsd:choice>
      <xsd:sequence>
        <xsd:element ref="child3"/>
        <xsd:choice minOccurs="0" maxOccurs="unbounded">
          <xsd:element ref="child1"/>
          <xsd:element ref="child2"/>
        </xsd:choice>      
        <xsd:element ref="child4"/>
      </xsd:sequence>
      <xsd:sequence>
        <xsd:element ref="child4"/>
        <xsd:choice minOccurs="0" maxOccurs="unbounded">
          <xsd:element ref="child1"/>
          <xsd:element ref="child2"/>
        </xsd:choice>      
        <xsd:element ref="child3"/>
      </xsd:sequence>
    </xsd:choice>
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="child1"/>
      <xsd:element ref="child2"/>
    </xsd:choice>      
  </xsd:sequence>
</xsd:complexType>

バルクを少し最小限にしたい場合は、child1child2の繰り返しの選択に対して名前付きグループを定義できます。

<xsd:group name="onetwo">
  <xsd:choice>
    <xsd:element ref="child1"/>
    <xsd:element ref="child2"/>
  </xsd:choice>   
</xsd:group>

<xsd:complexType name="paul2">
  <xsd:sequence>
    <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:choice>
      <xsd:sequence>
        <xsd:element ref="child3"/>
        <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="child4"/>
      </xsd:sequence>
      <xsd:sequence>
        <xsd:element ref="child4"/>
        <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="child3"/>
      </xsd:sequence>
    </xsd:choice>  
    <xsd:group ref="onetwo" minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
</xsd:complexType>

XSD 1.1では、all- groupsの制約の一部が解除されたため、このコンテンツモデルをより簡潔に定義できます。

<xsd:complexType name="paul3">
  <xsd:all>
    <xsd:element ref="child1" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:element ref="child2" minOccurs="0" maxOccurs="unbounded"/>
    <xsd:element ref="child3"/>
    <xsd:element ref="child4"/>      
  </xsd:all>
</xsd:complexType>

しかし、前述の例からわかるように、all- groupsに対するこれらの変更は、実際には言語の表現力を変更しません。特定の種類の言語の定義をより簡潔にするだけです。

これは最終的に私のために働いたものです:

<xsd:element name="bar">
  <xsd:complexType>
    <xsd:sequence>
      <!--  Permit any of these tags in any order in any number     -->
      <xsd:choice minOccurs="0" maxOccurs="unbounded">
        <xsd:element name="child1" type="xsd:string" />
        <xsd:element name="child2" type="xsd:string" />
        <xsd:element name="child3" type="xsd:string" />
      </xsd:choice>
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>
47
Alan

しかし、私が理解していることから、xs:choiceはまだ単一要素の選択のみを許可しています。したがって、このようにMaxOccursをunboundedに設定するということは、子要素の「いずれか」が複数回出現する可能性があることを意味するだけです。これは正確ですか?

いいえ。xs:choiceが原因で発生するmaxOccurs="unbounded"の「繰り返し」ごとに、個別に選択が行われます。したがって、投稿したコードは正しいものであり、実際に記述したとおりに実行します。

8
Pavel Minaev

次のスキーマにより、提案したものが許可されることがわかります。

  <xs:element name="foo">
    <xs:complexType>
      <xs:sequence minOccurs="0" maxOccurs="unbounded">
        <xs:choice>
          <xs:element maxOccurs="unbounded" name="child1" type="xs:unsignedByte" />
          <xs:element maxOccurs="unbounded" name="child2" type="xs:string" />
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

これにより、次のようなファイルを作成できます。

<?xml version="1.0" encoding="utf-8" ?>
<foo>
  <child1>2</child1>
  <child1>3</child1>
  <child2>test</child2>
  <child2>another-test</child2>
</foo>

あなたの質問と一致するようです。

3
Steven_W

上記のいずれも機能していない場合、おそらくHIPPAスキーマまたはその他の複雑なxsdに対して結果を検証する必要があるEDIトランザクションに取り組んでいる可能性があります。要件は、8つのREFセグメントがあり、それらのいずれかが任意の順序で出現する必要があり、すべてが必要というわけではないということです。デフォルトの状況EDIでは、受信は失敗します。デフォルトの複合タイプは

<xs:sequence>
  <xs:element.../>
</xs:sequence>

参照によって要素を呼び出す場合、状況はさらに複雑になり、元のスポットの要素自体は非常に複雑になります。例えば:

<xs:element>
<xs:complexType>
<xs:sequence>
<element name="REF1"  ref= "REF1_Mycustomelment" minOccurs="0" maxOccurs="1">
<element name="REF2"  ref= "REF2_Mycustomelment" minOccurs="0" maxOccurs="1">
<element name="REF3"  ref= "REF3_Mycustomelment" minOccurs="0" maxOccurs="1">
</xs:sequence>
</xs:complexType>
</xs:element>

解決:

ここでは、単に「シーケンス」を「すべて」に置き換えるか、「選択」を使用して最小/最大の組み合わせを使用しても機能しません。

最初に"xs:sequence" with "<xs:all>"を置き換えます。ここで、要素の参照元を変更する必要があります。

<xs:annotation>
  <xs:appinfo>
    <b:recordinfo structure="delimited" field.........Biztalk/2003">

***上記のセグメントで、このように最後にトリガーポイントを追加します「、「XX」、「YY」など。レコード情報は次のようになります。b:recordinfo structure="delimited" field.........Biztalk/2003" trigger_field="REF01_...complete name.." trigger_value="38">


これにより、各要素が一意になります。理由は、すべてのREFセグメント(上記の例)がREF01、REF02、REF03などの同じ構造を持つためです。また、検証中は構造の検証は問題ありませんが、最初のREF自体の残りの値を検索しようとするため、値を繰り返すことはできません。トリガーを追加すると、それらはすべて一意になり、任意の順序および状況の場合に渡されます(すべてが9/9ではなく、5 out 9を使用するなど)。

私がこれにほぼ20時間費やしたので、それがあなたを助けることを願っています。

幸運を

1
Prabhdeep Gill