The XSD choice element extends the XML Schema definition. It provides a single or multiple choices of content elements in an arbitrary order. We describes how to use the choice element within XSDs and how to access the values in a JSP with EL.

Using <xsd:choice> in an XSD

The <xsd:choice>-node can be used in the same way as a <xsd:sequence> to describe an OpenCms type. It has to be defined in XML schema definition of a nested XML content. The element in the root schema has to be optional. Add attribute minOccurs="0" on the element to make it optional. Root XML Schema Definition:

...
  <xsd:complexType name="OpenCmsDevDemoSettingsArticle">
    <xsd:sequence>
      ...
      <xsd:element name="Options" type="OpenCmsDevDemoTextOption" minOccurs="0" />
      ... 
    </xsd:sequence>
...

Use the <xsd:choice>-node to define the element of the selection. The elements, which define the selection options of the <xsd:choice> have to be optional, too. Nested XML schema definition with <xsd:choice>:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
           elementFormDefault="qualified">	
	<xsd:include schemaLocation="opencms://opencms-xmlcontent.xsd"/>
	…	
	<xsd:complexType name="OpenCmsDevDemoTextOption">
		<xsd:choice minOccurs="0" maxOccurs="3">
		 <xsd:element name="Text" type="OpenCmsString" minOccurs="0" />
		 <xsd:element name="Html" type="OpenCmsHtml" minOccurs="0" />
		 <xsd:element name="Link" type="OpenCmsVarLink" minOccurs="0" />
		</xsd:choice>
		<xsd:attribute name="language" type="OpenCmsLocale" use="optional"/>
	</xsd:complexType>
</xsd:schema>

Single and multiple choices

The <xsd:choice>-element can be used as single or multiple choice. To use the single choice do not use any attributes on the <xsd:choice>-node. This is the default setting.
To use the multiple choice set following attributes:

  • minOccurs="0" and
  • maxOccurs="[max number of elements]", e.g., maxOccurs="5"

Single choice:

<xsd:choice>
   <xsd:element name="VariableLink" type="OpenCmsVarLink" minOccurs="0" />
   <xsd:element name="LinkGallery" type="OpenCmsVfsFile" minOccurs="0" />
   <xsd:element name="DownloadGallery" type="OpenCmsVfsFile" minOccurs="0" />
</xsd:choice>

Multiple choice:

<xsd:choice minOccurs="0" maxOccurs="5">
   <xsd:element name="VariableLink" type="OpenCmsVarLink" minOccurs="0" />
   <xsd:element name="LinkGallery" type="OpenCmsVfsFile" minOccurs="0" />
   <xsd:element name="DownloadGallery" type="OpenCmsVfsFile" minOccurs="0" />
</xsd:choice>

Content editor

Fig. [xsdchoice_contenteditor1]: View of a multiple choice in the content editor (one choice already done)
Fig. [xsdchoice_contenteditor2]: View of a choice in the content editor (no choice taken before)

Accessing values in JSPs

The elements of a <xsd:choice>-node can be accessed in the same way as elements of the nested content. Before the content value is read, the existence of the root element and the choice elements have to be tested for their existence, e.g.:

<c:if test="${value.Options.exists && value.Options.value.Text.isSet}">
   <div>${value.Options.value.Text}</div>
</c:if>

Note that the property exists checks if an element exists, while isSet checks if the element exists and is not empty.

The other choice elements can be accessed in the same way. Complete example with a choice element inside a nested content (v8InfoBox):

<c:if test="${value.FurtherInfo.value.Link.exists 
            && (value.FurtherInfo.value.Link.value.VariableLink.isSet 
            || value.FurtherInfo.value.Link.value.LinkGallery.isSet 
            || value.FurtherInfo.value.Link.value.DownloadGallery.isSet)}">
   <c:choose>
       <c:when test="${value.FurtherInfo.value.Link.value.VariableLink.isSet}">
	    <c:set var="infolink">
               ${value.FurtherInfo.value.Link.value.VariableLink}
           </c:set>
	</c:when>
	<c:when test="${value.FurtherInfo.value.Link.value.LinkGallery.isSet}">
	    <c:set var="infolink">
               ${value.FurtherInfo.value.Link.value.LinkGallery}
           </c:set>
	</c:when>
       <c:when test="${value.FurtherInfo.value.Link.value.DownloadGallery.isSet}">
	    <c:set var="infolink">
                ${value.FurtherInfo.value.Link.value.DownloadGallery}
           </c:set>
	</c:when>
   </c:choose>
   <c:set var="infotext">${infolink}</c:set> ...
   <div class="boxbody_listentry">
       <c:set var="link"><cms:link>${infolink}</cms:link></c:set>
       <a href="${link}">${infotext}</a><br/>
   </div>
</c:if>