Skip to content
OpenCms documentation
OpenCms documentation

Usage of the XSD choice element

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

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 a nested XML schema definition. The element in the root schema has to be optional. Add an 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>

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 chioce:

<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>
View of a multiple choice in the content editor (one choice already done)

View of a multiple choice in the content editor (one choice already done)

View of a choice in the content editor (no choice taken before)

 View of a choice in the content editor (no choice taken before)

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:

<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>