Since RelaxNG was mentioned in Alnitak's answer, here is a solution
with RelaxNG (a language which is, in most cases, better than W3C
Schema). Do note the OR (|) in the definition of elem:
start = document
document = 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 messages
are suboptimal):
% 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