Generating C Code from XSD

Previous Menu Next

Generating C Code from XML Schemas

Let's look again at our Purchase.xsd file from previously, which is reproduced here:

   <xsd:element name="purchase" type="PurchaseRecord"/>

   <xsd:complexType name="PurchaseRecord">
      <xsd:sequence>
         <xsd:element name="customer" type="CustomerType" maxOccurs="1"/>
         <xsd:element name="store" type="xsd:string" maxOccurs="1"/>
         <xsd:sequence maxOccurs="unbounded">
            <xsd:element name="item" type="xsd:string"/>
            <xsd:element name="price" type="xsd:float"/>
         </xsd:sequence>
      </xsd:sequence>
   </xsd:complexType>

   <xsd:complexType name="CustomerType">
      <xsd:simpleContent>
         <xsd:extension base="xsd:string">
            <xsd:attribute name="number" type="xsd:integer"/>
         </xsd:extensiion>
      </xsd:simpleContent>
   </xsd:complexType>
   

This command will produce four files, as follows:

FilePurpose
PurchaseRecord.h Contains definitions of structures that correspond to the elements in the schema and declarations of functions whose implementations are in the .c files.
PurchaseRecord.cContains various utility functions
PurchaseRecordDec.c Contains implementations of functions to decode a PurchaseRecord instance.
PurchaseRecordEnc.c Contains implementations of functions to encode a PurchaseRecord.instance.

 

Let's look a little more closely at some of the structures generated for the element declarations in the .xsd file. We will look first at the code that gets generated for the CustomerType. Here is the schema declaration again:

      <xsd:complexType name="CustomerType">
      <xsd:simpleContent>
         <xsd:extension base="xsd:string">
            <xsd:attribute name="number" type="xsd:integer"/>
         </xsd:extensiion>
      </xsd:simpleContent>
   </xsd:complexType>
   

The defining code that gets generated in Purchase.h looks like this:

   /**
   * CustomerType
   */

   typedef struct EXTERN CustomerType {
      struct {
         unsigned numberPresent : 1;
      } m;
      OSXMLSTRING _base;

      /* attributes */
      OSINT32 number;

      /* namespace attributes - list of OSXMLNamespace */
      OSRTDList _nsAttrs;
   } CustomerType;

Take note of the following:

  • The complexType definition in the .xsd file results in a struct definition in the .h file.
  • Attributes that may appear in an element instance each have a bit defined in the structure to indicate whether they're present.
  • The base value of the element is represented as a string member of the structure.
  • The value of the attribute is represented as an integer member of the structure.

Now let's look at the code that gets generated for the PurchaseRecord, which appears like this in the schema:

   <xsd:complexType name="PurchaseRecord">
      <xsd:sequence>
         <xsd:element name="customer" type="CustomerType" maxOccurs="1"/>
         <xsd:element name="store" type="xsd:string" maxOccurs="1"/>
         <xsd:sequence maxOccurs="unbounded">
            <xsd:element name="item" type="xsd:string"/>
            <xsd:element name="price" type="xsd:float"/>
         </xsd:sequence>
      </xsd:sequence>
   </xsd:complexType>

The defining code that gets generated in PurchaseRecord.h looks like this:

   /**
   * PurchaseRecord
   */

   typedef struct EXTERN PurchaseRecord {
      CustomerType customer;
      OSXMLSTRING store;
      /* List of PurchaseRecord_3 */
      OSRTDList _seq3;

      /* namespace attributes - list of OSXMLNamespace */
      OSRTDList _nsAttrs;
   } PurchaseRecord;

Take note of the following:

  • The customer element in the purchase record is simply a member of type CustomerType, the definition for which we just examined.
  • The store element is simply a string member of the structure.
  • The collection of items and prices, which might repeat within an instance, is represented by a list member of the structure. This list is managed as a list of PurchaseRecord_3 items in the functions that do the encoding and decoding. Let's look now at the definition of PurchaseRecord_3.

XBinder generates a separate structure for the elements within the PurchaseRecord that might repeat. This structure, called PurchaseRecord_3 (3 simply because it's the third element in the PurchaseRecord) is defined as follows:

   /**
   * PurchaseRecord_3
   */

   typedef struct EXTERN PurchaseRecord_3 {
      OSXMLSTRING item;
      OSREAL price;
   } PurchaseRecord_3;

Here we see that the item element is simply expressed as a string structure member, and the price element is a decimal (real) structure member.

Previous Menu Next