[xsd-users] schema => simple print program, need walkthrough

Rutger Vos rutgeraldo at gmail.com
Fri Dec 21 02:53:42 EST 2007


Dear list members,

I sense this is going to be a long email, so here's the executive
summary: I have a large-ish modular schema and I'd like to use the
codesynthesis xsd tool (from now csxsd) to create a simple
proof-of-concept program that, given a valid instance document, will
print out its contents - or in any case some sort of sign of life to
indicate the mappings are working. I'm looking for some help to get
this done.

Okay, here's the long version: my endeavor is hampered by two
problems: i) I'm new to csxsd; ii) I don't know C++. I realize that
the latter is a rather big problem and I don't expect you to help me
with that, but I gather from what I've read so far that csxsd can
generate just the sort of simple read => print example program I'm
after without me having to write (a lot of) code. Also, I do have
experience with C (not so much, that, though) and Java, so the syntax
isn't entirely alien and I understand the general principles of OO and
type-mapping.

The schema I'm working with is this one:
http://www.nexml.org/nexml/xsd/ . The general requirements of the
schema are community-driven, but I'm the main designer, and I'm quite
willing to make (small, syntactical) changes if that helps csxsd. The
"root" file of the schema is nexml.xsd, which does a number of
includes (and some of the files it pulls in do so as well,
recursively), which all have the same targetNamespace. In fact, here
is a clickable image map that shows the inclusions:
http://www.nexml.org/nexml/html/doc/schema-1/nexml/inclusions/

In addition, it does a number of imports, specifically so that
instance documents can have some of the standard xml attributes
(xml:id, xml:lang, xml:base, xml:space) and xlink attributes
(xlink:href).

Lastly about the general schema design: it's "venetian blinds", one
root element, otherwise all named complexTypes and simpleTypes and it
uses polymorphism in instance documents  (i.e.
xsi:type="nex:SomeSubclass" attributes on a number of elements). Here
are some example files: http://nexml-dev.nescent.org/nexml/examples/
(e.g. look at characters.xml)

Because I've been using the oxygen plugin for eclipse (which complains
every time there's something wrong in the schema, using Xerces-J) and
are able to generate xmlbeans using apache's tools for java I conclude
that the schema is more or less sane and that what I'm trying to do is
possible. Now, I've been trying to turn the schema into C++ source
files and headers, create a driver, then compile everything. The idea
is that I may be able to show my C++-coding colleagues that csxsd
might be worth their while. Anyway, I ran into a number of snags, so
here's what I've learned so far:

* csxsd doesn't download remote schema files, so I've downloaded the
schemas I import (the xml and xlink namespaces) and reference them
locally, they're in the external/ folder.

* csxsd doesn't follow inclusions itself, you need to tell it
explicitly from which schema files to generate code

* csxsd - or actually gcc when I try to compile - doesn't like cycles
in schema inclusions (and hence generated code?), so I've broken them
to create an acyclic inclusion tree

* csxsd doesn't like the http://www.nexml.org/1.0 namespace, so I need
to declare a namespace mapping

* because of the xsi:type polymorphism I need to generate polymorphic bindings

With those things taken into account, I generate code as follows:

* I make a list of all schema files I will be working with, i.e. in
shell I do files=$(find . -name "*.xsd") out of which I "grep -v" the
files that aren't reached by the inclusions starting from nexml.xsd
(e.g. the "draft1" folder)

* because the schema files are organized in a folder structure (see
inclusions graph) I assume I will be happiest if the generated code
ends up in a similar folder structure, so I loop over each $file in
$files and modify the string to get $outdir, such that for file
./characters/dna.xsd $outdir is characters/

* I then run csxsd for each schema file with the following incantation:

./xsd cxx-tree --namespace-map http://www.nexml.org/1.0=Nexml \
--generate-polymorphic --output-dir ./out/$outdir $file

* this works without problems, I get ./out/$outdir/$file.hxx headers
and ./out/$outdir/$file.cxx sources

* however, to make my print program, I understand I should also
generate parser code (right?), so I also run:

./xsd cxx-parser --namespace-map http://www.nexml.org/1.0=Nexml \
--generate-print-impl --output-dir ./out/$outdir $file

* again, this works without problems, I get the $file-pskel header and
source files and $file-pimpl header and source files

==> Here is where I think things are starting to get sketchy <==

* because there is a single root element, which is defined in
nexml.xsd, I need to generate a test driver from that schema file, so
I do:

./xsd cxx-parser  --namespace-map http://www.nexml.org/1.0=Nexml
--root-element nexml \
--output-dir ./out --generate-print-impl --force-overwrite
--generate-test-driver ../../nexml/xsd/nexml.xsd

* this yields an additional nexml-driver.cxx

* I then need to compile this driver file so I do:

g++ -W -Wall -I../../libxsd
-I../../../xerces-c_2_8_0-x86-macosx-gcc_4_0/include -c
nexml-driver.cxx

* but I am rewarded with:

characters/continuous-pskel.hxx:292: error: expected class-name before '{' token

...times a million, and things go downhill from there. To be quite
honest, I'm probably making the wrong gcc incantation, in which case I
apologize for asking off topic questions (help still greatly
appreciated, of course), but if I'm making any wrong assumptions
further upstream, please let me know. I'm very eager to get this to
work, but haven't gotten much further by googling, checking the list
archives, or the csxsd wiki.

Thank you, best wishes,

Rutger

-- 
Dr. Rutger A. Vos
Department of zoology
University of British Columbia
http://www.nexml.org
http://rutgervos.blogspot.com




More information about the xsd-users mailing list