[xsd-users] Public XML schema that works in XJC (Java) but maybe not in CodeSynthesis XSD

Boris Kolpackov boris at codesynthesis.com
Sun Mar 29 14:56:58 EDT 2009


Cris,

I did some digging and it appears the error is caused by two schemas
(ansi-nist.xsd and ansi-nist_itl_constraint.xsd) that define the same
set of types both being imported from different sub-schemas when loading
the top-level ITL-2007f-Package.xsd schema.

According to the XML Schema spec, a schema processor can treat subsequent
imports with the same namespace in two ways: (1) it can ignore the
subsequent imports assuming the first schema provides all the definitions
for the vocabulary or (2) it can process the subsequent imported files.
In the second case there are two further options regarding redefinitions:
the schema processor can ignore redefinitions or it can issue an error.

By default Xerces-C++ (and XSD, which is built on top of Xerces-C++) uses
the first approach. The internal schema repository organization in
Xerces-C++ also assumes that all subsequent imported schemas for the
namespace are imported by the first schema (natural assumption since
otherwise whatever is provided by schemas in the subsequent imports will
be ignored). In case of ITL, we have two "parallel" schema files imported
at different points in the include/import graph which breaks this
assumption and as a result we get the unresolved type error.

Starting with version 3.0.0, Xerces-C++ also supports the second approach,
the variant with an error on redefinition. Turning on this mode doesn't
help ITL since the second version of ansi-nist redefines all the types
in the first.

The easiest way to resolve this issue is to modify the niem-code.xsd and 
jxdm.xsd schemas to import ansi-nist_itl_constraint.xsd instead of 
ansi-nist.xsd. With this change the ITL schema can be compiled in the
file-per-type mode without any problems. It is also possible to achieve
the same effect without modifying the schemas. During compilation you
can use the --location-map XSD compiler option to re-map ansi-nist.xsd
to ansi-nist_itl_constraint.xsd. If you enable XML Schema validation
during parsing, then you will also need to setup your own XML-to-DOM
parsing and install a custom entity resolver which returns 
ansi-nist_itl_constraint.xsd instead of ansi-nist.xsd when requested by
the parser.

To test the generated code I created a simple round-trip driver which
parses XML to object model and serializes the object model back to XML.
One difference that I noticed was that a few element names were different
compared to the original. It appears that the ITL schema is its use of
substitution groups as some sort of application-significant IDs rather
than just a way to specify the element types. For example, elements
PackageUserDefinedImageRecord, PackageLantentImageRecord, etc., all
substitute PackageDataRecord but are all of the same
PackageImageRecordType type. During serialization the generated code
uses object model types to automatically figure out which element name
to use based on the substitution group information from the schemas. As
a result, the generated code always uses the first element name from the
above group since the object types are the same. 

One way to overcome this in the C++/Tree mapping is to customize the 
xml_schema::type class (which is the base type for all the generated
classes) by adding a custom type id member (which is just the
substituting element name). This type id is automatically extracted
during parsing, can be queried/modified by the application, and is used
during serialization to make sure the right element name is used. With
this change the serialized XML is equivalent to the original.

I've created a page on our Wiki for the NIST-ITL schema which contains
some of the information I provided above:

http://wiki.codesynthesis.com/Schemas/NIST-ITL

I've also uploaded a package which contains the fixed-up NIST-ITL schemas,
custom xml_schema::type implementation, the test driver, XSD option files,
as well as the README which explains how to compile everything. The link
is provided on the above Wiki page.

Boris




More information about the xsd-users mailing list