I have a situation where I have different XMLs that will have different types of properties. Sometimes the element HEADER
could have just a node or some XMLs could have elements within the HEADER
node and values inside.
Example 1 (HEADER
with just text):
<Details HeaderLabel="DETAILS">
<HEADER Label="Header">2.5%</HEADER>
</Details>
Example 2 (HEADER
with two child elements):
<Details HeaderLabel="DETAILS">
<HEADER Label="Header">
<HEAD Label="H1a">2.88%</HEAD>
<HEAD Label="H2b">3.24%</HEAD>
</HEADER>
</Details>
The XSD works as so: This will validate for example 1:
<xs:element name="HEADER">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Label" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
This will validate the example 2:
<xs:element name="HEADER">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="HEAD">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Label" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Label" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
I tried using xs:choice
but it didn't seem to work well or maybe I don't have a clear understanding on how to implement choice in this situation.
In XSD, you cannot allow both simple and complex content unless you're willing to have mix elements and text via mixed="true"
(in this case Example 1 is not needed). You could then used XSD 1.1 assertions to exclude both from appearing simultaneously.
<xs:element name="HEADER">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="HEAD">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Label" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Label" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
However, you're swimming against the current here. Instead, accept that you really have two different entities with two different content models and name the different entities differently: SIMPLE_HEADER
and COMPLEX_HEADER
comes to mind. Then you can use xs:choice/maxOccurs="unbounded"
on Details
to allow simple and complex headers to be freely interspersed.