How to do mutually exclusive attributes in XML schema? How to do mutually exclusive attributes in XML schema? xml xml

How to do mutually exclusive attributes in XML schema?


You can't do with attributes, but you can with child elements...

<element name="elem">    <complexType>        <choice>            <element name="value"/>            <element name="ref"/>        </choice>    </complexType></element>

This way you can have...

<elem>    <value>1</value></elem>

or...

<elem>    <rel>something else</rel></elem>


Unfortunately AFAIK you can't do that with XML Schema, I've had the same problem myself.

I've seen it suggested that if you need both of:

<elem type="xxx"> <elem ref="yyy">

then <elem> itself should be split into two types, since they've clearly got different attributes...


Since RelaxNG was mentioned in Alnitak's answer, here is a solutionwith RelaxNG (a language which is, in most cases, better than W3CSchema). Do note the OR (|) in the definition of elem:

start = documentdocument = element document {elem+}elem = element elem {ref | value}ref = attribute ref {text}value = attribute value {xsd:integer}

If I have this XML file:

<document>    <elem value="1" />    <elem ref="something else" /></document>

It is accepted by rnv and xmlint:

 % rnv attributes-exclusive.rnc attributes-exclusive.xml              attributes-exclusive.xml % xmllint --noout --relaxng attributes-exclusive.rng attributes-exclusive.xml  attributes-exclusive.xml validates

If I add in the XML file:

<elem value="1" ref="something else" />

I get validation errors, as I want (do note that the error messagesare suboptimal):

% rnv attributes-exclusive.rnc attributes-exclusive.xml    attributes-exclusive.xmlattributes-exclusive.xml:4:0: error: attribute ^ref not allowedrequired:       after% xmllint --noout --relaxng attributes-exclusive.rng attributes-exclusive.xmlattributes-exclusive.xml:4: element elem: Relax-NG validity error : Invalid attribute value for element elemattributes-exclusive.xml fails to validate