2 つの XML 属性を相互に排他的にしようとしています。この種のシナリオをキャプチャする XSD スキーマを作成するにはどうすればよいでしょうか?
私はこれらのうちの1つを持っていたいです
<elem value="1" />
<elem ref="something else" />
だがしかし
<elem value="1" ref="something else" />
2 つの XML 属性を相互に排他的にしようとしています。この種のシナリオをキャプチャする XSD スキーマを作成するにはどうすればよいでしょうか?
私はこれらのうちの1つを持っていたいです
<elem value="1" />
<elem ref="something else" />
だがしかし
<elem value="1" ref="something else" />
属性を使用することはできませんが、子要素を使用することはできます...
<element name="elem">
<complexType>
<choice>
<element name="value"/>
<element name="ref"/>
</choice>
</complexType>
</element>
このようにあなたは持つことができます...
<elem>
<value>1</value>
</elem>
また...
<elem>
<rel>something else</rel>
</elem>
残念ながら、XMLスキーマではそれを行うことはできません。私自身も同じ問題を抱えています。
私はそれがあなたが両方を必要とするならばそれが示唆するのを見ました:
<elem type="xxx">
<elem ref="yyy">
明らかに異なる属性を持っているので、それ<elem>
自体を2つのタイプに分割する必要があります...
RelaxNGは Alnitak の回答で言及されているため 、RelaxNG (ほとんどの場合、W3C スキーマよりも優れた言語) を使用したソリューションを次に示します。elem の定義の OR (|) に注意してください。
start = document
document = element document {elem+}
elem = element elem {ref | value}
ref = attribute ref {text}
value = attribute value {xsd:integer}
この XML ファイルがある場合:
<document>
<elem value="1" />
<elem ref="something else" />
</document>
% rnv attributes-exclusive.rnc attributes-exclusive.xml
attributes-exclusive.xml
% xmllint --noout --relaxng attributes-exclusive.rng attributes-exclusive.xml
attributes-exclusive.xml validates
XML ファイルに追加すると、次のようになります。
<elem value="1" ref="something else" />
必要に応じて検証エラーが発生します(エラーメッセージが最適ではないことに注意してください):
% rnv attributes-exclusive.rnc attributes-exclusive.xml
attributes-exclusive.xml
attributes-exclusive.xml:4:0: error: attribute ^ref not allowed
required:
after
% xmllint --noout --relaxng attributes-exclusive.rng attributes-exclusive.xml
attributes-exclusive.xml:4: element elem: Relax-NG validity error : Invalid attribute value for element elem
attributes-exclusive.xml fails to validate
XSD には、このための抽象型があります: http://www.tek-tips.com/viewthread.cfm?qid=1364846 (tsuji の投稿を参照)
基本的に、手元の要素に抽象的で複雑なタイプを与え、そこに共通の属性を定義します。これは、すべての異なるユースケースでまったく同じです(例では必要ありません)。
次に、先ほど説明した抽象型を拡張する 2 つ (またはそれ以上) の追加の複合型を作成します。これらの新しいタイプ内で、ユース ケースごとに異なる属性セットを定義します。XSDの部分は以上です。
type
最後に、スキーマ インスタンス ドキュメント内の結果の要素にXSI 属性を追加する必要があります。そのため、有効であるためには、要素はいずれかの属性セットを持つ必要があります。
単純ではありませんが、柔軟性があります。ご存知のように、柔軟になればなるほど、何かが難しくなります。