Tool Usage

About xsd2cpp

XmlPlus build has a binary called xsd2cpp. This binary when invoked on a XML-Schema file, generates: The generated C++ sources serve for:

The main.cpp aims to demonstrate the multiple options available(parsing/writing/validating xml-files etc.) around the schema and xml files.

Further, in this document, in relation to xsd2cpp, the <name> token would signify the name(excluding extension like .xsd) of the supplied XML-Schema.
For instance, given a XML-Schema file simpleTypesDemo.xsd, the <name> would mean "simpleTypesDemo" token.



Running the xsd2cpp tool

As long as XmlPlus installation path is set in the environment, one should be able to run xsd2cpp from anywhere in the directory tree.
(see Updating the environment with the installation path)

Try accessing the xsd2cpp tool:
  $ xsd2cpp 
  Usage:

  1.  xsd2cpp xsd-file [outdir]
        outdir: directory to output the generated source to
        (if unspecified, defaults to xsd-file-name)

        -s :  do not terminate on error

  2.  xsd2cpp -v
        prints verion

  3.  xsd2cpp -h
        prints help


The xsd2cpp when run on a XML-Schema file, generates the C++ source/header files along with the make related files.
An example follows:
  $ xsd2cpp simpleTypesDemo.xsd .
  output path: .
  =>  Generating source files...
  =>  Generating automake/autoconf files ...
  =>  Generating README.build.txt file ...


Note that:

Building the generated source

Steps to build the generated source:
$ ./autogen.sh : generate configure script, run configure
$ make : build the source
$ make install : install the build
$ make doxygen-doc : generates the doxygen html documentation in doc/ directory relative to current working directory

( Note: The autogen.sh should be run only once, which generates the configure script and runs it too.
Once you have the configure script generated, next time onwards you should run configure instead of autogen.sh.)

It is likely that, while experimenting the tool with XML-Schema, you edit the files like XML-Schema iteratively, and would want to see the build in action for each such edit.
After every edit, you should run following commands in that order:
$ xsd2cpp XML-Schema outdir
$ cd outdir
$ run configure ( with your choice of options)
$ make
$ make install


The build is installed in the path depending on --prefix option specified to autogen.sh or configure.
Note that in the absence of an explicit specification of --prefix option, the autogen.sh(generated by xsd2cpp) defaults the install path to a directory build/ relative to the directory of input XML-Schema file.
For XML-Schema file <name>.xsd, the build contains:

Using the build

Look of the build

The built library alongwith the generated headers for user supplied XML-Schema, can be consumed by user applications in their builds.
One example of how to consume the built library/headers, comes alongwith the generated sources viz. main.cpp. The main.cpp includes the generated headers and links to the built library, and makes a binary named <name>run. This <name>run binary demostrates all the use cases around the XML-Schema, that XmlPlus supports. So in that sense main.cpp serves as an example user application, showing how to consume the C++ library built for a XML-Schema file.

Once the generated source(using xsd2cpp on XML Schema) is built, we should check out the build in the installed path. Taking the examples/simpleTypesDemo as an example, it should look like this:
$ pwd
/Users/goofy/xmlplus/examples/simpleTypesDemo

$ find build -type d
build/
build/bin/
build/lib/
build/include/

$ find build -type f
build/bin/simpleTypesDemorun
build/lib/libsimpleTypesDemo.0.dylib
build/lib/libsimpleTypesDemo.a
build/lib/libsimpleTypesDemo.la


Each <name>run comes with a set of options. The options provided are aimed at covering most of the use cases in relation to XML-Schema and xml documents. You should use one <name>run built for the XML-Schema of your choice, to undertand all the use cases.
An example of <name>run options:
 $ ./build/bin/simpleTypesDemorun --help 
 Usage: ./build/bin/simpleTypesDemorun [options] [XMLfile] 
 Options:
  -s, --sample
    create a schema-driven sample xml-file
  -w, --write
    write a xml-file using populated Document
    Note: populateDocument() function in main.cpp template,
    must be used to populate the Document
  -v, --validate
    validate input xml-file(against compiled schema)
  -r, --roundtrip
    roundtrip (read->write) input xml-file
  -u, --row
    perform read->operate->write operations on input xml-file
  -h, --help
    print help
 


