I have an element that could look like this:
<MyElement start="12.5. 2020" end="6.6 2020" info="Hello world!"/>
But also this:
<!-- This element still can contain useful info, but is not time-bound -->
<MyElement info="42" />
So I'd like to set the definition of the node so that either non or both of the attributes must be present. So far, I just used documentation to document the requirement, but it would be better if it was directly in the schema:
<xsd:complexType name="MyElement">
<xsd:attribute name="start" type="MyDate" use="optional">
<xs:annotation>
<xs:documentation>end date must also be present!</xs:documentation>
</xs:annotation>
</xsd:attribute>
<xsd:attribute name="end" type="MyDate" use="optional">
<xs:annotation>
<xs:documentation>start date must also be present!</xs:documentation>
</xs:annotation>
</xsd:attribute>
<xsd:attribute name="info" type="xsd:string" use="required" />
</xsd:complexType>
Your constraint cannot be enforced in XSD 1.0 alone.
Your constraint can be enforced in XSD 1.1 using xsd:assert
:
<xsd:assert test="(@start and @end) or (not(@start) and not(@end)) "/>
Show in context:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
elementFormDefault="qualified"
vc:minVersion="1.1">
<xsd:complexType name="MyElement">
<xsd:attribute name="start" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation>end date must also be present!</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="end" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation>start date must also be present!</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="info" type="xsd:string" use="required" />
<xsd:assert test="(@start and @end) or (not(@start) and not(@end)) "/>
</xsd:complexType>
<xsd:element name="MyElement" type="MyElement"/>
</xsd:schema>