summaryrefslogtreecommitdiff
path: root/xsd/examples/cxx/tree/custom
diff options
context:
space:
mode:
Diffstat (limited to 'xsd/examples/cxx/tree/custom')
-rw-r--r--xsd/examples/cxx/tree/custom/README40
-rw-r--r--xsd/examples/cxx/tree/custom/calendar/README47
-rw-r--r--xsd/examples/cxx/tree/custom/calendar/calendar.xml23
-rw-r--r--xsd/examples/cxx/tree/custom/calendar/calendar.xsd32
-rw-r--r--xsd/examples/cxx/tree/custom/calendar/driver.cxx40
-rw-r--r--xsd/examples/cxx/tree/custom/calendar/makefile129
-rw-r--r--xsd/examples/cxx/tree/custom/calendar/xml-schema-custom.cxx57
-rw-r--r--xsd/examples/cxx/tree/custom/calendar/xml-schema-custom.hxx34
-rw-r--r--xsd/examples/cxx/tree/custom/comments/README57
-rw-r--r--xsd/examples/cxx/tree/custom/comments/dom-parse.cxx125
-rw-r--r--xsd/examples/cxx/tree/custom/comments/dom-parse.hxx23
-rw-r--r--xsd/examples/cxx/tree/custom/comments/driver.cxx91
-rw-r--r--xsd/examples/cxx/tree/custom/comments/makefile125
-rw-r--r--xsd/examples/cxx/tree/custom/comments/people.xml21
-rw-r--r--xsd/examples/cxx/tree/custom/comments/people.xsd30
-rw-r--r--xsd/examples/cxx/tree/custom/comments/xml-schema-custom.cxx118
-rw-r--r--xsd/examples/cxx/tree/custom/comments/xml-schema-custom.hxx58
-rw-r--r--xsd/examples/cxx/tree/custom/contacts/README40
-rw-r--r--xsd/examples/cxx/tree/custom/contacts/contacts-custom.cxx51
-rw-r--r--xsd/examples/cxx/tree/custom/contacts/contacts-custom.hxx44
-rw-r--r--xsd/examples/cxx/tree/custom/contacts/contacts.xml21
-rw-r--r--xsd/examples/cxx/tree/custom/contacts/contacts.xsd32
-rw-r--r--xsd/examples/cxx/tree/custom/contacts/driver.cxx39
-rw-r--r--xsd/examples/cxx/tree/custom/contacts/makefile114
-rw-r--r--xsd/examples/cxx/tree/custom/double/README62
-rw-r--r--xsd/examples/cxx/tree/custom/double/double-custom.cxx97
-rw-r--r--xsd/examples/cxx/tree/custom/double/double-custom.hxx68
-rw-r--r--xsd/examples/cxx/tree/custom/double/driver.cxx32
-rw-r--r--xsd/examples/cxx/tree/custom/double/makefile114
-rw-r--r--xsd/examples/cxx/tree/custom/double/order.xsd26
-rw-r--r--xsd/examples/cxx/tree/custom/makefile50
-rw-r--r--xsd/examples/cxx/tree/custom/mixed/README50
-rw-r--r--xsd/examples/cxx/tree/custom/mixed/driver.cxx124
-rw-r--r--xsd/examples/cxx/tree/custom/mixed/makefile116
-rw-r--r--xsd/examples/cxx/tree/custom/mixed/people-custom.cxx90
-rw-r--r--xsd/examples/cxx/tree/custom/mixed/people-custom.hxx84
-rw-r--r--xsd/examples/cxx/tree/custom/mixed/people.xml39
-rw-r--r--xsd/examples/cxx/tree/custom/mixed/people.xsd46
-rw-r--r--xsd/examples/cxx/tree/custom/taxonomy/README53
-rw-r--r--xsd/examples/cxx/tree/custom/taxonomy/driver.cxx39
-rw-r--r--xsd/examples/cxx/tree/custom/taxonomy/makefile123
-rw-r--r--xsd/examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx20
-rw-r--r--xsd/examples/cxx/tree/custom/taxonomy/people-custom.cxx157
-rw-r--r--xsd/examples/cxx/tree/custom/taxonomy/people-custom.hxx97
-rw-r--r--xsd/examples/cxx/tree/custom/taxonomy/people.xml27
-rw-r--r--xsd/examples/cxx/tree/custom/taxonomy/people.xsd45
-rw-r--r--xsd/examples/cxx/tree/custom/wildcard/README45
-rw-r--r--xsd/examples/cxx/tree/custom/wildcard/driver.cxx48
-rw-r--r--xsd/examples/cxx/tree/custom/wildcard/makefile117
-rw-r--r--xsd/examples/cxx/tree/custom/wildcard/wildcard-custom.cxx85
-rw-r--r--xsd/examples/cxx/tree/custom/wildcard/wildcard-custom.hxx67
-rw-r--r--xsd/examples/cxx/tree/custom/wildcard/wildcard.xml15
-rw-r--r--xsd/examples/cxx/tree/custom/wildcard/wildcard.xsd26
53 files changed, 3353 insertions, 0 deletions
diff --git a/xsd/examples/cxx/tree/custom/README b/xsd/examples/cxx/tree/custom/README
new file mode 100644
index 0000000..b2a65b5
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/README
@@ -0,0 +1,40 @@
+This directory contains a number of examples that show how to customize the
+C++/Tree mapping. The following list gives an overview of each example:
+
+calendar
+ Shows how to customize XML Schema built-in types by mapping xsd:date
+ built-in type to the date class from the Boost date_time library.
+
+comments
+ This example shows how to customize the anyType XML Schema built-in
+ type to implement preservation of comments stored in XML documents.
+ Because anyType is a base type for every generated type, you can use
+ this technique to implement custom functionality that spans the
+ entire type system.
+
+contacts
+ Shows how to map a user-defined XML Schema type to a custom C++ class.
+ This example presents the simple case where the customized type is not
+ used as a base in the same schema.
+
+double
+ Shows how to customize parsing and serialization code for the xsd:double
+ XML Schema built-in type. It can be used as a guide on how to customize
+ built-in XML Schema types that are mapped to fundamental C++ types.
+
+mixed
+ Shows how to use type customization to parse and serialize mixed content.
+
+taxonomy
+ Shows how to map user-defined XML Schema types to custom C++ classes.
+ This example presents the complex case where the customized types are
+ inherited from in the same schema.
+
+wildcard
+ Shows how to use type customization to parse and serialize a specific
+ attribute that is matched by a wildcard (anyAttribute).
+
+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
diff --git a/xsd/examples/cxx/tree/custom/calendar/README b/xsd/examples/cxx/tree/custom/calendar/README
new file mode 100644
index 0000000..f7f6989
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/calendar/README
@@ -0,0 +1,47 @@
+This example shows how to customize the XML Schema built-in types by mapping
+xsd:date built-in type to the date class from the Boost date_time library.
+You will need the Boost date_time library[1] installed in order to build
+and run this example. For more information on the C++/Tree mapping
+customization see the C++/Tree Mapping Customization Guide[2].
+
+[1] http://www.boost.org
+[2] http://wiki.codesynthesis.com/Tree/Customization_guide
+
+The example consists of the following files:
+
+calendar.xsd
+ XML Schema definition for a simple calendar format.
+
+calendar.xml
+ Sample XML instance document.
+
+xml-schema.hxx
+ C++ types for XML Schema built-in types. This header file is generated
+ by XSD using the --generate-xml-schema option. The --custom-type option
+ is also used to customize the xsd:date type.
+
+calendar.hxx
+calendar.ixx
+calendar.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 calendar.xsd with the
+ --extern-xml-schema option in order to include xml-schema.hxx.
+
+xml-schema-custom.hxx
+ Header file which defines our own xml_schema::date class. It is
+ included at the end of xml-schema.hxx using the --hxx-epilogue
+ option.
+
+xml-schema-custom.cxx
+ Source file which contains the implementation of our xml_schema:date
+ class.
+
+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 calendar events to STDERR.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver calendar.xml
diff --git a/xsd/examples/cxx/tree/custom/calendar/calendar.xml b/xsd/examples/cxx/tree/custom/calendar/calendar.xml
new file mode 100644
index 0000000..ae9e570
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/calendar/calendar.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/calendar/calendar.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<cal:events xmlns:cal="http://www.codesynthesis.com/calendar"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/calendar calendar.xsd">
+
+ <event title="Bike ride" date="2006-09-04">
+ Don't forget to change the tire.
+ </event>
+
+ <event title="Mountain hike" date="2006-09-05">
+ Can be cancelled if it is too cold.
+ </event>
+
+</cal:events>
diff --git a/xsd/examples/cxx/tree/custom/calendar/calendar.xsd b/xsd/examples/cxx/tree/custom/calendar/calendar.xsd
new file mode 100644
index 0000000..fa612a7
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/calendar/calendar.xsd
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/calendar/calendar.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:cal="http://www.codesynthesis.com/calendar"
+ targetNamespace="http://www.codesynthesis.com/calendar">
+
+ <xsd:complexType name="event">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="title" type="xsd:string" use="required"/>
+ <xsd:attribute name="date" type="xsd:date" use="required"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="events">
+ <xsd:sequence>
+ <xsd:element name="event" type="cal:event" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="events" type="cal:events"/>
+
+</xsd:schema>
diff --git a/xsd/examples/cxx/tree/custom/calendar/driver.cxx b/xsd/examples/cxx/tree/custom/calendar/driver.cxx
new file mode 100644
index 0000000..02f1c27
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/calendar/driver.cxx
@@ -0,0 +1,40 @@
+// file : examples/cxx/tree/custom/calendar/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "calendar.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " calendar.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace calendar;
+
+ std::auto_ptr<events> e (events_ (argv[1]));
+
+ for (events::event_const_iterator i (e->event ().begin ());
+ i != e->event ().end (); ++i)
+ {
+ cerr << i->date () << " " << i->title () << endl
+ << *i << endl;
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd/examples/cxx/tree/custom/calendar/makefile b/xsd/examples/cxx/tree/custom/calendar/makefile
new file mode 100644
index 0000000..f4f4598
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/calendar/makefile
@@ -0,0 +1,129 @@
+# file : examples/cxx/tree/custom/calendar/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := calendar.xsd
+cxx := driver.cxx xml-schema-custom.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+install := $(out_base)/.install
+dist := $(out_base)/.dist
+dist-win := $(out_base)/.dist-win
+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)
+
+ifeq ($(filter $(MAKECMDGOALS),dist dist-win install),)
+$(call import,\
+ $(scf_root)/import/libboost/date-time/stub.make,\
+ l: boost_date_time.l,cpp-options: boost_date_time.l.cpp-options)
+endif
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l) $(boost_date_time.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options) $(boost_date_time.l.cpp-options)
+
+# Header file for XML Schema namespace.
+#
+$(out_base)/xml-schema.hxx: $(out_root)/xsd/xsd
+ $(call message,xsd $(src_base)/xml-schema.xsd,\
+$(out_root)/xsd/xsd cxx-tree --output-dir $(out_base) --generate-xml-schema \
+--custom-type date \
+--hxx-epilogue '\#include "xml-schema-custom.hxx"' xml-schema.xsd)
+
+#
+#
+genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx)
+gen := $(addprefix $(out_base)/,$(genf))
+
+$(gen): xsd := $(out_root)/xsd/xsd
+
+# We have to double-escape '#' because the message function
+# (which is used in command scripts) expands things twice.
+#
+$(gen): xsd_options := \
+--generate-inline \
+--extern-xml-schema xml-schema.xsd
+
+$(gen): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+$(out_base)/: $(driver)
+
+
+# Install & Dist.
+#
+dist-common := $(out_base)/.dist-common
+
+$(install) $(dist) $(dist-win) $(dist-common): path := $(subst $(src_root)/,,$(src_base))
+
+$(install):
+ $(call install-data,$(src_base)/README,$(install_doc_dir)/xsd/$(path)/README)
+ $(call install-data,$(src_base)/driver.cxx,$(install_doc_dir)/xsd/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/calendar.xsd,$(install_doc_dir)/xsd/$(path)/calendar.xsd)
+ $(call install-data,$(src_base)/calendar.xml,$(install_doc_dir)/xsd/$(path)/calendar.xml)
+ $(call install-data,$(src_base)/xml-schema-custom.hxx,$(install_doc_dir)/xsd/$(path)/xml-schema-custom.hxx)
+ $(call install-data,$(src_base)/xml-schema-custom.cxx,$(install_doc_dir)/xsd/$(path)/xml-schema-custom.cxx)
+
+$(dist-common):
+ $(call install-data,$(src_base)/driver.cxx,$(dist_prefix)/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/calendar.xsd,$(dist_prefix)/$(path)/calendar.xsd)
+ $(call install-data,$(src_base)/calendar.xml,$(dist_prefix)/$(path)/calendar.xml)
+ $(call install-data,$(src_base)/xml-schema-custom.hxx,$(dist_prefix)/$(path)/xml-schema-custom.hxx)
+ $(call install-data,$(src_base)/xml-schema-custom.cxx,$(dist_prefix)/$(path)/xml-schema-custom.cxx)
+
+$(dist): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README)
+
+$(dist-win): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README.txt)
+ $(call message,,unix2dos $(dist_prefix)/$(path)/README.txt)
+
+# Clean.
+#
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+ $(call message,rm $$1,rm -f $$1,$(out_base)/xml-schema.hxx)
+
+# Generated .gitignore.
+#
+ifeq ($(out_base),$(src_base))
+$(gen): | $(out_base)/.gitignore
+$(driver): | $(out_base)/.gitignore
+
+$(out_base)/.gitignore: files := driver xml-schema.hxx $(genf)
+$(clean): $(out_base)/.gitignore.clean
+
+$(call include,$(bld_root)/git/gitignore.make)
+endif
+
+# 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,$(bld_root)/install.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/xsd/examples/cxx/tree/custom/calendar/xml-schema-custom.cxx b/xsd/examples/cxx/tree/custom/calendar/xml-schema-custom.cxx
new file mode 100644
index 0000000..440a407
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/calendar/xml-schema-custom.cxx
@@ -0,0 +1,57 @@
+// file : examples/cxx/tree/custom/calendar/xml-schema-custom.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Include xml-schema.hxx instead of xml-schema-custom.hxx here.
+//
+#include "xml-schema.hxx"
+
+#include <xsd/cxx/xml/string.hxx> // xsd::cxx::xml::transcode
+#include <xsd/cxx/tree/text.hxx> // xsd::cxx::tree::text_content
+
+using namespace boost;
+using namespace boost::gregorian;
+
+namespace xml_schema
+{
+ date::
+ date (const xercesc::DOMElement& e, flags f, container* c)
+ : simple_type (e, f, c),
+ gregorian::date (
+ from_simple_string (
+ xsd::cxx::tree::text_content<char> (e)))
+ {
+ }
+
+ date::
+ date (const xercesc::DOMAttr& a, flags f, container* c)
+ : simple_type (a, f, c),
+ gregorian::date (
+ from_simple_string (
+ xsd::cxx::xml::transcode<char> (a.getValue ())))
+ {
+ }
+
+ date::
+ date (const std::string& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : simple_type (s, e, f, c),
+ gregorian::date (from_simple_string (s))
+ {
+ }
+
+ date::
+ date (const date& d, flags f, container* c)
+ : simple_type (d, f, c),
+ gregorian::date (d)
+ {
+ }
+
+ date* date::
+ _clone (flags f, container* c) const
+ {
+ return new date (*this, f, c);
+ }
+}
diff --git a/xsd/examples/cxx/tree/custom/calendar/xml-schema-custom.hxx b/xsd/examples/cxx/tree/custom/calendar/xml-schema-custom.hxx
new file mode 100644
index 0000000..2bab0b5
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/calendar/xml-schema-custom.hxx
@@ -0,0 +1,34 @@
+// file : examples/cxx/tree/custom/calendar/xml-schema-custom.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use xml-schema.hxx instead. This
+// file is included into generated xml-schema.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <boost/date_time/gregorian/gregorian.hpp> // boost::gregorian::date
+
+namespace xml_schema
+{
+ class date: public simple_type,
+ public boost::gregorian::date
+ {
+ public:
+ // Parsing c-tors: element, attribute, and list item.
+ //
+ date (const xercesc::DOMElement&, flags = 0, container* = 0);
+ date (const xercesc::DOMAttr&, flags = 0, container* = 0);
+ date (const std::string&,
+ const xercesc::DOMElement*,
+ flags = 0,
+ container* = 0);
+
+ // Copy c-tor and _clone.
+ //
+ date (const date&, flags = 0, container* = 0);
+
+ virtual date*
+ _clone (flags = 0, container* = 0) const;
+ };
+}
diff --git a/xsd/examples/cxx/tree/custom/comments/README b/xsd/examples/cxx/tree/custom/comments/README
new file mode 100644
index 0000000..8fd69d0
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/comments/README
@@ -0,0 +1,57 @@
+This example shows how to customize the anyType XML Schema built-in
+type to implement preservation of comments stored in XML documents.
+Because anyType is a base type for every generated type, you can use
+this technique to implement custom functionality that spans the
+entire type system. For more information on the C++/Tree mapping
+customization see the C++/Tree Mapping Customization Guide[2].
+
+[2] http://wiki.codesynthesis.com/Tree/Customization_guide
+
+The example consists of the following files:
+
+people.xsd
+ XML Schema definition for a simple person record vocabulary.
+
+people.xml
+ Sample XML instance document.
+
+xml-schema.hxx
+ C++ types for XML Schema built-in types. This header file is generated
+ by XSD using the --generate-xml-schema option. The --custom-type option
+ is also used to customize the xsd:anyType type.
+
+people.hxx
+people.ixx
+people.cxx
+ C++ types that represent the person record vocabulary, a set of
+ parsing functions that convert XML instance documents to a tree-like
+ in-memory object model, and a set of serialization functions that
+ convert the object model back to XML. These are generated by XSD
+ from people.xsd with the --extern-xml-schema option in order to
+ include xml-schema.hxx.
+
+xml-schema-custom.hxx
+ Header file which defines our own xml_schema::type class. It is
+ included at the end of xml-schema.hxx using the --hxx-epilogue
+ option.
+
+xml-schema-custom.cxx
+ Source file which contains the implementation of our xml_schema:type
+ class.
+
+dom-parse.hxx
+dom-parse.cxx
+ Definition and implementation of the parse() function that
+ parses an XML document to a DOM document while preserving
+ XML comments.
+
+driver.cxx
+ Driver for the example. It first calls the above parse() function
+ to parse the input file to a DOM document. It then parses the DOM
+ document to the object model and performs a number of modifications
+ on this object model. Finally, it serializes the modified object
+ model back to XML, including XML comments.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver people.xml
diff --git a/xsd/examples/cxx/tree/custom/comments/dom-parse.cxx b/xsd/examples/cxx/tree/custom/comments/dom-parse.cxx
new file mode 100644
index 0000000..1ba62e5
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/comments/dom-parse.cxx
@@ -0,0 +1,125 @@
+// file : examples/cxx/tree/custom/comments/dom-parse.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include "dom-parse.hxx"
+
+#include <istream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_*
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+using namespace xercesc;
+namespace xml = xsd::cxx::xml;
+namespace tree = xsd::cxx::tree;
+
+xml::dom::auto_ptr<DOMDocument>
+parse (std::istream& is, const std::string& id, bool validate)
+{
+ const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+#if _XERCES_VERSION >= 30000
+
+ // Xerces-C++ 3.0.0 and later.
+ //
+ xml::dom::auto_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable/Disable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, validate);
+ conf->setParameter (XMLUni::fgXercesSchema, validate);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support.
+ //
+#if _XERCES_VERSION >= 30100
+ conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+#endif
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ // Set error handler.
+ //
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+#else // _XERCES_VERSION >= 30000
+
+ // Same as above but for Xerces-C++ 2 series.
+ //
+ xml::dom::auto_ptr<DOMBuilder> parser (
+ impl->createDOMBuilder (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ parser->setFeature (XMLUni::fgDOMComments, false);
+ parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
+ parser->setFeature (XMLUni::fgDOMEntities, false);
+ parser->setFeature (XMLUni::fgDOMNamespaces, true);
+ parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false);
+ parser->setFeature (XMLUni::fgDOMValidation, validate);
+ parser->setFeature (XMLUni::fgXercesSchema, validate);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ parser->setErrorHandler (&ehp);
+
+#endif // _XERCES_VERSION >= 30000
+
+ // Prepare input stream.
+ //
+ xml::sax::std_input_source isrc (is, id);
+ Wrapper4InputSource wrap (&isrc, false);
+
+#if _XERCES_VERSION >= 30000
+ xml::dom::auto_ptr<DOMDocument> doc (parser->parse (&wrap));
+#else
+ xml::dom::auto_ptr<DOMDocument> doc (parser->parse (wrap));
+#endif
+
+ eh.throw_if_failed<tree::parsing<char> > ();
+
+ return doc;
+}
diff --git a/xsd/examples/cxx/tree/custom/comments/dom-parse.hxx b/xsd/examples/cxx/tree/custom/comments/dom-parse.hxx
new file mode 100644
index 0000000..05bfa2e
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/comments/dom-parse.hxx
@@ -0,0 +1,23 @@
+// file : examples/cxx/tree/custom/comments/dom-parse.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef DOM_PARSE
+#define DOM_PARSE
+
+#include <string>
+#include <iosfwd>
+
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+
+// Parse an XML document from the standard input stream with an
+// optional resource id. Resource id is used in diagnostics as
+// well as to locate schemas referenced from inside the document.
+//
+xsd::cxx::xml::dom::auto_ptr<xercesc::DOMDocument>
+parse (std::istream& is,
+ const std::string& id,
+ bool validate);
+
+#endif // DOM_PARSE
diff --git a/xsd/examples/cxx/tree/custom/comments/driver.cxx b/xsd/examples/cxx/tree/custom/comments/driver.cxx
new file mode 100644
index 0000000..4ce2573
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/comments/driver.cxx
@@ -0,0 +1,91 @@
+// file : examples/cxx/tree/custom/commens/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include "people.hxx"
+#include "dom-parse.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " people.xml" << endl;
+ return 1;
+ }
+
+ int r (0);
+
+ // We need to initialize the Xerces-C++ runtime because we
+ // are doing the XML-to-DOM parsing ourselves (see below).
+ //
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ using namespace people;
+ namespace xml = xsd::cxx::xml;
+
+ ifstream ifs;
+ ifs.exceptions (ifstream::badbit | ifstream::failbit);
+ ifs.open (argv[1]);
+
+ // For performance reasons the internal XML to DOM parsing code
+ // discards comments in the resulting DOM document. To overcome
+ // this we are going to use our own parse() function from
+ // dom-parse.hxx that preserves comments in the resulting DOM
+ // documents.
+ //
+ xml_schema::dom::auto_ptr<xercesc::DOMDocument> doc (
+ parse (ifs, argv[1], true));
+
+ // Parse the DOM document to the object model.
+ //
+ std::auto_ptr<catalog> c (catalog_ (*doc));
+
+ // Change the object model.
+ //
+ catalog::person_sequence& ps (c->person ());
+
+ for (catalog::person_iterator i (ps.begin ()); i != ps.end (); ++i)
+ {
+ i->age (i->age () + 1);
+ }
+
+ person john ("John Doe", 30);
+ john.comment ("Record for John Doe");
+
+ ps.push_back (john);
+
+ // Serialize.
+ //
+ xml_schema::namespace_infomap map;
+
+ map["ppl"].name = "http://www.codesynthesis.com/people";
+ map["ppl"].schema = "people.xsd";
+
+ catalog_ (std::cout, *c, map);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ r = 1;
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+ return r;
+}
diff --git a/xsd/examples/cxx/tree/custom/comments/makefile b/xsd/examples/cxx/tree/custom/comments/makefile
new file mode 100644
index 0000000..de265a1
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/comments/makefile
@@ -0,0 +1,125 @@
+# file : examples/cxx/tree/custom/comments/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2010 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 xml-schema-custom.cxx dom-parse.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+install := $(out_base)/.install
+dist := $(out_base)/.dist
+dist-win := $(out_base)/.dist-win
+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)
+
+# Header file for XML Schema namespace.
+#
+$(out_base)/xml-schema.hxx: $(out_root)/xsd/xsd
+ $(call message,xsd $(src_base)/xml-schema.xsd,\
+$(out_root)/xsd/xsd cxx-tree --output-dir $(out_base) --generate-xml-schema \
+--generate-serialization --custom-type anyType=/type_base \
+--hxx-epilogue '\#include "xml-schema-custom.hxx"' xml-schema.xsd)
+
+#
+#
+genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx)
+gen := $(addprefix $(out_base)/,$(genf))
+
+$(gen): xsd := $(out_root)/xsd/xsd
+
+$(gen): xsd_options := \
+--generate-inline \
+--generate-serialization \
+--extern-xml-schema xml-schema.xsd
+
+$(gen): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+$(out_base)/: $(driver)
+
+
+# Install & Dist.
+#
+dist-common := $(out_base)/.dist-common
+
+$(install) $(dist) $(dist-win) $(dist-common): path := $(subst $(src_root)/,,$(src_base))
+
+$(install):
+ $(call install-data,$(src_base)/README,$(install_doc_dir)/xsd/$(path)/README)
+ $(call install-data,$(src_base)/driver.cxx,$(install_doc_dir)/xsd/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/people.xsd,$(install_doc_dir)/xsd/$(path)/people.xsd)
+ $(call install-data,$(src_base)/people.xml,$(install_doc_dir)/xsd/$(path)/people.xml)
+ $(call install-data,$(src_base)/xml-schema-custom.hxx,$(install_doc_dir)/xsd/$(path)/xml-schema-custom.hxx)
+ $(call install-data,$(src_base)/xml-schema-custom.cxx,$(install_doc_dir)/xsd/$(path)/xml-schema-custom.cxx)
+ $(call install-data,$(src_base)/dom-parse.hxx,$(install_doc_dir)/xsd/$(path)/dom-parse.hxx)
+ $(call install-data,$(src_base)/dom-parse.cxx,$(install_doc_dir)/xsd/$(path)/dom-parse.cxx)
+
+$(dist-common):
+ $(call install-data,$(src_base)/driver.cxx,$(dist_prefix)/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/people.xsd,$(dist_prefix)/$(path)/people.xsd)
+ $(call install-data,$(src_base)/people.xml,$(dist_prefix)/$(path)/people.xml)
+ $(call install-data,$(src_base)/xml-schema-custom.hxx,$(dist_prefix)/$(path)/xml-schema-custom.hxx)
+ $(call install-data,$(src_base)/xml-schema-custom.cxx,$(dist_prefix)/$(path)/xml-schema-custom.cxx)
+ $(call install-data,$(src_base)/dom-parse.hxx,$(dist_prefix)/$(path)/dom-parse.hxx)
+ $(call install-data,$(src_base)/dom-parse.cxx,$(dist_prefix)/$(path)/dom-parse.cxx)
+
+$(dist): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README)
+
+$(dist-win): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README.txt)
+ $(call message,,unix2dos $(dist_prefix)/$(path)/README.txt)
+
+# Clean.
+#
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+ $(call message,rm $$1,rm -f $$1,$(out_base)/xml-schema.hxx)
+
+# Generated .gitignore.
+#
+ifeq ($(out_base),$(src_base))
+$(gen): | $(out_base)/.gitignore
+$(driver): | $(out_base)/.gitignore
+
+$(out_base)/.gitignore: files := driver xml-schema.hxx $(genf)
+$(clean): $(out_base)/.gitignore.clean
+
+$(call include,$(bld_root)/git/gitignore.make)
+endif
+
+# 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,$(bld_root)/install.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/xsd/examples/cxx/tree/custom/comments/people.xml b/xsd/examples/cxx/tree/custom/comments/people.xml
new file mode 100644
index 0000000..b6a44e5
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/comments/people.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/comments/people.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<ppl:catalog xmlns:ppl="http://www.codesynthesis.com/people"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/people people.xsd">
+
+ <person>
+ <!--Record for Joe Dirt-->
+ <name>Joe Dirt</name>
+ <age>28</age>
+ </person>
+
+</ppl:catalog>
diff --git a/xsd/examples/cxx/tree/custom/comments/people.xsd b/xsd/examples/cxx/tree/custom/comments/people.xsd
new file mode 100644
index 0000000..2f40754
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/comments/people.xsd
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/comments/people.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:ppl="http://www.codesynthesis.com/people"
+ targetNamespace="http://www.codesynthesis.com/people">
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="age" type="xsd:unsignedShort"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="catalog">
+ <xsd:sequence>
+ <xsd:element name="person" type="ppl:person" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="catalog" type="ppl:catalog"/>
+
+</xsd:schema>
diff --git a/xsd/examples/cxx/tree/custom/comments/xml-schema-custom.cxx b/xsd/examples/cxx/tree/custom/comments/xml-schema-custom.cxx
new file mode 100644
index 0000000..d86d6af
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/comments/xml-schema-custom.cxx
@@ -0,0 +1,118 @@
+// file : examples/cxx/tree/custom/comments/xml-schema-custom.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Include xml-schema.hxx instead of xml-schema-custom.hxx here.
+//
+#include "xml-schema.hxx"
+
+#include <xercesc/dom/DOMComment.hpp>
+#include <xercesc/dom/DOMDocument.hpp>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode, xml::string
+
+namespace xml = xsd::cxx::xml;
+
+namespace xml_schema
+{
+ type::
+ type ()
+ : type_base ()
+ {
+ }
+
+ type::
+ type (const xercesc::DOMElement& e, flags f, container* c)
+ : type_base (e, f, c)
+ {
+ using namespace xercesc;
+
+ // Here we are only handling a comment that is the first
+ // node in the element's content.
+ //
+ const DOMNode* n (e.getFirstChild ());
+
+ if (n != 0 && n->getNodeType () == DOMNode::COMMENT_NODE)
+ {
+ const DOMComment* c (static_cast<const DOMComment*> (n));
+ comment_ = xml::transcode<char> (c->getData ());
+ }
+ }
+
+ type::
+ type (const xercesc::DOMAttr& a, flags f, container* c)
+ : type_base (a, f, c)
+ {
+ // No comments for attributes.
+ //
+ }
+
+ type::
+ type (const std::string& s, const xercesc::DOMElement* e,
+ flags f, container* c)
+ : type_base (s, e, f, c)
+ {
+ // No comments for list items.
+ //
+ }
+
+ type::
+ type (const type& x, flags f, container* c)
+ : type_base (x, f, c), comment_ (x.comment_)
+ {
+ }
+
+ type* type::
+ _clone (flags f, container* c) const
+ {
+ return new type (*this, f, c);
+ }
+
+ // Serialization operators.
+ //
+ void
+ operator<< (xercesc::DOMElement& e, const type& x)
+ {
+ // Call our base first.
+ //
+ const type_base& b (x);
+ e << b;
+
+ // Add the comment if any.
+ //
+ const std::string s (x.comment ());
+
+ if (!s.empty ())
+ {
+ using namespace xercesc;
+
+ DOMDocument* doc (e.getOwnerDocument ());
+ DOMComment* c (doc->createComment (xml::string (s).c_str ()));
+ e.appendChild (c);
+ }
+ }
+
+ void
+ operator<< (xercesc::DOMAttr& a, const type& x)
+ {
+ // Call our base first.
+ //
+ const type_base& b (x);
+ a << b;
+
+ // No comments for attributes.
+ //
+ }
+
+ void
+ operator<< (xml_schema::list_stream& ls, const type& x)
+ {
+ // Call our base first.
+ //
+ const type_base& b (x);
+ ls << b;
+
+ // No comments for list items.
+ //
+ }
+}
diff --git a/xsd/examples/cxx/tree/custom/comments/xml-schema-custom.hxx b/xsd/examples/cxx/tree/custom/comments/xml-schema-custom.hxx
new file mode 100644
index 0000000..821d0dd
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/comments/xml-schema-custom.hxx
@@ -0,0 +1,58 @@
+// file : examples/cxx/tree/custom/comments/xml-schema-custom.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use xml-schema.hxx instead. This
+// file is included into generated xml-schema.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <string>
+
+namespace xml_schema
+{
+ // When customizing anyType always inherit from the original type.
+ //
+ class type: public type_base
+ {
+ public:
+ type ();
+ type (const xercesc::DOMElement&, flags = 0, container* = 0);
+ type (const xercesc::DOMAttr&, flags = 0, container* = 0);
+ type (const std::string&, const xercesc::DOMElement*,
+ flags = 0, container* = 0);
+ type (const type&, flags = 0, container* = 0);
+
+ virtual type*
+ _clone (flags = 0, container* = 0) const;
+
+ public:
+ // Comment manipulation API.
+ //
+ const std::string&
+ comment () const
+ {
+ return comment_;
+ }
+
+ void
+ comment (const std::string& c)
+ {
+ comment_ = c;
+ }
+
+ private:
+ std::string comment_;
+ };
+
+ // New serialization operators.
+ //
+ void
+ operator<< (xercesc::DOMElement&, const type&);
+
+ void
+ operator<< (xercesc::DOMAttr&, const type&);
+
+ void
+ operator<< (xml_schema::list_stream&, const type&);
+}
diff --git a/xsd/examples/cxx/tree/custom/contacts/README b/xsd/examples/cxx/tree/custom/contacts/README
new file mode 100644
index 0000000..072ede3
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/contacts/README
@@ -0,0 +1,40 @@
+This example shows how to map a user-defined XML Schema type to a custom
+C++ class. It presents the simple case where the customized type is not
+used as a base in the same schema. For the complex case see the taxonomy
+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:
+
+contacts.xsd
+ XML Schema definition for a simple contacts database.
+
+contacts.xml
+ Sample XML instance document.
+
+contacts.hxx
+contacts.ixx
+contacts.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 contacts.xsd with the
+ --custom-type option in order to customize the contact type.
+
+contacts-custom.hxx
+ Header file which defines our own contact class by inheriting from the
+ generated contact_base. It is included at the end of contacts.hxx using
+ the --hxx-epilogue option.
+
+contacts-custom.cxx
+ Source file which contains the implementation of our contact class.
+
+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 contacts to STDERR.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver contacts.xml
diff --git a/xsd/examples/cxx/tree/custom/contacts/contacts-custom.cxx b/xsd/examples/cxx/tree/custom/contacts/contacts-custom.cxx
new file mode 100644
index 0000000..dd7c453
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/contacts/contacts-custom.cxx
@@ -0,0 +1,51 @@
+// file : examples/cxx/tree/custom/contacts/contacts-custom.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <ostream>
+
+// Include contacts.hxx instead of contacts-custom.hxx here.
+//
+#include "contacts.hxx"
+
+namespace contacts
+{
+ // We implement the following constructs by simply forwarding
+ // to our base.
+ //
+ contact::
+ contact (const name_type& n,
+ const email_type& e,
+ const phone_type& p)
+ : contact_base (n, e, p)
+ {
+ }
+
+ contact::
+ contact (const xercesc::DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : contact_base (e, f, c)
+ {
+ }
+
+ contact::
+ contact (const contact& x,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : contact_base (x, f, c)
+ {
+ }
+
+ contact* contact::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new contact (*this, f, c);
+ }
+
+ void contact::
+ print (std::ostream& os) const
+ {
+ os << name () << " e| " << email () << " t| " << phone () << std::endl;
+ }
+}
diff --git a/xsd/examples/cxx/tree/custom/contacts/contacts-custom.hxx b/xsd/examples/cxx/tree/custom/contacts/contacts-custom.hxx
new file mode 100644
index 0000000..fdb6810
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/contacts/contacts-custom.hxx
@@ -0,0 +1,44 @@
+// file : examples/cxx/tree/custom/contacts/contacts-custom.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use contacts.hxx instead. This
+// file is included into generated contacts.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <iosfwd> // std::ostream
+
+namespace contacts
+{
+ class contact: public contact_base
+ {
+ // The following constructor signatures are copied from
+ // contact_base except for the copy constructor and the
+ // _clone function where we had to change the type from
+ // contact_base to contact.
+ //
+ public:
+ contact (const name_type&,
+ const email_type&,
+ const phone_type&);
+
+ contact (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ contact (const contact&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ virtual contact*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ // Our customizations.
+ //
+ public:
+ void
+ print (std::ostream&) const;
+ };
+}
diff --git a/xsd/examples/cxx/tree/custom/contacts/contacts.xml b/xsd/examples/cxx/tree/custom/contacts/contacts.xml
new file mode 100644
index 0000000..c6dc38f
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/contacts/contacts.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/contacts/contacts.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<cts:catalog xmlns:cts="http://www.codesynthesis.com/contacts"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/contacts contacts.xsd">
+
+ <contact>
+ <name>Joe Dirt</name>
+ <email>joe@dirt.com</email>
+ <phone>555 DIRT</phone>
+ </contact>
+
+</cts:catalog>
diff --git a/xsd/examples/cxx/tree/custom/contacts/contacts.xsd b/xsd/examples/cxx/tree/custom/contacts/contacts.xsd
new file mode 100644
index 0000000..da73c78
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/contacts/contacts.xsd
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/contacts/contacts.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:cts="http://www.codesynthesis.com/contacts"
+ targetNamespace="http://www.codesynthesis.com/contacts">
+
+ <xsd:complexType name="contact">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="email" type="xsd:string"/>
+ <xsd:element name="phone" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="catalog">
+ <xsd:sequence>
+ <xsd:element name="contact" type="cts:contact" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <xsd:element name="catalog" type="cts:catalog"/>
+
+</xsd:schema>
diff --git a/xsd/examples/cxx/tree/custom/contacts/driver.cxx b/xsd/examples/cxx/tree/custom/contacts/driver.cxx
new file mode 100644
index 0000000..9015e87
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/contacts/driver.cxx
@@ -0,0 +1,39 @@
+// file : examples/cxx/tree/custom/contacts/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "contacts.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " contacts.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace contacts;
+
+ std::auto_ptr<catalog> c (catalog_ (argv[1]));
+
+ for (catalog::contact_const_iterator i (c->contact ().begin ());
+ i != c->contact ().end (); ++i)
+ {
+ i->print (cerr);
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd/examples/cxx/tree/custom/contacts/makefile b/xsd/examples/cxx/tree/custom/contacts/makefile
new file mode 100644
index 0000000..e279634
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/contacts/makefile
@@ -0,0 +1,114 @@
+# file : examples/cxx/tree/custom/contacts/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := contacts.xsd
+cxx := driver.cxx contacts-custom.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+install := $(out_base)/.install
+dist := $(out_base)/.dist
+dist-win := $(out_base)/.dist-win
+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)
+
+genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx)
+gen := $(addprefix $(out_base)/,$(genf))
+
+$(gen): xsd := $(out_root)/xsd/xsd
+
+# We have to double-escape '#' because the message function
+# (which is used in command scripts) expands things twice.
+#
+$(gen): xsd_options := \
+--generate-inline \
+--custom-type contact=/contact_base \
+--hxx-epilogue '\\\#include "contacts-custom.hxx"'
+
+$(gen): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+$(out_base)/: $(driver)
+
+
+# Install & Dist.
+#
+dist-common := $(out_base)/.dist-common
+
+$(install) $(dist) $(dist-win) $(dist-common): path := $(subst $(src_root)/,,$(src_base))
+
+$(install):
+ $(call install-data,$(src_base)/README,$(install_doc_dir)/xsd/$(path)/README)
+ $(call install-data,$(src_base)/driver.cxx,$(install_doc_dir)/xsd/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/contacts.xsd,$(install_doc_dir)/xsd/$(path)/contacts.xsd)
+ $(call install-data,$(src_base)/contacts.xml,$(install_doc_dir)/xsd/$(path)/contacts.xml)
+ $(call install-data,$(src_base)/contacts-custom.hxx,$(install_doc_dir)/xsd/$(path)/contacts-custom.hxx)
+ $(call install-data,$(src_base)/contacts-custom.cxx,$(install_doc_dir)/xsd/$(path)/contacts-custom.cxx)
+
+$(dist-common):
+ $(call install-data,$(src_base)/driver.cxx,$(dist_prefix)/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/contacts.xsd,$(dist_prefix)/$(path)/contacts.xsd)
+ $(call install-data,$(src_base)/contacts.xml,$(dist_prefix)/$(path)/contacts.xml)
+ $(call install-data,$(src_base)/contacts-custom.hxx,$(dist_prefix)/$(path)/contacts-custom.hxx)
+ $(call install-data,$(src_base)/contacts-custom.cxx,$(dist_prefix)/$(path)/contacts-custom.cxx)
+
+$(dist): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README)
+
+$(dist-win): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README.txt)
+ $(call message,,unix2dos $(dist_prefix)/$(path)/README.txt)
+
+# Clean.
+#
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+# Generated .gitignore.
+#
+ifeq ($(out_base),$(src_base))
+$(gen): | $(out_base)/.gitignore
+$(driver): | $(out_base)/.gitignore
+
+$(out_base)/.gitignore: files := driver $(genf)
+$(clean): $(out_base)/.gitignore.clean
+
+$(call include,$(bld_root)/git/gitignore.make)
+endif
+
+# 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,$(bld_root)/install.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/xsd/examples/cxx/tree/custom/double/README b/xsd/examples/cxx/tree/custom/double/README
new file mode 100644
index 0000000..15348d2
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/double/README
@@ -0,0 +1,62 @@
+This example shows how to customize parsing and serialization code for the
+xsd:double XML Schema built-in type using the type customization mechanism
+provided by the C++/Tree Mapping. For more information on type customization
+see the C++/Tree Mapping Customization Guide, particularly sections 1 and 4:
+
+http://wiki.codesynthesis.com/Tree/Customization_guide
+
+In this example our schema uses xsd:double to represent a price. There are
+two potential problems with this choice of a price type. First, xsd:double
+can be serialized in the scientific notation which would be an unusual way
+of representing a price. Second, we would like to limit the number of
+fraction digits in our prices to 2. Furthermore, we would like to always
+have two fraction digits, even if one or both of them are zeros, for
+example: 12.99, 12.90, 12.00.
+
+In case we can modify the schema, a better approach would be to define the
+price type as a restriction of the xsd:decimal type (always fixed notation)
+and specify the fractionDigits facet to limit the number of fraction digits
+to 2. However, there is no way in XML Schema to specify that there should
+always be exactly 2 fraction digits. Therefore, it may still be desirable
+to customize this price type to get the required serialization behavior.
+
+Finally, it is worth noting that the behavior achieved in this example via
+type customization can also be achieved by compiling your code with the
+following macros defined:
+
+XSD_TREE_DOUBLE_FIXED
+XSD_TREE_DOUBLE_PRECISION 2
+
+However, the type customization approach while requiring more work is
+cleaner since it does not rely on global macro definitions.
+
+This example consists of the following files:
+
+order.xsd
+ XML Schema definition for a simple order vocabulary.
+
+double-custom.hxx
+double-custom.cxx
+ Custom parsing and serialization code for the xsd:double types. The
+ double-custom.hxx file is included at the end of the xml-schema.hxx
+ file described below.
+
+xml-schema.hxx
+ C++ types for XML Schema built-in types. This header file is generated
+ by the XSD compiler using the --generate-xml-schema option. The
+ --custom-type option is used to customize the xsd:double type. The
+ --hxx-epilogue option is used to include the double-custom.hxx file
+ at the end of this file.
+
+order.hxx
+order.cxx
+ C++ types generated from order.xsd. The --extern-xml-schema option
+ is used to include xml-schema.hxx into order.hxx.
+
+driver.cxx
+ Test driver for the example. It creates a sample order and then
+ writes it to XML to test the custom xsd:double serialization code.
+
+To run the example simply execute:
+
+$ ./driver
diff --git a/xsd/examples/cxx/tree/custom/double/double-custom.cxx b/xsd/examples/cxx/tree/custom/double/double-custom.cxx
new file mode 100644
index 0000000..78904a0
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/double/double-custom.cxx
@@ -0,0 +1,97 @@
+// file : examples/cxx/tree/custom/double/double-custom.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Include xml-schema.hxx instead of double-custom.hxx here.
+//
+#include "xml-schema.hxx"
+
+#include <limits>
+#include <locale>
+#include <sstream>
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+using namespace std;
+
+// Parsing.
+//
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ double traits<double, char, schema_type::double_>::
+ create (const std::string& s,
+ const xercesc::DOMElement*,
+ flags,
+ type*)
+ {
+ // This type cannot have whitespaces in its values. As result we
+ // don't need to waste time collapsing whitespaces. All we need to
+ // do is trim the string representation which can be done without
+ // copying.
+ //
+ ro_string<char> tmp (s);
+ trim (tmp);
+
+ zc_istream<char> is (tmp);
+ is.imbue (locale::classic ());
+
+ double t;
+ is >> t;
+
+ return t;
+ }
+ }
+ }
+}
+
+// Serialization.
+//
+namespace XERCES_CPP_NAMESPACE
+{
+ void
+ operator<< (xercesc::DOMElement& e, const xml_schema::as_double& d)
+ {
+ ostringstream os;
+ os.imbue (locale::classic ());
+
+ os.precision (2);
+ os << fixed << d.x;
+
+ e << os.str ();
+ }
+
+ void
+ operator<< (xercesc::DOMAttr& a, const xml_schema::as_double& d)
+ {
+ ostringstream os;
+ os.imbue (locale::classic ());
+
+ os.precision (2);
+ os << fixed << d.x;
+
+ a << os.str ();
+ }
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ void
+ operator<< (xml_schema::list_stream& ls,
+ const xml_schema::as_double& d)
+ {
+ ls.os_.imbue (locale::classic ());
+ ls.os_.precision (2);
+ ls.os_ << fixed << d.x;
+ }
+ }
+ }
+}
diff --git a/xsd/examples/cxx/tree/custom/double/double-custom.hxx b/xsd/examples/cxx/tree/custom/double/double-custom.hxx
new file mode 100644
index 0000000..17d9a44
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/double/double-custom.hxx
@@ -0,0 +1,68 @@
+// file : examples/cxx/tree/custom/double/double-custom.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use xml-schema.hxx instead. This
+// file is included into generated xml-schema.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+#include <xsd/cxx/tree/text.hxx> // text_content
+
+// Parsing.
+//
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template<>
+ struct traits<double, char, schema_type::double_>
+ {
+ static double
+ create (const xercesc::DOMElement& e, flags f, type* c)
+ {
+ return create (text_content<char> (e), 0, f, c);
+ }
+
+ static double
+ create (const xercesc::DOMAttr& a, flags f, type* c)
+ {
+ return create (xml::transcode<char> (a.getValue ()), 0, f, c);
+ }
+
+ static double
+ create (const std::string& s,
+ const xercesc::DOMElement*,
+ flags,
+ type*);
+ };
+ }
+ }
+}
+
+// Serialization.
+//
+namespace XERCES_CPP_NAMESPACE
+{
+ void
+ operator<< (xercesc::DOMElement& e, const xml_schema::as_double& d);
+
+ void
+ operator<< (xercesc::DOMAttr& a, const xml_schema::as_double& d);
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ void
+ operator<< (xml_schema::list_stream& ls,
+ const xml_schema::as_double& d);
+ }
+ }
+}
diff --git a/xsd/examples/cxx/tree/custom/double/driver.cxx b/xsd/examples/cxx/tree/custom/double/driver.cxx
new file mode 100644
index 0000000..2e5b44d
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/double/driver.cxx
@@ -0,0 +1,32 @@
+// file : examples/cxx/tree/custom/double/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <iostream>
+
+#include "order.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main ()
+{
+ try
+ {
+ // Order one Airbus A380.
+ //
+ order o;
+ o.item ().push_back (item ("Airbus A380", 317000000.90));
+
+
+ // Serialize.
+ //
+ order_ (std::cout, o);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd/examples/cxx/tree/custom/double/makefile b/xsd/examples/cxx/tree/custom/double/makefile
new file mode 100644
index 0000000..5bd4f71
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/double/makefile
@@ -0,0 +1,114 @@
+# file : examples/cxx/tree/custom/double/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := order.xsd
+cxx := driver.cxx double-custom.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+install := $(out_base)/.install
+dist := $(out_base)/.dist
+dist-win := $(out_base)/.dist-win
+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)/xml-schema.hxx: $(out_root)/xsd/xsd
+ $(call message,xsd $(src_base)/xml-schema.xsd,\
+$(out_root)/xsd/xsd cxx-tree --output-dir $(out_base) --generate-xml-schema \
+--generate-serialization --custom-type double=double \
+--hxx-epilogue '\#include "double-custom.hxx"' xml-schema.xsd)
+
+genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx)
+gen := $(addprefix $(out_base)/,$(genf))
+
+$(gen): xsd := $(out_root)/xsd/xsd
+
+$(gen): xsd_options := \
+--generate-serialization --extern-xml-schema xml-schema.xsd
+
+$(gen): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+$(out_base)/: $(driver)
+
+
+# Install & Dist.
+#
+dist-common := $(out_base)/.dist-common
+
+$(install) $(dist) $(dist-win) $(dist-common): path := $(subst $(src_root)/,,$(src_base))
+
+$(install):
+ $(call install-data,$(src_base)/README,$(install_doc_dir)/xsd/$(path)/README)
+ $(call install-data,$(src_base)/driver.cxx,$(install_doc_dir)/xsd/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/order.xsd,$(install_doc_dir)/xsd/$(path)/order.xsd)
+ $(call install-data,$(src_base)/double-custom.hxx,$(install_doc_dir)/xsd/$(path)/double-custom.hxx)
+ $(call install-data,$(src_base)/double-custom.cxx,$(install_doc_dir)/xsd/$(path)/double-custom.cxx)
+
+$(dist-common):
+ $(call install-data,$(src_base)/driver.cxx,$(dist_prefix)/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/order.xsd,$(dist_prefix)/$(path)/order.xsd)
+ $(call install-data,$(src_base)/double-custom.hxx,$(dist_prefix)/$(path)/double-custom.hxx)
+ $(call install-data,$(src_base)/double-custom.cxx,$(dist_prefix)/$(path)/double-custom.cxx)
+
+$(dist): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README)
+
+$(dist-win): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README.txt)
+ $(call message,,unix2dos $(dist_prefix)/$(path)/README.txt)
+
+# Clean.
+#
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+ $(call message,rm $$1,rm -f $$1,$(out_base)/xml-schema.hxx)
+
+# Generated .gitignore.
+#
+ifeq ($(out_base),$(src_base))
+$(gen): | $(out_base)/.gitignore
+$(driver): | $(out_base)/.gitignore
+
+$(out_base)/.gitignore: files := driver xml-schema.hxx $(genf)
+$(clean): $(out_base)/.gitignore.clean
+
+$(call include,$(bld_root)/git/gitignore.make)
+endif
+
+# 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,$(bld_root)/install.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/xsd/examples/cxx/tree/custom/double/order.xsd b/xsd/examples/cxx/tree/custom/double/order.xsd
new file mode 100644
index 0000000..0d7fe05
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/double/order.xsd
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/double/order.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="item">
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ <xsd:attribute name="price" type="xsd:double" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="order">
+ <xsd:sequence>
+ <xsd:element name="item" type="item" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="order" type="order"/>
+
+</xsd:schema>
diff --git a/xsd/examples/cxx/tree/custom/makefile b/xsd/examples/cxx/tree/custom/makefile
new file mode 100644
index 0000000..d1044db
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/makefile
@@ -0,0 +1,50 @@
+# file : examples/cxx/tree/custom/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+all_examples := comments contacts double mixed taxonomy wildcard calendar
+build_examples := comments contacts double mixed taxonomy wildcard
+
+ifeq ($(xsd_with_boost_date_time),y)
+build_examples += calendar
+endif
+
+default := $(out_base)/
+install := $(out_base)/.install
+dist := $(out_base)/.dist
+dist-win := $(out_base)/.dist-win
+clean := $(out_base)/.clean
+
+# Build.
+#
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(build_examples)))
+
+# Install & Dist.
+#
+$(install) $(dist) $(dist-win): path := $(subst $(src_root)/,,$(src_base))
+
+$(install): $(addprefix $(out_base)/,$(addsuffix /.install,$(all_examples)))
+ $(call install-data,$(src_base)/README,$(install_doc_dir)/xsd/$(path)/README)
+
+$(dist): $(addprefix $(out_base)/,$(addsuffix /.dist,$(all_examples)))
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README)
+
+$(dist-win): $(addprefix $(out_base)/,$(addsuffix /.dist-win,$(all_examples)))
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README.txt)
+ $(call message,,unix2dos $(dist_prefix)/$(path)/README.txt)
+
+# Clean.
+#
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(build_examples)))
+
+$(call include,$(bld_root)/install.make)
+
+ifneq ($(filter $(MAKECMDGOALS),dist dist-win install),)
+$(foreach e,$(all_examples),$(call import,$(src_base)/$e/makefile))
+else
+$(foreach e,$(build_examples),$(call import,$(src_base)/$e/makefile))
+endif
+
diff --git a/xsd/examples/cxx/tree/custom/mixed/README b/xsd/examples/cxx/tree/custom/mixed/README
new file mode 100644
index 0000000..7b56812
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/mixed/README
@@ -0,0 +1,50 @@
+This example shows how to use type customization to parse and serialize
+mixed content. The example achieves this by customizing the type with
+the mixed content model to include a DOM document that stores the data
+as a raw XML representation. The customized type also provides its own
+parsing constructor and serialization operator where the mixed content
+is extracted from and inserted back to DOM, respectively. The use of
+DOM for mixed content storage is one of the options. You may find other
+data structures (e.g., a string) more suitable depending on your situation.
+
+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 person record vocabulary. Each
+ record includes the bio element which represents arbitrary XHTML
+ fragments as mixed content.
+
+people.xml
+ Sample XML instance document.
+
+people.hxx
+people.ixx
+people.cxx
+ C++ types that represent the given vocabulary, a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model, and a set of serialization functions that convert the
+ object model back to XML. These are generated by XSD from people.xsd
+ with the --custom-type option in order to customize the bio type.
+
+people-custom.hxx
+ Header file which defines our own bio class by inheriting from the
+ generated bio_base. It is included at the end of people.hxx using
+ the --hxx-epilogue option.
+
+people-custom.cxx
+ Source file which contains the implementation of our bio class.
+
+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 data to STDERR, including the bio information converted to text.
+ Finally, the driver serializes the object model back to XML.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver people.xml
diff --git a/xsd/examples/cxx/tree/custom/mixed/driver.cxx b/xsd/examples/cxx/tree/custom/mixed/driver.cxx
new file mode 100644
index 0000000..a6dd0a7
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/mixed/driver.cxx
@@ -0,0 +1,124 @@
+// file : examples/cxx/tree/custom/mixed/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include "people.hxx"
+
+// The following transcode() utility function is handy when working with
+// Xerces. Include it after the generated header in order to get only char
+// or wchar_t version depending on how you compiled your schemas.
+//
+#include <xsd/cxx/xml/string.hxx>
+
+using std::cerr;
+using std::endl;
+using namespace xercesc;
+
+
+void
+xhtml2txt (const DOMElement*);
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " people.xml" << endl;
+ return 1;
+ }
+
+ int r (0);
+
+ // The Xerces-C++ DOM document that will be used to store the XHTML
+ // fragments "out-live" the call to the parsing function. Therefore
+ // we need to initialize the Xerces-C++ runtime ourselves.
+ //
+ XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ using namespace people;
+
+ // Parse.
+ //
+ std::auto_ptr<directory> d (
+ directory_ (argv[1], xml_schema::flags::dont_initialize));
+
+ // Print what we've got.
+ //
+ const directory::person_sequence& s (d->person ());
+
+ for (directory::person_const_iterator i (s.begin ()); i != s.end (); ++i)
+ {
+ cerr << "First : " << i->first_name () << endl
+ << "Last : " << i->last_name () << endl
+ << "Gender : " << i->gender () << endl
+ << "Age : " << i->age () << endl;
+
+ const bio& b (i->bio ());
+ const DOMElement* xhtml (b.xhtml ());
+
+ if (xhtml != 0)
+ {
+ cerr << "Bio : " << endl;
+ xhtml2txt (xhtml);
+ }
+
+ cerr << endl;
+ }
+
+ // Serialize.
+ //
+ xml_schema::namespace_infomap map;
+
+ map["ppl"].name = "http://www.codesynthesis.com/people";
+ map["ppl"].schema = "people.xsd";
+
+ directory_ (
+ std::cout, *d, map, "UTF-8", xml_schema::flags::dont_initialize);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+
+ XMLPlatformUtils::Terminate ();
+ return r;
+}
+
+// Primitive XHTML to text converter that just prints all the text
+// nodes and ignores everything else.
+//
+void
+xhtml2txt (const DOMElement* e)
+{
+ namespace xml = xsd::cxx::xml;
+
+ for (const DOMNode* n (e->getFirstChild ());
+ n != 0;
+ n = n->getNextSibling ())
+ {
+ switch (n->getNodeType ())
+ {
+ case DOMNode::TEXT_NODE:
+ {
+ cerr << xml::transcode<char> (n->getTextContent ());
+ break;
+ }
+ case DOMNode::ELEMENT_NODE:
+ {
+ xhtml2txt (static_cast<const DOMElement*> (n));
+ break;
+ }
+ default:
+ break; // Ignore all other nodes (e.g., comments, etc).
+ }
+ }
+}
diff --git a/xsd/examples/cxx/tree/custom/mixed/makefile b/xsd/examples/cxx/tree/custom/mixed/makefile
new file mode 100644
index 0000000..144299e
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/mixed/makefile
@@ -0,0 +1,116 @@
+# file : examples/cxx/tree/custom/mixed/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2010 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
+install := $(out_base)/.install
+dist := $(out_base)/.dist
+dist-win := $(out_base)/.dist-win
+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)
+
+genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx)
+gen := $(addprefix $(out_base)/,$(genf))
+
+$(gen): xsd := $(out_root)/xsd/xsd
+
+# We have to double-escape '#' because the message function
+# (which is used in command scripts) expands things twice.
+#
+$(gen): xsd_options := \
+--generate-inline \
+--generate-serialization \
+--custom-type bio=/bio_base \
+--hxx-epilogue '\\\#include "people-custom.hxx"'
+
+$(gen): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+$(out_base)/: $(driver)
+
+
+# Install & Dist.
+#
+dist-common := $(out_base)/.dist-common
+
+$(install) $(dist) $(dist-win) $(dist-common): path := $(subst $(src_root)/,,$(src_base))
+
+$(install):
+ $(call install-data,$(src_base)/README,$(install_doc_dir)/xsd/$(path)/README)
+ $(call install-data,$(src_base)/driver.cxx,$(install_doc_dir)/xsd/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/people.xsd,$(install_doc_dir)/xsd/$(path)/people.xsd)
+ $(call install-data,$(src_base)/people.xml,$(install_doc_dir)/xsd/$(path)/people.xml)
+ $(call install-data,$(src_base)/people-custom.hxx,$(install_doc_dir)/xsd/$(path)/people-custom.hxx)
+ $(call install-data,$(src_base)/people-custom.cxx,$(install_doc_dir)/xsd/$(path)/people-custom.cxx)
+
+$(dist-common):
+ $(call install-data,$(src_base)/driver.cxx,$(dist_prefix)/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/people.xsd,$(dist_prefix)/$(path)/people.xsd)
+ $(call install-data,$(src_base)/people.xml,$(dist_prefix)/$(path)/people.xml)
+ $(call install-data,$(src_base)/people-custom.hxx,$(dist_prefix)/$(path)/people-custom.hxx)
+ $(call install-data,$(src_base)/people-custom.cxx,$(dist_prefix)/$(path)/people-custom.cxx)
+
+$(dist): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README)
+
+$(dist-win): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README.txt)
+ $(call message,,unix2dos $(dist_prefix)/$(path)/README.txt)
+
+
+# Clean.
+#
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+# Generated .gitignore.
+#
+ifeq ($(out_base),$(src_base))
+$(gen): | $(out_base)/.gitignore
+$(driver): | $(out_base)/.gitignore
+
+$(out_base)/.gitignore: files := driver $(genf)
+$(clean): $(out_base)/.gitignore.clean
+
+$(call include,$(bld_root)/git/gitignore.make)
+endif
+
+# 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,$(bld_root)/install.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/xsd/examples/cxx/tree/custom/mixed/people-custom.cxx b/xsd/examples/cxx/tree/custom/mixed/people-custom.cxx
new file mode 100644
index 0000000..af07e22
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/mixed/people-custom.cxx
@@ -0,0 +1,90 @@
+// file : examples/cxx/tree/custom/mixed/people-custom.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <ostream>
+
+// Include people.hxx instead of people-custom.hxx here.
+//
+#include "people.hxx"
+
+namespace people
+{
+ using namespace xercesc;
+
+ const XMLCh ls[] = {chLatin_L, chLatin_S, chNull};
+
+ bio::
+ bio ()
+ : xhtml_ (0)
+ {
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls));
+
+ doc_.reset (impl->createDocument ());
+ }
+
+ bio::
+ bio (const DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : bio_base (e, f, c), xhtml_ (0)
+ {
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls));
+
+ doc_.reset (impl->createDocument ());
+
+ // Copy the xhtml element. Assume the first child element in
+ // e is always xhtml.
+ //
+ for (DOMNode* n (e.getFirstChild ()); n != 0; n = n->getNextSibling ())
+ {
+ if (n->getNodeType () == DOMNode::ELEMENT_NODE)
+ {
+ xhtml_ = static_cast<DOMElement*> (doc_->importNode (n, true));
+ break;
+ }
+ }
+ }
+
+ bio::
+ bio (const bio& d,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : bio_base (d, f, c), xhtml_ (0)
+ {
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls));
+
+ doc_.reset (impl->createDocument ());
+
+ xhtml_ = static_cast<DOMElement*> (
+ doc_->importNode (const_cast<DOMElement*> (d.xhtml_), true));
+ }
+
+ bio* bio::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new bio (*this, f, c);
+ }
+
+ void
+ operator<< (DOMElement& e, const bio& x)
+ {
+ // Allow our base to serialize first.
+ //
+ const bio_base& b (x);
+ e << b;
+
+ // Copy the XHTML fragment if we have one.
+ //
+ const DOMElement* xhtml (x.xhtml ());
+
+ if (xhtml != 0)
+ {
+ DOMDocument* doc (e.getOwnerDocument ());
+ e.appendChild (doc->importNode (const_cast<DOMElement*> (xhtml), true));
+ }
+ }
+}
diff --git a/xsd/examples/cxx/tree/custom/mixed/people-custom.hxx b/xsd/examples/cxx/tree/custom/mixed/people-custom.hxx
new file mode 100644
index 0000000..f05ba4a
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/mixed/people-custom.hxx
@@ -0,0 +1,84 @@
+// file : examples/cxx/tree/custom/mixed/people-custom.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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 <cassert>
+#include <xercesc/dom/DOM.hpp>
+
+namespace people
+{
+ class bio: public bio_base
+ {
+ // Standard constructors.
+ //
+ public:
+ bio ();
+
+ bio (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ bio (const bio&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ virtual bio*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ // XHTML bio as a DOM document.
+ //
+ public:
+ const xercesc::DOMElement*
+ xhtml () const
+ {
+ return xhtml_;
+ }
+
+ xercesc::DOMElement*
+ xhtml ()
+ {
+ return xhtml_;
+ }
+
+ // The element should belong to the DOMDocument returned by
+ // the dom_document() functions.
+ //
+ void
+ xhtml (xercesc::DOMElement* e)
+ {
+ assert (e->getOwnerDocument () == doc_.get ());
+
+ if (xhtml_ != 0)
+ xhtml_->release ();
+
+ xhtml_ = e;
+ }
+
+ const xercesc::DOMDocument&
+ dom_document () const
+ {
+ return *doc_;
+ }
+
+ xercesc::DOMDocument&
+ dom_document ()
+ {
+ return *doc_;
+ }
+
+ private:
+ xercesc::DOMElement* xhtml_;
+ xml_schema::dom::auto_ptr<xercesc::DOMDocument> doc_;
+ };
+
+ // Serialization operator.
+ //
+ void
+ operator<< (xercesc::DOMElement&, const bio&);
+}
diff --git a/xsd/examples/cxx/tree/custom/mixed/people.xml b/xsd/examples/cxx/tree/custom/mixed/people.xml
new file mode 100644
index 0000000..4e5c0ca
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/mixed/people.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/mixed/people.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<ppl:directory xmlns:ppl="http://www.codesynthesis.com/people"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/people people.xsd">
+
+ <person>
+ <first-name>John</first-name>
+ <last-name>Doe</last-name>
+ <gender>male</gender>
+ <age>32</age>
+ <bio>
+ <xhtml xmlns="http://www.w3.org/1999/xhtml">
+ <p>Married to Jane Doe.</p>
+ </xhtml>
+ </bio>
+ </person>
+
+ <person>
+ <first-name>Jane</first-name>
+ <last-name>Doe</last-name>
+ <gender>female</gender>
+ <age>28</age>
+ <bio>
+ <xhtml xmlns="http://www.w3.org/1999/xhtml">
+ <p>Married to John Doe.</p>
+ </xhtml>
+ </bio>
+ </person>
+
+</ppl:directory>
diff --git a/xsd/examples/cxx/tree/custom/mixed/people.xsd b/xsd/examples/cxx/tree/custom/mixed/people.xsd
new file mode 100644
index 0000000..40c1fc1
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/mixed/people.xsd
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/mixed/people.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:ppl="http://www.codesynthesis.com/people"
+ targetNamespace="http://www.codesynthesis.com/people">
+
+ <xsd:simpleType name="gender">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="male"/>
+ <xsd:enumeration value="female"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:complexType name="bio" mixed="true">
+ <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+ <xsd:any namespace="http://www.w3.org/1999/xhtml" processContents="skip"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="first-name" type="xsd:string"/>
+ <xsd:element name="last-name" type="xsd:string"/>
+ <xsd:element name="gender" type="ppl:gender"/>
+ <xsd:element name="age" type="xsd:unsignedShort"/>
+ <xsd:element name="bio" type="ppl:bio"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="directory">
+ <xsd:sequence>
+ <xsd:element name="person" type="ppl:person" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="directory" type="ppl:directory"/>
+
+</xsd:schema>
diff --git a/xsd/examples/cxx/tree/custom/taxonomy/README b/xsd/examples/cxx/tree/custom/taxonomy/README
new file mode 100644
index 0000000..c2e425a
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/taxonomy/README
@@ -0,0 +1,53 @@
+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 customize the person, superman, and
+ batman types. Generation of the people-fwd.hxx forward declaration
+ file is requested with the --generate-forward option. Note also that
+ we use the --generate-polymorphic command line option as well as
+ --polymorphic-type to mark the type hierarchy starting with the
+ person type as polymorphic.
+
+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/xsd/examples/cxx/tree/custom/taxonomy/driver.cxx b/xsd/examples/cxx/tree/custom/taxonomy/driver.cxx
new file mode 100644
index 0000000..f102fc3
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/taxonomy/driver.cxx
@@ -0,0 +1,39 @@
+// file : examples/cxx/tree/custom/taxonomy/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#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<catalog> 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/xsd/examples/cxx/tree/custom/taxonomy/makefile b/xsd/examples/cxx/tree/custom/taxonomy/makefile
new file mode 100644
index 0000000..ca3327c
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/taxonomy/makefile
@@ -0,0 +1,123 @@
+# file : examples/cxx/tree/custom/taxonomy/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2010 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
+install := $(out_base)/.install
+dist := $(out_base)/.dist
+dist-win := $(out_base)/.dist-win
+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)
+
+genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=-fwd.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx)
+gen := $(addprefix $(out_base)/,$(genf))
+
+$(gen): xsd := $(out_root)/xsd/xsd
+
+# We have to double-escape '#' because the message function
+# (which is used in command scripts) expands things twice.
+#
+$(gen): xsd_options := \
+--generate-inline \
+--generate-forward \
+--generate-polymorphic \
+--polymorphic-type person \
+--custom-type "person=person_impl<person_base>/person_base" \
+--custom-type "superman=superman_impl<superman_base>/superman_base" \
+--custom-type "batman=batman_impl<batman_base>/batman_base" \
+--fwd-prologue '\\\#include "people-custom-fwd.hxx"' \
+--hxx-prologue '\\\#include "people-custom.hxx"'
+
+$(gen): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+$(out_base)/: $(driver)
+
+
+# Install & Dist.
+#
+dist-common := $(out_base)/.dist-common
+
+$(install) $(dist) $(dist-win) $(dist-common): path := $(subst $(src_root)/,,$(src_base))
+
+$(install):
+ $(call install-data,$(src_base)/README,$(install_doc_dir)/xsd/$(path)/README)
+ $(call install-data,$(src_base)/driver.cxx,$(install_doc_dir)/xsd/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/people.xsd,$(install_doc_dir)/xsd/$(path)/people.xsd)
+ $(call install-data,$(src_base)/people.xml,$(install_doc_dir)/xsd/$(path)/people.xml)
+ $(call install-data,$(src_base)/people-custom.hxx,$(install_doc_dir)/xsd/$(path)/people-custom.hxx)
+ $(call install-data,$(src_base)/people-custom.cxx,$(install_doc_dir)/xsd/$(path)/people-custom.cxx)
+ $(call install-data,$(src_base)/people-custom-fwd.hxx,$(install_doc_dir)/xsd/$(path)/people-custom-fwd.hxx)
+
+$(dist-common):
+ $(call install-data,$(src_base)/driver.cxx,$(dist_prefix)/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/people.xsd,$(dist_prefix)/$(path)/people.xsd)
+ $(call install-data,$(src_base)/people.xml,$(dist_prefix)/$(path)/people.xml)
+ $(call install-data,$(src_base)/people-custom.hxx,$(dist_prefix)/$(path)/people-custom.hxx)
+ $(call install-data,$(src_base)/people-custom.cxx,$(dist_prefix)/$(path)/people-custom.cxx)
+ $(call install-data,$(src_base)/people-custom-fwd.hxx,$(dist_prefix)/$(path)/people-custom-fwd.hxx)
+
+$(dist): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README)
+
+$(dist-win): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README.txt)
+ $(call message,,unix2dos $(dist_prefix)/$(path)/README.txt)
+
+
+# Clean.
+#
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+# Generated .gitignore.
+#
+ifeq ($(out_base),$(src_base))
+$(gen): | $(out_base)/.gitignore
+$(driver): | $(out_base)/.gitignore
+
+$(out_base)/.gitignore: files := driver $(genf)
+$(clean): $(out_base)/.gitignore.clean
+
+$(call include,$(bld_root)/git/gitignore.make)
+endif
+
+# 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,$(bld_root)/install.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/xsd/examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx b/xsd/examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx
new file mode 100644
index 0000000..973b6e5
--- /dev/null
+++ b/xsd/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 <boris@codesynthesis.com>
+// 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 <typename base>
+ class person_impl;
+
+ template <typename base>
+ class superman_impl;
+
+ template <typename base>
+ class batman_impl;
+}
diff --git a/xsd/examples/cxx/tree/custom/taxonomy/people-custom.cxx b/xsd/examples/cxx/tree/custom/taxonomy/people-custom.cxx
new file mode 100644
index 0000000..321d2df
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/taxonomy/people-custom.cxx
@@ -0,0 +1,157 @@
+// file : examples/cxx/tree/custom/taxonomy/people-custom.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <ostream>
+
+// Include people.hxx instead of people-custom.hxx here.
+//
+#include "people.hxx"
+
+namespace people
+{
+ // person_impl
+ //
+ template <typename base>
+ person_impl<base>::
+ person_impl (const xml_schema::string& name)
+ : base (name)
+ {
+ }
+
+ template <typename base>
+ person_impl<base>::
+ person_impl (const xercesc::DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : base (e, f, c)
+ {
+ }
+
+ template <typename base>
+ person_impl<base>::
+ person_impl (const person_impl& p,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : base (p, f, c)
+ {
+ }
+
+ template <typename base>
+ person_impl<base>* person_impl<base>::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new person_impl (*this, f, c);
+ }
+
+ template <typename base>
+ void person_impl<base>::
+ print (std::ostream& os) const
+ {
+ os << this->name () << std::endl;
+ }
+
+ // Explicitly instantiate person_impl class template for person_base.
+ //
+ template class person_impl<person_base>;
+
+
+ // superman_impl
+ //
+ template <typename base>
+ superman_impl<base>::
+ superman_impl (const xml_schema::string& name, bool can_fly)
+ : base (name, can_fly)
+ {
+ }
+
+ template <typename base>
+ superman_impl<base>::
+ superman_impl (const xercesc::DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : base (e, f, c)
+ {
+ }
+
+ template <typename base>
+ superman_impl<base>::
+ superman_impl (const superman_impl& s,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : base (s, f, c)
+ {
+ }
+
+ template <typename base>
+ superman_impl<base>* superman_impl<base>::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new superman_impl (*this, f, c);
+ }
+
+ template <typename base>
+ void superman_impl<base>::
+ 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<superman_base>;
+
+
+ // batman_impl
+ //
+ template <typename base>
+ batman_impl<base>::
+ batman_impl (const xml_schema::string& name,
+ bool can_fly,
+ unsigned int wing_span)
+ : base (name, can_fly, wing_span)
+ {
+ }
+
+ template <typename base>
+ batman_impl<base>::
+ batman_impl (const xercesc::DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : base (e, f, c)
+ {
+ }
+
+ template <typename base>
+ batman_impl<base>::
+ batman_impl (const batman_impl& s,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : base (s, f, c)
+ {
+ }
+
+ template <typename base>
+ batman_impl<base>* batman_impl<base>::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new batman_impl (*this, f, c);
+ }
+
+ template <typename base>
+ void batman_impl<base>::
+ 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<batman_base>;
+}
diff --git a/xsd/examples/cxx/tree/custom/taxonomy/people-custom.hxx b/xsd/examples/cxx/tree/custom/taxonomy/people-custom.hxx
new file mode 100644
index 0000000..c601061
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/taxonomy/people-custom.hxx
@@ -0,0 +1,97 @@
+// file : examples/cxx/tree/custom/taxonomy/people-custom.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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 <iosfwd> // std::ostream
+
+// Include people-fwd.hxx here so that we can refer to the generated
+// types.
+//
+#include "people-fwd.hxx"
+
+namespace people
+{
+ //
+ //
+ template <typename base>
+ class person_impl: public base
+ {
+ public:
+ person_impl (const xml_schema::string& 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 <typename base>
+ class superman_impl: public base
+ {
+ public:
+ superman_impl (const xml_schema::string& 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 <typename base>
+ class batman_impl: public base
+ {
+ public:
+ batman_impl (const xml_schema::string& 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/xsd/examples/cxx/tree/custom/taxonomy/people.xml b/xsd/examples/cxx/tree/custom/taxonomy/people.xml
new file mode 100644
index 0000000..5f84855
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/taxonomy/people.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/taxonomy/people.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<ppl:catalog xmlns:ppl="http://www.codesynthesis.com/people"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/people people.xsd">
+
+ <person>
+ <name>Joe Dirt</name>
+ </person>
+
+ <person xsi:type="ppl:superman" can-fly="false">
+ <name>James "007" Bond</name>
+ </person>
+
+ <person xsi:type="ppl:batman" can-fly="true" wing-span="10">
+ <name>Bruce Wayne</name>
+ </person>
+
+</ppl:catalog>
diff --git a/xsd/examples/cxx/tree/custom/taxonomy/people.xsd b/xsd/examples/cxx/tree/custom/taxonomy/people.xsd
new file mode 100644
index 0000000..c77a866
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/taxonomy/people.xsd
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/taxonomy/people.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:ppl="http://www.codesynthesis.com/people"
+ targetNamespace="http://www.codesynthesis.com/people">
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="superman">
+ <xsd:complexContent>
+ <xsd:extension base="ppl:person">
+ <xsd:attribute name="can-fly" type="xsd:boolean" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="batman">
+ <xsd:complexContent>
+ <xsd:extension base="ppl:superman">
+ <xsd:attribute name="wing-span" type="xsd:unsignedInt" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="catalog">
+ <xsd:sequence>
+ <xsd:element name="person" type="ppl:person" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="catalog" type="ppl:catalog"/>
+
+</xsd:schema>
diff --git a/xsd/examples/cxx/tree/custom/wildcard/README b/xsd/examples/cxx/tree/custom/wildcard/README
new file mode 100644
index 0000000..70eaea4
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/wildcard/README
@@ -0,0 +1,45 @@
+This example shows how to use type customization to parse and serialize
+a specific attribute that is matched by a wildcard (anyAttribute). The
+example achieves this by customizing the type to include the data
+members and accessors/modifiers that represent the attribute as well as
+the parsing constructor and serialization operator where the attribute
+value is extracted from and inserted back to DOM, respectively. 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:
+
+wildcard.xsd
+ XML Schema definition for simple data type and element.
+
+wildcard.xml
+ Sample XML instance document.
+
+wildcard.hxx
+wildcard.ixx
+wildcard.cxx
+ C++ types that represent the given vocabulary, a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model, and a set of serialization functions that convert the
+ object model back to XML. These are generated by XSD from wildcard.xsd
+ with the --custom-type option in order to customize the data type.
+
+wildcard-custom.hxx
+ Header file which defines our own data class by inheriting from the
+ generated data_base. It is included at the end of wildcard.hxx using
+ the --hxx-epilogue option.
+
+wildcard-custom.cxx
+ Source file which contains the implementation of our data class.
+
+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 data to STDERR, including the extra attribute. Finally, the driver
+ serializes the object model back to XML.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver wildcard.xml
diff --git a/xsd/examples/cxx/tree/custom/wildcard/driver.cxx b/xsd/examples/cxx/tree/custom/wildcard/driver.cxx
new file mode 100644
index 0000000..d63fb11
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/wildcard/driver.cxx
@@ -0,0 +1,48 @@
+// file : examples/cxx/tree/custom/wildcard/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "wildcard.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " wildcard.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace wildcard;
+
+ // Parse.
+ //
+ std::auto_ptr<data> d (data_ (argv[1]));
+
+ // Print.
+ //
+ cerr << *d << endl;
+
+ // Serialize.
+ //
+ xml_schema::namespace_infomap map;
+
+ map["wc"].name = "http://www.codesynthesis.com/wildcard";
+ map["wc"].schema = "wildcard.xsd";
+
+ data_ (std::cout, *d, map);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd/examples/cxx/tree/custom/wildcard/makefile b/xsd/examples/cxx/tree/custom/wildcard/makefile
new file mode 100644
index 0000000..d06fff3
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/wildcard/makefile
@@ -0,0 +1,117 @@
+# file : examples/cxx/tree/custom/wildcard/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := wildcard.xsd
+cxx := driver.cxx wildcard-custom.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+install := $(out_base)/.install
+dist := $(out_base)/.dist
+dist-win := $(out_base)/.dist-win
+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)
+
+genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx)
+gen := $(addprefix $(out_base)/,$(genf))
+
+$(gen): xsd := $(out_root)/xsd/xsd
+
+# We have to double-escape '#' because the message function
+# (which is used in command scripts) expands things twice.
+#
+$(gen): xsd_options := \
+--generate-inline \
+--generate-ostream \
+--generate-serialization \
+--custom-type data=/data_base \
+--hxx-epilogue '\\\#include "wildcard-custom.hxx"'
+
+$(gen): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+$(out_base)/: $(driver)
+
+
+# Install & Dist.
+#
+dist-common := $(out_base)/.dist-common
+
+$(install) $(dist) $(dist-win) $(dist-common): path := $(subst $(src_root)/,,$(src_base))
+
+$(install):
+ $(call install-data,$(src_base)/README,$(install_doc_dir)/xsd/$(path)/README)
+ $(call install-data,$(src_base)/driver.cxx,$(install_doc_dir)/xsd/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/wildcard.xsd,$(install_doc_dir)/xsd/$(path)/wildcard.xsd)
+ $(call install-data,$(src_base)/wildcard.xml,$(install_doc_dir)/xsd/$(path)/wildcard.xml)
+ $(call install-data,$(src_base)/wildcard-custom.hxx,$(install_doc_dir)/xsd/$(path)/wildcard-custom.hxx)
+ $(call install-data,$(src_base)/wildcard-custom.cxx,$(install_doc_dir)/xsd/$(path)/wildcard-custom.cxx)
+
+$(dist-common):
+ $(call install-data,$(src_base)/driver.cxx,$(dist_prefix)/$(path)/driver.cxx)
+ $(call install-data,$(src_base)/wildcard.xsd,$(dist_prefix)/$(path)/wildcard.xsd)
+ $(call install-data,$(src_base)/wildcard.xml,$(dist_prefix)/$(path)/wildcard.xml)
+ $(call install-data,$(src_base)/wildcard-custom.hxx,$(dist_prefix)/$(path)/wildcard-custom.hxx)
+ $(call install-data,$(src_base)/wildcard-custom.cxx,$(dist_prefix)/$(path)/wildcard-custom.cxx)
+
+$(dist): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README)
+
+$(dist-win): $(dist-common)
+ $(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README.txt)
+ $(call message,,unix2dos $(dist_prefix)/$(path)/README.txt)
+
+
+# Clean.
+#
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+# Generated .gitignore.
+#
+ifeq ($(out_base),$(src_base))
+$(gen): | $(out_base)/.gitignore
+$(driver): | $(out_base)/.gitignore
+
+$(out_base)/.gitignore: files := driver $(genf)
+$(clean): $(out_base)/.gitignore.clean
+
+$(call include,$(bld_root)/git/gitignore.make)
+endif
+
+# 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,$(bld_root)/install.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/xsd/examples/cxx/tree/custom/wildcard/wildcard-custom.cxx b/xsd/examples/cxx/tree/custom/wildcard/wildcard-custom.cxx
new file mode 100644
index 0000000..422a4b3
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/wildcard/wildcard-custom.cxx
@@ -0,0 +1,85 @@
+// file : examples/cxx/tree/custom/wildcard/wildcard-custom.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <ostream>
+
+// Include wildcard.hxx instead of wildcard-custom.hxx here.
+//
+#include "wildcard.hxx"
+
+namespace wildcard
+{
+ data::
+ data (const xml_schema::string& d)
+ : data_base (d), scope_present_ (false)
+ {
+ }
+
+ data::
+ data (const xercesc::DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : data_base (e, f, c), scope_present_ (false)
+ {
+ // Check if we've got the scope attribute.
+ //
+ namespace xml = xsd::cxx::xml;
+ xml::string name ("scope");
+
+ if (e.hasAttribute (name.c_str ()))
+ {
+ scope (xml::transcode<char> (e.getAttribute (name.c_str ())));
+ }
+ }
+
+ data::
+ data (const data& d,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : data_base (d, f, c),
+ scope_present_ (d.scope_present_),
+ scope_ (d.scope_)
+ {
+ }
+
+ data* data::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new data (*this, f, c);
+ }
+
+ void
+ operator<< (xercesc::DOMElement& e, const data& x)
+ {
+ // Use our base to serialize data and id.
+ //
+ const data_base& b (x);
+ e << b;
+
+ // Add the scope attribute if present.
+ //
+ if (x.scope_present ())
+ {
+ namespace xml = xsd::cxx::xml;
+ xml::string name ("scope");
+ xml::string value (x.scope ());
+
+ e.setAttribute (name.c_str (), value.c_str ());
+ }
+ }
+
+ std::ostream&
+ operator<< (std::ostream& os, const data& x)
+ {
+ // Use our base to print date and id.
+ //
+ const data_base& b (x);
+ os << b;
+
+ if (x.scope_present ())
+ os << std::endl << "scope: " << x.scope ();
+
+ return os;
+ }
+}
diff --git a/xsd/examples/cxx/tree/custom/wildcard/wildcard-custom.hxx b/xsd/examples/cxx/tree/custom/wildcard/wildcard-custom.hxx
new file mode 100644
index 0000000..2c58cc8
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/wildcard/wildcard-custom.hxx
@@ -0,0 +1,67 @@
+// file : examples/cxx/tree/custom/wildcard/wildcard-custom.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use wildcard.hxx instead. This
+// file is included into generated wildcard.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+namespace wildcard
+{
+ class data: public data_base
+ {
+ // Standard constructors.
+ //
+ public:
+ data (const xml_schema::string&);
+
+ data (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ data (const data&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ virtual data*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ // Our customizations.
+ //
+ public:
+ bool
+ scope_present () const
+ {
+ return scope_present_;
+ }
+
+ const xml_schema::string&
+ scope () const
+ {
+ return scope_;
+ }
+
+ void
+ scope (const xml_schema::string& s)
+ {
+ scope_present_ = true;
+ scope_ = s;
+ }
+
+ private:
+ bool scope_present_;
+ xml_schema::string scope_;
+ };
+
+ // Serialization operator.
+ //
+ void
+ operator<< (xercesc::DOMElement&, const data&);
+
+ // std::ostream insertion operator.
+ //
+ std::ostream&
+ operator<< (std::ostream&, const data&);
+}
diff --git a/xsd/examples/cxx/tree/custom/wildcard/wildcard.xml b/xsd/examples/cxx/tree/custom/wildcard/wildcard.xml
new file mode 100644
index 0000000..c980193
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/wildcard/wildcard.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/wildcard/wildcard.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<wc:data xmlns:wc="http://www.codesynthesis.com/wildcard"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/wildcard wildcard.xsd"
+ id="1"
+ scope="global">abc123</wc:data>
diff --git a/xsd/examples/cxx/tree/custom/wildcard/wildcard.xsd b/xsd/examples/cxx/tree/custom/wildcard/wildcard.xsd
new file mode 100644
index 0000000..ccce30b
--- /dev/null
+++ b/xsd/examples/cxx/tree/custom/wildcard/wildcard.xsd
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/wildcard/wildcard.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wc="http://www.codesynthesis.com/wildcard"
+ targetNamespace="http://www.codesynthesis.com/wildcard">
+
+ <xsd:complexType name="data">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="id" type="xsd:unsignedInt"/>
+ <xsd:anyAttribute namespace="##any" processContents="skip"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:element name="data" type="wc:data"/>
+
+</xsd:schema>