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/buildfile6
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/.gitignore2
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/README47
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/buildfile47
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/calendar.xml22
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/calendar.xsd31
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/driver.cxx39
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/xml-schema-custom.cxx56
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/xml-schema-custom.hxx33
-rw-r--r--xsd-examples/cxx/tree/custom/comments/.gitignore2
-rw-r--r--xsd-examples/cxx/tree/custom/comments/README57
-rw-r--r--xsd-examples/cxx/tree/custom/comments/buildfile48
-rw-r--r--xsd-examples/cxx/tree/custom/comments/dom-parse.cxx93
-rw-r--r--xsd-examples/cxx/tree/custom/comments/dom-parse.hxx23
-rw-r--r--xsd-examples/cxx/tree/custom/comments/driver.cxx90
-rw-r--r--xsd-examples/cxx/tree/custom/comments/people.xml20
-rw-r--r--xsd-examples/cxx/tree/custom/comments/people.xsd29
-rw-r--r--xsd-examples/cxx/tree/custom/comments/xml-schema-custom.cxx117
-rw-r--r--xsd-examples/cxx/tree/custom/comments/xml-schema-custom.hxx60
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/README40
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/buildfile25
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/contacts-custom.cxx50
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/contacts-custom.hxx43
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/contacts.xml20
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/contacts.xsd31
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/driver.cxx38
-rw-r--r--xsd-examples/cxx/tree/custom/double/.gitignore2
-rw-r--r--xsd-examples/cxx/tree/custom/double/README62
-rw-r--r--xsd-examples/cxx/tree/custom/double/buildfile46
-rw-r--r--xsd-examples/cxx/tree/custom/double/double-custom.cxx96
-rw-r--r--xsd-examples/cxx/tree/custom/double/double-custom.hxx67
-rw-r--r--xsd-examples/cxx/tree/custom/double/driver.cxx31
-rw-r--r--xsd-examples/cxx/tree/custom/double/order.xsd25
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/README50
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/buildfile30
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/driver.cxx122
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/people-custom.cxx89
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/people-custom.hxx83
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/people.xml38
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/people.xsd45
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/.gitignore2
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/README53
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/buildfile31
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/driver.cxx38
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx19
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/people-custom.cxx156
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/people-custom.hxx105
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/people.xml26
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/people.xsd44
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/README45
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/buildfile27
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/driver.cxx47
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/wildcard-custom.cxx84
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/wildcard-custom.hxx66
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/wildcard.xml14
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/wildcard.xsd25
60 files changed, 2680 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/buildfile b/xsd-examples/cxx/tree/custom/buildfile
new file mode 100644
index 0000000..e650f99
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/buildfile
@@ -0,0 +1,6 @@
+# file : cxx/tree/custom/buildfile
+# license : not copyrighted - public domain
+
+# Exclude examples which depend on not yet packaged libraries.
+#
+./: {*/ -calendar/}
diff --git a/xsd-examples/cxx/tree/custom/calendar/.gitignore b/xsd-examples/cxx/tree/custom/calendar/.gitignore
new file mode 100644
index 0000000..2f35b6b
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/.gitignore
@@ -0,0 +1,2 @@
+calendar.?xx
+xml-schema.hxx
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/buildfile b/xsd-examples/cxx/tree/custom/calendar/buildfile
new file mode 100644
index 0000000..3c26122
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/buildfile
@@ -0,0 +1,47 @@
+# file : cxx/tree/custom/calendar/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+import libs += libboost-date-time%lib{boost_date_time}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -calendar -xml-schema} \
+ {hxx ixx cxx}{calendar} \
+ {hxx }{xml-schema} \
+ $libs
+
+exe{driver}: xml{calendar}: test.input = true
+
+<{hxx ixx cxx}{calendar}>: xsd{calendar} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --extern-xml-schema xml-schema.xsd \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+hxx{xml-schema}: $xsd
+{{
+ diag xsd gen ($>[0])
+
+ # Note that the specified xml-schema.xsd doesn't exist and is only used to
+ # deduce the generated header name.
+ #
+ $xsd cxx-tree --std c++11 \
+ --generate-xml-schema \
+ --custom-type date \
+ --hxx-epilogue '#include "xml-schema-custom.hxx"' \
+ --output-dir $out_base \
+ xml-schema.xsd
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
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..8fff59c
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/calendar.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/calendar/calendar.xml
+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..8b36c34
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/calendar.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/calendar/calendar.xsd
+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..fdecf57
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/driver.cxx
@@ -0,0 +1,39 @@
+// file : cxx/tree/custom/calendar/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_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::unique_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/xml-schema-custom.cxx b/xsd-examples/cxx/tree/custom/calendar/xml-schema-custom.cxx
new file mode 100644
index 0000000..2bfe0f2
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/xml-schema-custom.cxx
@@ -0,0 +1,56 @@
+// file : cxx/tree/custom/calendar/xml-schema-custom.cxx
+// 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..f8f8218
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/xml-schema-custom.hxx
@@ -0,0 +1,33 @@
+// file : cxx/tree/custom/calendar/xml-schema-custom.hxx
+// 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/.gitignore b/xsd-examples/cxx/tree/custom/comments/.gitignore
new file mode 100644
index 0000000..78cfc67
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/.gitignore
@@ -0,0 +1,2 @@
+people.?xx
+xml-schema.hxx
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/buildfile b/xsd-examples/cxx/tree/custom/comments/buildfile
new file mode 100644
index 0000000..093a6cc
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/buildfile
@@ -0,0 +1,48 @@
+# file : cxx/tree/custom/comments/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -people -xml-schema} \
+ {hxx ixx cxx}{people} \
+ {hxx }{xml-schema} \
+ $libs
+
+exe{driver}: xml{people}: test.input = true
+
+<{hxx ixx cxx}{people}>: xsd{people} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-serialization \
+ --extern-xml-schema xml-schema.xsd \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+hxx{xml-schema}: $xsd
+{{
+ diag xsd gen ($>[0])
+
+ # Note that the specified xml-schema.xsd doesn't exist and is only used to
+ # deduce the generated header name.
+ #
+ $xsd cxx-tree --std c++11 \
+ --generate-xml-schema \
+ --generate-serialization \
+ --custom-type anyType=/type_base \
+ --hxx-epilogue '#include "xml-schema-custom.hxx"' \
+ --output-dir $out_base \
+ xml-schema.xsd
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
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..2fa6a70
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/dom-parse.cxx
@@ -0,0 +1,93 @@
+// file : cxx/tree/custom/comments/dom-parse.cxx
+// 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::unique_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));
+
+ xml::dom::unique_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Preserve comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, true);
+
+ // 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);
+
+ // Prepare input stream.
+ //
+ xml::sax::std_input_source isrc (is, id);
+ Wrapper4InputSource wrap (&isrc, false);
+
+ xml::dom::unique_ptr<DOMDocument> doc (parser->parse (&wrap));
+
+ 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..83c3dd4
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/dom-parse.hxx
@@ -0,0 +1,23 @@
+// file : cxx/tree/custom/comments/dom-parse.hxx
+// 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::unique_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..5588273
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/driver.cxx
@@ -0,0 +1,90 @@
+// file : cxx/tree/custom/commens/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_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::unique_ptr<xercesc::DOMDocument> doc (
+ parse (ifs, argv[1], true));
+
+ // Parse the DOM document to the object model.
+ //
+ unique_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/people.xml b/xsd-examples/cxx/tree/custom/comments/people.xml
new file mode 100644
index 0000000..08d69e9
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/people.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/comments/people.xml
+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..20f265f
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/people.xsd
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/comments/people.xsd
+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..265e0cb
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/xml-schema-custom.cxx
@@ -0,0 +1,117 @@
+// file : cxx/tree/custom/comments/xml-schema-custom.cxx
+// 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..01a4f9c
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/xml-schema-custom.hxx
@@ -0,0 +1,60 @@
+// file : cxx/tree/custom/comments/xml-schema-custom.hxx
+// 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);
+
+ type&
+ operator= (const type&) = default;
+
+ 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/.gitignore b/xsd-examples/cxx/tree/custom/contacts/.gitignore
new file mode 100644
index 0000000..43c214d
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/.gitignore
@@ -0,0 +1 @@
+contacts.?xx
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/buildfile b/xsd-examples/cxx/tree/custom/contacts/buildfile
new file mode 100644
index 0000000..190306c
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/buildfile
@@ -0,0 +1,25 @@
+# file : cxx/tree/custom/contacts/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -contacts} {hxx ixx cxx}{contacts} $libs
+
+exe{driver}: xml{contacts}: test.input = true
+
+<{hxx ixx cxx}{contacts}>: xsd{contacts} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --custom-type contact=/contact_base \
+ --hxx-epilogue '#include "contacts-custom.hxx"' \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
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..208b00f
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/contacts-custom.cxx
@@ -0,0 +1,50 @@
+// file : cxx/tree/custom/contacts/contacts-custom.cxx
+// 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..a5bc893
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/contacts-custom.hxx
@@ -0,0 +1,43 @@
+// file : cxx/tree/custom/contacts/contacts-custom.hxx
+// 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..884c25e
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/contacts.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/contacts/contacts.xml
+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..5348810
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/contacts.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/contacts/contacts.xsd
+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..a0c7510
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/driver.cxx
@@ -0,0 +1,38 @@
+// file : cxx/tree/custom/contacts/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_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::unique_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/double/.gitignore b/xsd-examples/cxx/tree/custom/double/.gitignore
new file mode 100644
index 0000000..5cc7f75
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/double/.gitignore
@@ -0,0 +1,2 @@
+order.?xx
+xml-schema.hxx
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/buildfile b/xsd-examples/cxx/tree/custom/double/buildfile
new file mode 100644
index 0000000..258191a
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/double/buildfile
@@ -0,0 +1,46 @@
+# file : cxx/tree/custom/double/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -order -xml-schema} \
+ {hxx ixx cxx}{order} \
+ {hxx }{xml-schema} \
+ $libs
+
+<{hxx ixx cxx}{order}>: xsd{order} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-serialization \
+ --extern-xml-schema xml-schema.xsd \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+hxx{xml-schema}: $xsd
+{{
+ diag xsd gen ($>[0])
+
+ # Note that the specified xml-schema.xsd doesn't exist and is only used to
+ # deduce the generated header name.
+ #
+ $xsd cxx-tree --std c++11 \
+ --generate-xml-schema \
+ --generate-serialization \
+ --custom-type double=double \
+ --hxx-epilogue '#include "double-custom.hxx"' \
+ --output-dir $out_base \
+ xml-schema.xsd
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
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..bfec6e0
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/double/double-custom.cxx
@@ -0,0 +1,96 @@
+// file : cxx/tree/custom/double/double-custom.cxx
+// 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..cb74442
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/double/double-custom.hxx
@@ -0,0 +1,67 @@
+// file : cxx/tree/custom/double/double-custom.hxx
+// 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..e3f1800
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/double/driver.cxx
@@ -0,0 +1,31 @@
+// file : cxx/tree/custom/double/driver.cxx
+// 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/order.xsd b/xsd-examples/cxx/tree/custom/double/order.xsd
new file mode 100644
index 0000000..8066975
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/double/order.xsd
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/double/order.xsd
+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/mixed/.gitignore b/xsd-examples/cxx/tree/custom/mixed/.gitignore
new file mode 100644
index 0000000..83d0a51
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/.gitignore
@@ -0,0 +1 @@
+people.?xx
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/buildfile b/xsd-examples/cxx/tree/custom/mixed/buildfile
new file mode 100644
index 0000000..9da936e
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/buildfile
@@ -0,0 +1,30 @@
+# file : cxx/tree/custom/mixed/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -people} {hxx ixx cxx}{people} $libs
+
+exe{driver}: xml{people}: test.input = true
+
+<{hxx ixx cxx}{people}>: xsd{people} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-serialization \
+ --custom-type bio=/bio_base \
+ --hxx-epilogue '#include "people-custom.hxx"' \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
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..08c83e0
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/driver.cxx
@@ -0,0 +1,122 @@
+// file : cxx/tree/custom/mixed/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_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::unique_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/people-custom.cxx b/xsd-examples/cxx/tree/custom/mixed/people-custom.cxx
new file mode 100644
index 0000000..bd03fcc
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/people-custom.cxx
@@ -0,0 +1,89 @@
+// file : cxx/tree/custom/mixed/people-custom.cxx
+// 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..2ab949d
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/people-custom.hxx
@@ -0,0 +1,83 @@
+// file : cxx/tree/custom/mixed/people-custom.hxx
+// 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::unique_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..4033f95
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/people.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/mixed/people.xml
+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..739861b
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/people.xsd
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/mixed/people.xsd
+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/.gitignore b/xsd-examples/cxx/tree/custom/taxonomy/.gitignore
new file mode 100644
index 0000000..71428ab
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/.gitignore
@@ -0,0 +1,2 @@
+people.?xx
+people-fwd.hxx
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/buildfile b/xsd-examples/cxx/tree/custom/taxonomy/buildfile
new file mode 100644
index 0000000..9267c68
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/buildfile
@@ -0,0 +1,31 @@
+# file : cxx/tree/custom/taxonomy/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -people} {hxx ixx cxx}{people} hxx{people-fwd} $libs
+
+exe{driver}: xml{people}: test.input = true
+
+<{hxx ixx cxx}{people} hxx{people-fwd}>: xsd{people} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --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"' \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
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..f719bbb
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/driver.cxx
@@ -0,0 +1,38 @@
+// file : cxx/tree/custom/taxonomy/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_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::unique_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/people-custom-fwd.hxx b/xsd-examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx
new file mode 100644
index 0000000..1b59a54
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx
@@ -0,0 +1,19 @@
+// file : cxx/tree/custom/taxonomy/people-custom-fwd.hxx
+// 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..decc847
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/people-custom.cxx
@@ -0,0 +1,156 @@
+// file : cxx/tree/custom/taxonomy/people-custom.cxx
+// 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..58c94c4
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/people-custom.hxx
@@ -0,0 +1,105 @@
+// file : cxx/tree/custom/taxonomy/people-custom.hxx
+// 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);
+
+ person_impl&
+ operator= (const person_impl&) = default;
+
+ 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;
+
+ superman_impl&
+ operator= (const superman_impl&) = default;
+
+ 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);
+
+ batman_impl&
+ operator= (const batman_impl&) = default;
+
+ 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..831c547
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/people.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/taxonomy/people.xml
+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..b07f338
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/people.xsd
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/taxonomy/people.xsd
+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/.gitignore b/xsd-examples/cxx/tree/custom/wildcard/.gitignore
new file mode 100644
index 0000000..f32cbe8
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/.gitignore
@@ -0,0 +1 @@
+wildcard.?xx
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/buildfile b/xsd-examples/cxx/tree/custom/wildcard/buildfile
new file mode 100644
index 0000000..e386709
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/buildfile
@@ -0,0 +1,27 @@
+# file : cxx/tree/custom/wildcard/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -wildcard} {hxx ixx cxx}{wildcard} $libs
+
+exe{driver}: xml{wildcard}: test.input = true
+
+<{hxx ixx cxx}{wildcard}>: xsd{wildcard} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-serialization \
+ --generate-ostream \
+ --custom-type data=/data_base \
+ --hxx-epilogue '#include "wildcard-custom.hxx"' \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
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..43fae82
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/driver.cxx
@@ -0,0 +1,47 @@
+// file : cxx/tree/custom/wildcard/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_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::unique_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/wildcard-custom.cxx b/xsd-examples/cxx/tree/custom/wildcard/wildcard-custom.cxx
new file mode 100644
index 0000000..16798d2
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/wildcard-custom.cxx
@@ -0,0 +1,84 @@
+// file : cxx/tree/custom/wildcard/wildcard-custom.cxx
+// 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..e789a86
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/wildcard-custom.hxx
@@ -0,0 +1,66 @@
+// file : cxx/tree/custom/wildcard/wildcard-custom.hxx
+// 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..8f6ba65
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/wildcard.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/wildcard/wildcard.xml
+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..a19be3f
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/wildcard.xsd
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/wildcard/wildcard.xsd
+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>