XSD を作成し、次の要件で定義を記述しようとしています。
- 指定された子要素を任意の回数だけ出現させる(0~無制限)
- 子要素を任意の順序で配置できるようにする
いろいろ調べてみると、次のような解決策が見つかりましたこれ:
<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 を無制限に設定すると、子要素の「いずれか 1 つ」が複数回出現できることを意味するだけです。これは正しいですか?
上記の解決策が正しくない場合、要件で上記に述べた内容をどのように達成できますか?
編集: 要件が次のような場合はどうでしょうか?
- 要素 child1 child2 は任意の回数出現できます (0 から無制限)
- 要素は任意の順序で配置されます
- 要素 child3 と child4 は 1 回だけ出現する必要があります。
たとえば、次の XML は有効です。
<foo>
<child1> value </child1>
<child1> value </child1>
<child3> value </child3>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>
しかし、これは(行方不明の子供3)ではありません
<foo>
<child1> value </child1>
<child1> value </child1>
<child2> value </child2>
<child4> value </child4>
<child1> value </child1>
</foo>
ベストアンサー1
後の編集で追加された質問の代替表現は、まだ回答されていないようです。つまり、要素の子の中に、 という名前の要素が 1 つchild3
、 という名前の要素が 1 つ、およびまたは というchild4
名前の要素がいくつも存在し、子の出現順序に制約がないことを指定する方法です。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>
およびの 0 個以上の選択肢を挿入するのはchild1
簡単child2
です。
<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>
かさばりを少しでも抑えたい場合は、child1
との繰り返し選択に名前付きグループを定義できますchild2
。
<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 では、 -group の制約の一部all
が解除されたため、このコンテンツ モデルをより簡潔に定義できるようになりました。
<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
-group の変更は実際には言語の表現力を変えるものではなく、特定の種類の言語の定義をより簡潔にするだけです。