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