How Do I deal with <Choice> elements?

Problem

One of the main constructs of an XSD schema is the <choice> group type. Simply put this means that only one of the elements described within it can be present.

Resolution

Liquid XML copes with a choice by wrappering it with a class. This class has properties for each of the elements that can be present, and an additional property ChoiceSelectedElement, which allows you to determine which of them is currently populated.

If you have a choice and one of the elements is already populated, then setting another will clear the current contents of the choice, and set the new.

Example

Using the following schema as an example

<xs:element name="ElmChoice"> <xs:complexType> <xs:choice> <xs:element ref="BasicElement"/> <xs:element name="ElmChoiceComplexType" type="BasicComplexType"/> <xs:element name="stringElm" type="xs:string"/> </xs:choice> </xs:complexType> </xs:element>

  C++

class ElmChoice_DLL CElmChoice : public CInstanceMonitor , public virtual LtXmlLib16::CXmlGeneratedClass { public: CElmChoice() ... CBasicElementPtr GetBasicElement() ... void SetBasicElement(CBasicElement* lpVal) ... CBasicComplexTypePtr GetBasicComplexType() ... void SetBasicComplexType(CBasicComplexType* lpVal) ... std::tstring GetStringElm() ... void SetStringElm(LPCTSTR lpstr) ... bool IsValidStringElm() ... std::tstring GetChoiceSelectedElement() ... }

Note: Because StringElm is a primitive type is has a method IsValidStringElm, to allow you to determine whether it is set or not.

CElmChoicePtr spElm = ... // nothing set initially ASSERT(spElm->GetChoiceSelectedElement() == _T("")); ASSERT(spElm->GetBasicElement() == NULL); ASSERT(spElm->GetElmChoiceComplexType() == NULL); ASSERT(spElm->IsValidStringElm() == false); // we'll set the StringElm property spElm->SetStringElm(_T("Value")); ASSERT(spElm->GetChoiceSelectedElement() == _T("StringElm")); ASSERT(spElm->GetBasicElement() == NULL); ASSERT(spElm->GetElmChoiceComplexType() == NULL); ASSERT(spElm->IsValidStringElm() == true); // if we now set another property then it will clear the first, and set that one spElm->SetBasicElement(CBasicElement::CreateInstance()); ASSERT(spElm->GetChoiceSelectedElement() == _T("BasicElement")); ASSERT(spElm->GetBasicElement() != NULL); ASSERT(spElm->GetElmChoiceComplexType() == NULL); ASSERT(spElm->IsValidStringElm() == false);

  C#

public class ElmChoice : LiquidTechnologies.Runtime.Net40.XmlGeneratedClass { public ElmChoice() ... public ElmChoice.BasicElement BasicElement { get ... set ... } public ElmChoice.BasicComplexType ElmChoiceComplexType { get ... set ... } public String StringElm { get ... set ... } public Boolean IsValidStringElm { get ... set ... } public String ChoiceSelectedElement { get ... } }

Note: Because StringElm is a primitive type is has a method IsValidStringElm, to allow you to determine whether it is set or not.

ElmChoice elm = ... // nothing set initially Debug.Assert(elm.ChoiceSelectedElement == ""); Debug.Assert(elm.BasicElement == null); Debug.Assert(elm.ElmChoiceComplexType == null); Debug.Assert(elm.IsValidStringElm == false); // we'll set the StringElm property elm.StringElm = "Value"; Debug.Assert(elm.ChoiceSelectedElement == "StringElm"); Debug.Assert(elm.BasicElement == null); Debug.Assert(elm.ElmChoiceComplexType == null); Debug.Assert(elm.IsValidStringElm == true); // if we now set another property then it will clear the first, and set that one elm.BasicElement = new BasicElement(); Debug.Assert(elm.ChoiceSelectedElement == "BasicElement"); Debug.Assert(elm.BasicElement != null); Debug.Assert(elm.ElmChoiceComplexType == null); Debug.Assert(elm.IsValidStringElm == false);

  Java

public class ElmChoice extends com.liquid_technologies.ltxmllib16.XmlGeneratedClass { public ElmChoiceA() ... public ElmChoice.BasicElement getBasicElement() ... public void setBasicElement(ElmChoice.BasicElement value) throws com.liquid_technologies.ltxmllib16.exceptions.LtException ... public ElmChoice.BasicComplexType getElmChoiceComplexType() ... public void setElmChoiceComplexType(ElmChoice.BasicComplexType value) throws com.liquid_technologies.ltxmllib16.exceptions.LtException ... public java.lang.String getStringElm() throws com.liquid_technologies.ltxmllib16.exceptions.LtException ... public void setStringElm(java.lang.String value) throws com.liquid_technologies.ltxmllib16.exceptions.LtException ... public boolean isValidStringElm() ... public void setValidStringElm(boolean value) throws com.liquid_technologies.ltxmllib16.exceptions.LtException ... public String getChoiceSelectedElement() ... }

Note: Because StringElm is a primitive type is has a method IsValidStringElm, to allow you to determine whether it is set or not.

ElmChoice elm = ... // nothing set initially Assert(elm.getChoiceSelectedElement().Equals("")); Assert(elm.getBasicElement() == null); Assert(elm.getElmChoiceComplexType() == null); Assert(elm.isValidStringElm() == false); // we'll set the StringElm property elm.setStringElm("Value"); Assert(elm.getChoiceSelectedElement().Equals("StringElm")); Assert(elm.getBasicElement() == null); Assert(elm.getElmChoiceComplexType() == null); Assert(elm.isValidStringElm() == true); // if we now set another property then it will clear the first, and set that one elm.setBasicElement(new BasicElement()); Assert(elm.getChoiceSelectedElement().Equals("BasicElement")); Assert(elm.getBasicElement() != null); Assert(elm.getElmChoiceComplexType() == null); Assert(elm.isValidStringElm() == false);

  Visual Basic

public Property Get BasicElement as ElmChoice.BasicElement ... End Property public Property Set BasicElement(ByVal value as ElmChoice.BasicElement) ... End Property public Property Get ElmChoiceComplexType as ElmChoice.BasicComplexType ... End Property public Property Set ElmChoiceComplexType(ByVal value as ElmChoice.BasicComplexType) ... End Property public Property Get StringElm as String ... End Property public Property Let StringElm(byval value as String) ... End Property public Property Get IsValidStringElm as Boolean ... End Property public Property Let IsValidStringElm(byval value as Boolean) ... End Property public property get ChoiceSelectedElement as String ... End Property

Note: Because StringElm is a primitive type is has a method IsValidStringElm, to allow you to determine whether it is set or not.

Dim elm as ElmChoice Set elm = ... ' nothing set initially Debug.Assert elm.ChoiceSelectedElement = "" Debug.Assert elm.BasicElement is nothing Debug.Assert elm.ElmChoiceComplexType is nothing Debug.Assert elm.IsValidStringElm = false ' we'll set the StringElm property elm.setStringElm("Value" Debug.Assert elm.getChoiceSelectedElement = "StringElm" Debug.Assert elm.getBasicElement is nothing Debug.Assert elm.getElmChoiceComplexType is nothing Debug.Assert elm.isValidStringElm = true ' if we now set another property then it will clear the first, and set that one set elm.setBasicElement = new BasicElement Debug.Assert elm.getChoiceSelectedElement = "BasicElement" Debug.Assert Not elm.getBasicElement is Nothing Debug.Assert elm.getElmChoiceComplexType is nothing Debug.Assert elm.isValidStringElm = false

 

Notes

Description Value
Article Created 6/2/2006
Version Liquid XML 2005 and greater