main.cpp edit needed prior to use of -s and -w run options: choose the document element

If the input XML Schema has just one choice of document-element then that element is automatically chosen as document element by Document class, and no edit in main.cpp is required. In this case, the generated main.cpp would not have a callback named chooseDocumentElement(...).
However, if the input XML Schema has more than one choice of document-element then the generated main.cpp would have a calback function viz. chooseDocumentElement(...), wherein you would need to uncomment the appropriate choice of document element(root of xml document).
Here is an example:
  void chooseDocumentElement(NoNS::Document* xsdDoc)
  {
    // uncomment one of folowing to choose root
    xsdDoc->set_root_mails();
    //xsdDoc->set_root_header();
    //xsdDoc->set_root_Date();
  }
  

Run Options explained

The <name>run options are mostly self-explanatory. Here follows some more details on these options:

  1. write sample xml file(-s option)
    This option results in writing of a schema driven sample xml file namely sample.xml.
    Following points are noteworthy in this regard:
    • If XML Schema has more than one choice of document element, then choose the document element in the generated main.cpp file.
    • This sample.xml file is just one of many possible instance documents for the XML Schema in question, and not necessarily the only possible layout.
    • This sample.xml is not necessarily a valid instance document. Though, the order of elements and attributes in the sample.xml file is a valid order, the values of elements and attributes are not necessarily valid with respect to the XML Schema in question.


  2. write a xml file using populated Document(-w option)
    This option shows the use case of writing xml file, by serializing the populated XML-Objects. The serialization is done through Document class.
    Following points are noteworthy in this regard:
    • If XML Schema has more than one choice of document element, then choose the document element in the generated main.cpp file.
    • The callback function populateDocument(...) should be filled with appropriate code to populate the XML Objects under Document.


  3. validate input xml file(-v option)

    This option is used to validate the input xml-file(against compiled schema).
    For instance, for a XML-Schema named simpleTypesDemo.xsd, we would have a simpleTypesDemorun test utility built.
    Now, let us assume that you have one st.xml file which is a well-formed xml document, but is invalid against the XML-Schema.
      $ ./build/bin/simpleTypesDemorun -v st.xml
      validating file:st.xml
        => validation failed
    
      Error: {
        Expected:
          => Element '{http://www.example.com/STDemo} anIntMax5k'
        Got:
          => Element '{http://www.example.com/STDemo} anIntMax10'
      
        element: myComplexTypeElem
        file: st.xml
        line,column: 43, 2
      }


    On fixing the error in st.xml, when the validation is done again, it should look like this:
      $ ./build/bin/simpleTypesDemorun -v st.xml
      validating file:st.xml
         => validated successfully



  4. roundtrip a xml file(-r option)
    This option shows the use case of roundtripping(read->write) an input xml file, ie. deserializing an input xml file into XML-Objects and then serializing them back to a xml file. This option can be used to test if the roundtrip causes any loss of xml entities or data. XmlPlus claims to retain comments and processing-instructions in addition to elements and attributes.

  5. roundtrip with a callback(-u option)

    This option shows the use case where:
    • a xml file is read(deserialized) into Document(along with the XML Objects under the Document)
    • then the Document is updated using callback function named updateOrConsumeDocument(...). The callback function updateOrConsumeDocument(...) should be filled with appropriate code to update the Document. Alternatively, this callback function can be used to test the correctness of XML Objects' values.
    • then the Document is written(serialized) back to output xml file

    Note that, if the updateOrConsumeDocument(...) is left empty, the -u option is as good as -r option.