SAX Based Decode Functions

If -sax is specified on the XBinder command-line or selected in the GUI, SAX-based decode functions are generated. The code generated in this case uses off-the-shelf XML parser software to parse the XML documents to be decoded. This software contains a common interface known as the Simple API for XML (or SAX) that is a de-facto standard that is supported by many parsers. XBinder generates an implementation of the content handler interface defined by this standard. This implementation receives the parsed XML data and uses it to populate the structures generated by the compiler.

The default XML parser used is the GNOME LibXML2 parser ( http://xmlsoft.org). This is a fullfeatured, open-source parser that was implemented in C. XBinder generates C SAX handler functions that are called from the SAX interface of this framework to decode XML data into the generated typed data structures. The interface was designed to be generic so that other XML parsers could be easily substituted. An interface to the EXPAT parser ( http://www.expat.org) is also available as well as an interface to a custom micro-parser for memory constrained applications. Interfacing to other parsers requires only building an abstraction layer to map the common interface to the vendor's interface. See the SAX Parser Interface section below for more details.

XBinder generates code to implement the following functions defined in the SAX content handler interface:

       startElement

       characters

       endElement

The interface defines other methods that can be implemented as well, but these are sufficient to decode XML encoded data.

Generated C Function Format and Calling Parameters

Generated decode functions are written to a .c file with a name of the following format:

       <xsdFileName>Dec.c

where <xsdFileName> is the base name of the XSD file being parsed. For example, if code is being generated for file x.xsd, decode functions for each global element defined in the specification will be written to xDec.c . In addition, the SAX handler functions that are invoked by the underlying XML parser software are written to a file with a name of the following format:

       <xsdFileName>SAX.c

The format of the name of each generated C XML decode function is as follows:

       [<ns>]XmlD_<elemName

where <elemName>is the name of the XSD global element for which the function is being generated and <ns>is an optional namespace setting that can be used to disambiguate element names from multiple sources (note: this should not be confused with XML namespaces which are different).

The calling sequence for each decode function (except WSDL output operation deocde function) is as follows:

       status = <decodeFunc> (OSCTXT* pctxt, <typeName>*
pvalue);

In this definition, <decodeFunc> is the name of the decode function described above and <typeName> is the name of the generated C type definition for the global element.

The pctxtargument is used to hold a context pointer to keep track of decode parameters. This is a basic "handle" variable that is used to make the function reentrant so that it can be used in an asynchronous or threaded application. The user is required to supply a pointer to a variable of this type declared somewhere in his or her program. The variable must be initialized using the rtXmlInitContext run-time function before use.

The pvalueargument is a pointer to a variable to hold the decoded result. This variable is of the type generated for the XSD type of the global element. The decode function will automatically allocate dynamic memory for variable length fields within the structure. This memory is tracked within the context structure and is released when the context structure is freed.

The function result variable statusreturns the status of the decode operation. Status code zero indicates the function was successful. A negative value indicates decoding failed. Return status values are defined in the "rtxErrCodes.h" include file. The reason text and a stack trace can be displayed using the rtxErrPrint function.

The calling sequence for a WSDL output operation decode function is as follows:

     status = <decodeFunc> (OSCTXT* pctxt, <name>* pvalue,
                              <fault name>* pfault);

In this definition, <decodeFunc> denotes the decode function name defined above. The pctxtargument is used to hold a context pointer to keep track of decode parameters. This is a basic "handle" variable that is used to make the function reentrant so it can be used in an asynchronous or threaded application. The user is required to supply a pointer to a variable of this type declared somewhere in his or her program.

The pvalue argument is a pointer to a variable of the decode function type (operation output) to receive the decoded output data.

A negative return value indicates decoding failed. Return status values are defined in the rtxErrCodes.h include file. The error text and a stack trace can be displayed using the rtxErrPrint function.

The WSDL output operation decode function is used to decode a response from a Web Service server. If the response is an SOAP Fault message, the returned status value is RTERR_SOAPFAULT, and the decoded data is saved in pfault. The pfault argument is a pointer to a variable of the operation fault type to receive the decoded SOAP Fault data.

If the response is a normal SOAP message without Fault, the returned status value is zero and the decoded data is saved in pvalue .

SAX Parser Interface

Third-party SAX parsers are configured to work with XBinder through interface source files. Pre-built interface source files for Expat, LibXML2, and a micro-SAX parser that was developed in-house are available in the XBinder distribution package. The source files for these respective parsers are as follows:

   rtXmlExpatIF.c
   rtXmlLibxml2IF.c
   rtXmlMicroIF.c

These files implement the following functions which are required to interface a third-party SAX parser with XBinder:

rtSaxCStartElementHandler - this is the start element adapter function. It receives a SAX start element callback using the parser's native arguments and converts the arguments into the XBinder common format and then invokes the XBinder startElement callback.

rtSaxCEndElementHandler - this is the endelement adapter function. It receives a SAX end element callback using the parser's native arguments and converts the arguments into the XBinder common format and then invokes the XBinder endElement callback.

rtSaxCCharacterDataHandler - this is the characters adapter function. It receives a SAX characters callback using the parser's native arguments and converts the arguments into the XBinder common format and then invokes the XBinder characters callback.

rtSaxCParse - this is a wrapper function for the third-party SAX handler's parse function. This can be as simple as directly calling the function itself. In the XBinder built-in case, the functions are more complicated because they support reading a stream of multiple documents.

In the case of the micro parser, the full implementation is contained within the rtXmlMicroIF.c file. This parser is designed for applications that require a small footprint to operate. It is a bare-boned XML parser that does not support many of the well-formedness and validity checks of the other parsers. If documents to be parsed are known to be good, this can be a viable alternative to make an application smaller.

The parameters required to compile against and link with a given parser implementation can be found in the xmlparser.mk file in the C subdirectory of the installation. Files for various operating system, parser type combinations are identified by special extensions on the files (for example, xmlparser.gnu_expat is the interface file for Expat on GNU systems such as Linux). All that generally needs to be done to interface with a specific parser is to rename the file to xmlparser.mk .

DOM Interface

Decoders can be generated that can decode from a W3C Document Object Model (DOM) structure into XBinder generated structures. This is accomplished by adding the -dom switch to the command-line instead of -sax and -xml . The generated global element decode functions in this case would be of the following format:

        [ns]XmlDec_<elemName>_fromDOM (OSCTXT* pctxt,
           OSRTDOMDocPtr doc, <typeName>* pvalue);

The pctxt argument is the standard context argument as defined in other function definitions. The doc argument is the pointer to the main document root node of a DOM structure. This is abstract and is defined in domAPI.h to be a void pointer. It is assumed that the user has a DOM implementation defined that contains a concrete representation of this type. The pvalue argument is a pointer to a structure of the generated element type to receive the decoded data.