Simple vs. complex content
Simple vs. complex content (a co-constraint use case)
source: Kieran Dolan[1]
Other use cases: Co-constraint Use Cases
Description
Is there any way in XML schema to specify that an element contains either simple content or complex content but not both? For example: `<X>23</X>` is valid and `<X><Y>45</Y></X>` is also valid but not `<X>23<Y>45</Y></X>`
Use of a `mixed` content model permits the first two cases but does not exclude the last one.
Analysis
HT
slightly off-topic
FV
This is an UNCONDITIONED CHOICE OF TYPE on an ELEMENT
CoConstraintDimensionSource: |
CoConstraintDimensionDestination: |
CoConstraintDimensionType: |
CoConstraintDimensionEffect: |
CoConstraintDimensionAxis: |
Possible solutions
Relax NG
Schematron
Check clause
A partial solution to this use case is to declare the type with mixed content (as suggested by the original poster) and then add this constraint:
<xsd:annotation><xsd:appinfo><sch:pattern><sch:rule> <sch:assert test="count(./Y) = 0 or count(./text()[normalize-space(.) != '']) = 0"> Content must either be character data (only) or child elements and whitespace (only). </sch:report> </sch:rule></sch:pattern></xsd:appinfo></xsd:annotation>
(assuming that the only possible child is the Y element seen in the example).
The solution is only partial, since when Y is not present, the content is not really simple, but mixed. So in particular, '42' will be a sequence of characters, not the lexical representation of an integer or decimal or ...
(Solution provided by MSM)
SchemaPath
One of the possible solutions is:
<xsd:element name="X"> <xsd:alt cond="./Y"> <xsd:complexType> <xsd:sequence> <xsd:element name="Y" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:alt> <xsd:alt type="xsd:string"/> </xsd:element>
Conditional Type
<xsd:element name="X"> <xsd:complexType> <xsd:alt cond="./Y"> <xsd:sequence> <xsd:element name="Y" type="xsd:string"/> </xsd:sequence> </xsd:alt> <xsd:alt> <xsd:simpleContent> <xsd:extension base="xsd:string"> </xsd:simpleContent> </xsd:alt> </xsd:complexType> </xsd:element>