From f0510d2f90467de8e8f260b47d79a9baaf9bef17 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 17 Sep 2009 07:15:29 +0200 Subject: Start tracking XSD with git --- examples/cxx/tree/custom/taxonomy/README | 50 ++++++ examples/cxx/tree/custom/taxonomy/driver.cxx | 39 +++++ examples/cxx/tree/custom/taxonomy/makefile | 82 ++++++++++ .../cxx/tree/custom/taxonomy/people-custom-fwd.hxx | 20 +++ .../cxx/tree/custom/taxonomy/people-custom.cxx | 180 +++++++++++++++++++++ .../cxx/tree/custom/taxonomy/people-custom.hxx | 103 ++++++++++++ examples/cxx/tree/custom/taxonomy/people.xml | 27 ++++ examples/cxx/tree/custom/taxonomy/people.xsd | 45 ++++++ 8 files changed, 546 insertions(+) create mode 100644 examples/cxx/tree/custom/taxonomy/README create mode 100644 examples/cxx/tree/custom/taxonomy/driver.cxx create mode 100644 examples/cxx/tree/custom/taxonomy/makefile create mode 100644 examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx create mode 100644 examples/cxx/tree/custom/taxonomy/people-custom.cxx create mode 100644 examples/cxx/tree/custom/taxonomy/people-custom.hxx create mode 100644 examples/cxx/tree/custom/taxonomy/people.xml create mode 100644 examples/cxx/tree/custom/taxonomy/people.xsd (limited to 'examples/cxx/tree/custom/taxonomy') diff --git a/examples/cxx/tree/custom/taxonomy/README b/examples/cxx/tree/custom/taxonomy/README new file mode 100644 index 0000000..addce83 --- /dev/null +++ b/examples/cxx/tree/custom/taxonomy/README @@ -0,0 +1,50 @@ +This example shows how to map user-defined XML Schema types to custom C++ +classes. It presents the complex case where the customized types are +inherited from in the same schema. For the simple case see the contacts +example. For more information on the C++/Tree mapping customization see +the C++/Tree Mapping Customization Guide[1]. + +[1] http://wiki.codesynthesis.com/Tree/Customization_guide + +The example consists of the following files: + +people.xsd + XML Schema definition for a simple people database. + +people.xml + Sample XML instance document. + +people-fwd.hxx +people.hxx +people.ixx +people.cxx + C++ types that represent the given vocabulary and a set of parsing + functions that convert XML instance documents to a tree-like in-memory + object model. These are generated by XSD from people.xsd with the + --custom-type option in order to to customize the person, superman, + and batman types. Generation of the people-fwd.hxx forward declaration + file is requested with the --generate-forward option. + +people-custom-fwd.hxx + Header file which forward-declares our own person, superman, and batman + as class templates. It is included at the beginning of people-fwd.hxx + using the --fwd-prologue option. + +people-custom.hxx + Header file which defines our own person, superman, and batman class + templates by inheriting from the generated person_base, superman_base, + and batman_base. It is included at the beginning of people.hxx using + the --hxx-prologue option. + +people-custom.cxx + Source file which contains the implementations and instantiations of + our person, superman, and batman class templates. + +driver.cxx + Driver for the example. It first calls one of the parsing functions + that constructs the object model from the input file. It then prints + the database to STDERR. + +To run the example on the sample XML instance document simply execute: + +$ ./driver people.xml diff --git a/examples/cxx/tree/custom/taxonomy/driver.cxx b/examples/cxx/tree/custom/taxonomy/driver.cxx new file mode 100644 index 0000000..f102fc3 --- /dev/null +++ b/examples/cxx/tree/custom/taxonomy/driver.cxx @@ -0,0 +1,39 @@ +// file : examples/cxx/tree/custom/taxonomy/driver.cxx +// author : Boris Kolpackov +// copyright : not copyrighted - public domain + +#include // std::auto_ptr +#include + +#include "people.hxx" + +using std::cerr; +using std::endl; + +int +main (int argc, char* argv[]) +{ + if (argc != 2) + { + cerr << "usage: " << argv[0] << " people.xml" << endl; + return 1; + } + + try + { + using namespace people; + + std::auto_ptr c (catalog_ (argv[1])); + + for (catalog::person_const_iterator i (c->person ().begin ()); + i != c->person ().end (); ++i) + { + i->print (cerr); + } + } + catch (const xml_schema::exception& e) + { + cerr << e << endl; + return 1; + } +} diff --git a/examples/cxx/tree/custom/taxonomy/makefile b/examples/cxx/tree/custom/taxonomy/makefile new file mode 100644 index 0000000..a5fa4a3 --- /dev/null +++ b/examples/cxx/tree/custom/taxonomy/makefile @@ -0,0 +1,82 @@ +# file : examples/cxx/tree/custom/taxonomy/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make + +xsd := people.xsd +cxx := driver.cxx people-custom.cxx + +obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o)) +dep := $(obj:.o=.o.d) + +driver := $(out_base)/driver +clean := $(out_base)/.clean + + +# Import. +# +$(call import,\ + $(scf_root)/import/libxerces-c/stub.make,\ + l: xerces_c.l,cpp-options: xerces_c.l.cpp-options) + + +# Build. +# +$(driver): $(obj) $(xerces_c.l) + +$(obj) $(dep): cpp_options := -I$(src_root)/libxsd +$(obj) $(dep): $(xerces_c.l.cpp-options) + +$(out_base)/$(xsd:.xsd=.hxx) \ +$(out_base)/$(xsd:.xsd=.ixx) \ +$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd + +# We have to double-escape '#' because the message function +# (which is used in command scripts) expands things twice. +# +$(out_base)/$(xsd:.xsd=.hxx) \ +$(out_base)/$(xsd:.xsd=.ixx) \ +$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \ +--generate-inline \ +--generate-forward \ +--generate-polymorphic \ +--custom-type "person=person_impl/person_base" \ +--custom-type "superman=superman_impl/superman_base" \ +--custom-type "batman=batman_impl/batman_base" \ +--fwd-prologue '\\\#include "people-custom-fwd.hxx"' \ +--hxx-prologue '\\\#include "people-custom.hxx"' + +$(out_base)/$(xsd:.xsd=.hxx) \ +$(out_base)/$(xsd:.xsd=.ixx) \ +$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd + +$(call include-dep,$(dep)) + +# Convenience alias for default target. +# +.PHONY: $(out_base)/ +$(out_base)/: $(driver) + + +# Clean. +# +.PHONY: $(clean) + +$(clean): $(driver).o.clean \ + $(addsuffix .cxx.clean,$(obj)) \ + $(addsuffix .cxx.clean,$(dep)) \ + $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean)) + + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) +$(call include,$(scf_root)/xsd/tree/xsd-cxx.make) + +# Dependencies. +# +$(call import,$(src_root)/xsd/makefile) diff --git a/examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx b/examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx new file mode 100644 index 0000000..973b6e5 --- /dev/null +++ b/examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx @@ -0,0 +1,20 @@ +// file : examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx +// author : Boris Kolpackov +// copyright : not copyrighted - public domain + +// Do not include this file directly, use people-fwd.hxx instead. This +// file is included into generated people-fwd.hxx so we do not need to +// guard against multiple inclusions. +// + +namespace people +{ + template + class person_impl; + + template + class superman_impl; + + template + class batman_impl; +} diff --git a/examples/cxx/tree/custom/taxonomy/people-custom.cxx b/examples/cxx/tree/custom/taxonomy/people-custom.cxx new file mode 100644 index 0000000..14c7087 --- /dev/null +++ b/examples/cxx/tree/custom/taxonomy/people-custom.cxx @@ -0,0 +1,180 @@ +// file : examples/cxx/tree/custom/taxonomy/people-custom.cxx +// author : Boris Kolpackov +// copyright : not copyrighted - public domain + +#include + +// Include people.hxx instead of people-custom.hxx here. +// +#include "people.hxx" + +namespace people +{ + // person_impl + // + template + person_impl:: + person_impl (const xml_schema::string& name) + : base (name) + { + } + + template + person_impl:: + person_impl (std::auto_ptr& name) + : base (name) + { + } + + template + person_impl:: + person_impl (const xercesc::DOMElement& e, + xml_schema::flags f, + xml_schema::container* c) + : base (e, f, c) + { + } + + template + person_impl:: + person_impl (const person_impl& p, + xml_schema::flags f, + xml_schema::container* c) + : base (p, f, c) + { + } + + template + person_impl* person_impl:: + _clone (xml_schema::flags f, xml_schema::container* c) const + { + return new person_impl (*this, f, c); + } + + template + void person_impl:: + print (std::ostream& os) const + { + os << this->name () << std::endl; + } + + // Explicitly instantiate person_impl class template for person_base. + // + template class person_impl; + + + // superman_impl + // + template + superman_impl:: + superman_impl (const xml_schema::string& name, bool can_fly) + : base (name, can_fly) + { + } + + template + superman_impl:: + superman_impl (std::auto_ptr& name, bool can_fly) + : base (name, can_fly) + { + } + + template + superman_impl:: + superman_impl (const xercesc::DOMElement& e, + xml_schema::flags f, + xml_schema::container* c) + : base (e, f, c) + { + } + + template + superman_impl:: + superman_impl (const superman_impl& s, + xml_schema::flags f, + xml_schema::container* c) + : base (s, f, c) + { + } + + template + superman_impl* superman_impl:: + _clone (xml_schema::flags f, xml_schema::container* c) const + { + return new superman_impl (*this, f, c); + } + + template + void superman_impl:: + print (std::ostream& os) const + { + if (this->can_fly ()) + os << "Flying superman "; + else + os << "Superman "; + + os << this->name () << std::endl; + } + + // Explicitly instantiate superman_impl class template for superman_base. + // + template class superman_impl; + + + // batman_impl + // + template + batman_impl:: + batman_impl (const xml_schema::string& name, + bool can_fly, + unsigned int wing_span) + : base (name, can_fly, wing_span) + { + } + + template + batman_impl:: + batman_impl (std::auto_ptr& name, + bool can_fly, + unsigned int wing_span) + : base (name, can_fly, wing_span) + { + } + + template + batman_impl:: + batman_impl (const xercesc::DOMElement& e, + xml_schema::flags f, + xml_schema::container* c) + : base (e, f, c) + { + } + + template + batman_impl:: + batman_impl (const batman_impl& s, + xml_schema::flags f, + xml_schema::container* c) + : base (s, f, c) + { + } + + template + batman_impl* batman_impl:: + _clone (xml_schema::flags f, xml_schema::container* c) const + { + return new batman_impl (*this, f, c); + } + + template + void batman_impl:: + print (std::ostream& os) const + { + os << "Batman " << this->name () << " with " << + this->wing_span () << "m wing span" << std::endl; + } + + // Explicitly instantiate batman_impl class template for batman_base. + // + template class batman_impl; +} diff --git a/examples/cxx/tree/custom/taxonomy/people-custom.hxx b/examples/cxx/tree/custom/taxonomy/people-custom.hxx new file mode 100644 index 0000000..23e7731 --- /dev/null +++ b/examples/cxx/tree/custom/taxonomy/people-custom.hxx @@ -0,0 +1,103 @@ +// file : examples/cxx/tree/custom/taxonomy/people-custom.hxx +// author : Boris Kolpackov +// copyright : not copyrighted - public domain + +// Do not include this file directly, use people.hxx instead. This +// file is included into generated people.hxx so we do not need to +// guard against multiple inclusions. +// + +#include // std::ostream + +// Include people-fwd.hxx here so that we can refer to the generated +// types. +// +#include "people-fwd.hxx" + +namespace people +{ + // + // + template + class person_impl: public base + { + public: + person_impl (const xml_schema::string& name); + person_impl (std::auto_ptr& name); + + person_impl (const xercesc::DOMElement&, + xml_schema::flags = 0, + xml_schema::container* = 0); + + person_impl (const person_impl&, + xml_schema::flags = 0, + xml_schema::container* = 0); + + virtual person_impl* + _clone (xml_schema::flags = 0, + xml_schema::container* = 0) const; + + public: + virtual void + print (std::ostream&) const; + }; + + + // + // + template + class superman_impl: public base + { + public: + superman_impl (const xml_schema::string& name, bool can_fly); + superman_impl (std::auto_ptr& name, bool can_fly); + + superman_impl (const xercesc::DOMElement&, + xml_schema::flags = 0, + xml_schema::container* = 0); + + superman_impl (const superman_impl&, + xml_schema::flags = 0, + xml_schema::container* = 0); + + virtual superman_impl* + _clone (xml_schema::flags = 0, + xml_schema::container* = 0) const; + + public: + virtual void + print (std::ostream&) const; + }; + + + // + // + template + class batman_impl: public base + { + public: + batman_impl (const xml_schema::string& name, + bool can_fly, + unsigned int wing_span); + + batman_impl (std::auto_ptr& name, + bool can_fly, + unsigned int wing_span); + + batman_impl (const xercesc::DOMElement&, + xml_schema::flags = 0, + xml_schema::container* = 0); + + batman_impl (const batman_impl&, + xml_schema::flags = 0, + xml_schema::container* = 0); + + virtual batman_impl* + _clone (xml_schema::flags = 0, + xml_schema::container* = 0) const; + + public: + virtual void + print (std::ostream&) const; + }; +} diff --git a/examples/cxx/tree/custom/taxonomy/people.xml b/examples/cxx/tree/custom/taxonomy/people.xml new file mode 100644 index 0000000..5f84855 --- /dev/null +++ b/examples/cxx/tree/custom/taxonomy/people.xml @@ -0,0 +1,27 @@ + + + + + + + + Joe Dirt + + + + James "007" Bond + + + + Bruce Wayne + + + diff --git a/examples/cxx/tree/custom/taxonomy/people.xsd b/examples/cxx/tree/custom/taxonomy/people.xsd new file mode 100644 index 0000000..c77a866 --- /dev/null +++ b/examples/cxx/tree/custom/taxonomy/people.xsd @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.1