XSD element with nillable attributes changes name of element in generated XML
Question asked by Lee Carter - 9/6/2017 at 1:07 PM
Answered
I have a 3rd party XSD (cannot provide full XDS but will attempt to provide sensible snippets) that defines an element with the nillable attribute:
 
  <xs:element name="locationType" nillable="true">
    <xs:complexType>
      <xs:simpleContent msdata:ColumnName="locationType_Text" msdata:Ordinal="4">
        <xs:extension base="xs:string">
          <xs:attribute name="units" type="xs:string" use="required" />
          <xs:attribute name="datum" type="xs:string" />
          <xs:attribute name="zone" type="xs:string" />
          <xs:attribute name="north" type="xs:string" />
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
This element is then used in other elements such as:
  <xs:element name="TopLevelElement">
    <xs:complexType>
      <xs:element name="LocationDefinition" minOccurs="0" maxOccurs="1">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="locationType" minOccurs="1" maxOccurs="1" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:complexType>
  </xs:element>  
When XSD is processed by the Data Binder to produce C++ code, it appears to create both CLocationType and CLocationType_nillable classes and the relevant CSmartPtr<class> typedefs.
 
The class generated for LocationDefinition has get/set methods for LocationType but these methods only return/take a LocationType_nillable pointer.
 
When the XML string is generated for TopLevelElement where a LocationDefinition has been added, the XML looks something like:
 
<?xml version="1.0"?>
<TopLevelElement>
  <LocationDefinition>
    <locationType_nillable units="someunits" datum="somedatum" north="Grid">GPS</locationType_nillable>
  </LocationDefinition>
</TopLevelElement>
The above is not what I expected.  The locationType within the LocationDefinition should not have the "_nillable" in its element name.
 
I would have expected the LocationType class to have had a SetIsNil(bool) method and GetIsNil() method that returns a bool but it is only the LocationType_nillable class that has these.
 
The CLocationDefinition::SetLocationType(...) method will not take a CLocationType* as the parameter, only a CLocationType_nillable*
 
The only way I have found to make the XML acceptable to the 3rd party server receiving the XML is to override the name of the element when creating CLocationType_nillable object with CLocationType_nillable::CreateInstance("locationType") before passing it to CLocationDefinition::SetLocationType(...) but having to do this does not seem right to me.
 
Am I doing something wrong in the data binder or use of the generated C++ library?
Liquid Support Replied
Employee Post
Hi,
Yes you are correct, the nillable generated class should use the element name "locationType". I have raised this as an issue to be fixed in the next point release.
 
Your workaround is also correct, the following works OK:
CTopLevelElementPtr elm = CTopLevelElement::CreateInstance();
CLocationDefinitionPtr def = CLocationDefinition::CreateInstance();
CLocationType_NillablePtr type = CLocationType_Nillable::CreateInstance("locationType");
type->SetUnits("test");
def->SetLocationType(type);
elm->SetLocationDefinition(def);
 
Lee Carter Replied
Thank you for the reply.

I currently have the latest available version (15.1.12) installed. By "the next point release" do you mean 15.1.13 or 15.2.x?

I am concerned that the fix may not be available before my USPP expires.
Liquid Support Replied
Employee Post
It will be in 15.1.13 later today or tomorrow at the latest.
Liquid Support Replied
Employee Post Marked As Answer
This fix is now live and can be downloaded from:
Lee Carter Replied
Regenerated and rebuilt C++ library using the new 15.1.13 release of XML Data Binder and nillable elements look like they are correctly named now.

Reply to Thread