Support for the xml namespace in Codesynthesis xsd cxx-tree

This page shows a number of ways to access the xml:base attribute using Codesynthesis xsd cxx-tree. (See also similar work on cxx-parser.) It is the result of a discussion in the xsd-users mailing list starting here. At the moment, this page and the files it references are work in progress. It should be easy to add the other attributes in the xml namespace to the code presented here. See for instance program custom-datamodel in item 7 on the bottom right of this page.

The easier way is when the XML Schema allows or requires the xml:base attribute explicitely. This is demonstrated in the following source files for the program named explicit.

Note that I use the extensions .cpp and .hpp for manually crafted code. Extensions .cxx and .hxx are reserved for files generated by xsd. This allows me to use rm *.?xx as part of a complete rebuild. You have been warned.

At one point in that discussion, Boris Kolpackov suggested three ways to access xml:base when it is covered by an '<xs:anyAttribute namespace="##other"/>' in the XML Schema. On the right you'll find my interpretation of these suggestions.

The story continues at the bottom with some more interpretations.

There also is a tarball file containing all source files referenced here. It expands in the current working directory with a directory for each implementation.

Where necessary, the notes on each implementation also describe to which version(s) of xsd the implementation applies. In general:

  • Most examples given here have been tested with xsd versions 3.0.0, 3.1.0 and 3.2.0.
  • A few require at least version 3.1.0.a1.
  • Some, including explicit described above, also work for xsd version 2.3.0.
  • All examples that work for xsd version 2.3.0 should also work for version 2.3.1, but I have not tested this.

In the source code, the differences between the xsd versions are handled with preprocessor conditionals.

mailto:jnw@xs4all.nl
  1. DOM_association: Use DOM association directly.

    • lax.xsd: An XML Schema where the xml:base attribute is covered by '<xs:anyAttribute namespace="##other"/>'.

    • DOM_association.cpp: The application logic.

    • using-lax.xml: Sample input.

    • Makefile: The GNU Makefile to build and run the program.

    DOM_association works for both version 2.3.0 and versions 3.0.0, 3.1.0 and 3.2.0 of xsd.

  2. custom-types: Move the DOM association code to the constructors of custom types.

    This implementation uses the same lax.xsd file and using-lax.xml file as the one above.

    custom-types works for both version 2.3.0 and versions 3.0.0, 3.1.0 and 3.2.0 of xsd.

  3. custom-xmlbase: Replace the DOM association code by a base class for our types. This base class contains an adaptation of the code generated by xsd when the xml:base attribute is mentioned explicitely in the XML Schema, as is the case in the XML Schema file on the left. As a result, the xml:base attribute is not represented by a std::wstring, but by an ::xml_schema::uri.

    As custom-xmlbase depends on implementation details of xsd, it may well break unexpectedly and seriously when upgrading to a new version of xsd.

    This implementation uses the same lax.xsd file and using-lax.xml file as program DOM_association above.

    custom-xmlbase works for both version 2.3.0 and versions 3.0.0, 3.1.0 and 3.2.0 of xsd.

The Makefiles of the three implementations above also run the program against the sample.xml file on the left, verifying that they also work when xml:base is specified explicitely.


  1. custom-intended: Access xml:base using DOM association in a customization of xml_schema::anyType.

    • XmlNamespace.hpp and XmlNamespace.cpp: The implementation of the custom types.

    • XmlNamespace-fwd.hpp: Forward declaration. We need to manually create this file, because xsd does not automagically create a forward for our type, as is does for the calender / date example.

    • driver.cpp: The application logic.

    • Makefile: The GNU Makefile to build and run the program.

    custom-intended works for versions 3.1.0.a1 and later, and 3.2.0 of xsd.

  1. attset-driver: Use the attribute_set introduced in xsd 3.0.0 in the driver logic to access the xml:base attribute when its presence is covered by <xsd:anyAttribute/>.

    This implementation uses the same lax.xsd file and using-lax.xml file as program DOM_association above.

    The Makefile of this implementation also runs the program against the sample.xml file of program explicit, verifying that they also work when xml:base is specified explicitely.

    attset-driver works for versions 3.0.0, 3.1.0 and 3.2.0 of xsd.


  1. custom-anyType: Access xml:base using a custom type generated by xsd. The idea for this implementation came from the observation that program explicit above also works for the lax.xsd and using-lax.xml files, where the use of xml:base is covered by an '<xs:anyAttribute namespace="##other"/>' in the XML Schema.

    This implementation uses the same lax.xsd file and using-lax.xml file as program DOM_association above.

    The Makefile of this implementation also runs the program against the sample.xml file of program explicit, verifying that they also work when xml:base is specified explicitely.

    custom-anyType works for version 3.1.0.a1 and later, and 3.2.0 of xsd.

    The trick of having xsd generate the custom type does not work in more complex cases, because a number of required constructors are missing from the generated code. You have been warned. For details see this email from Boris Kolpackov.

  1. custom-datamodel: Using a customization of anyType, maintain a data model for the attributes in the xml namespace, handling inheritance and uniqueness where appropriate. This data model is based on similar work on cxx-parser. It uses xercesc to manipulate URIs.

    The remainder of this implementation is based on custom-intended in item 4 above. As there, we can handle the attributes in the xml namespace both when the schema contains <anyAttribute namespace="##other"/> and when it declares them explicitely.

    This implementation uses the same lax.xsd file and using-lax.xml file as program parser-anytype (See similar work on cxx-parser.)

    custom-datamodel only works for version 3.1.0.a1 and later, and 3.2.0 of xsd. In xsd versions before 3.1.0.b3, handling duplicate values for xml:id fails with pure virtual method called in xsd::cxx::xml::dom::auto_ptr<xercesc_2_7::DOMDocument>::reset(0).

up arrow mailto:jnw@xs4all.nl