summaryrefslogtreecommitdiff
path: root/xsd-examples/cxx/parser
diff options
context:
space:
mode:
Diffstat (limited to 'xsd-examples/cxx/parser')
-rw-r--r--xsd-examples/cxx/parser/.gitignore1
-rw-r--r--xsd-examples/cxx/parser/README45
-rw-r--r--xsd-examples/cxx/parser/buildfile4
-rw-r--r--xsd-examples/cxx/parser/generated/.gitignore2
-rw-r--r--xsd-examples/cxx/parser/generated/README32
-rw-r--r--xsd-examples/cxx/parser/generated/buildfile32
-rw-r--r--xsd-examples/cxx/parser/generated/library.xml52
-rw-r--r--xsd-examples/cxx/parser/generated/library.xsd78
-rw-r--r--xsd-examples/cxx/parser/hello/README28
-rw-r--r--xsd-examples/cxx/parser/hello/buildfile24
-rw-r--r--xsd-examples/cxx/parser/hello/driver.cxx67
-rw-r--r--xsd-examples/cxx/parser/hello/hello.xml19
-rw-r--r--xsd-examples/cxx/parser/hello/hello.xsd21
-rw-r--r--xsd-examples/cxx/parser/library/README44
-rw-r--r--xsd-examples/cxx/parser/library/buildfile25
-rw-r--r--xsd-examples/cxx/parser/library/driver.cxx109
-rw-r--r--xsd-examples/cxx/parser/library/library-pimpl.cxx183
-rw-r--r--xsd-examples/cxx/parser/library/library-pimpl.hxx135
-rw-r--r--xsd-examples/cxx/parser/library/library.hxx241
-rw-r--r--xsd-examples/cxx/parser/library/library.map15
-rw-r--r--xsd-examples/cxx/parser/library/library.xml52
-rw-r--r--xsd-examples/cxx/parser/library/library.xsd78
-rw-r--r--xsd-examples/cxx/parser/mixed/README49
-rw-r--r--xsd-examples/cxx/parser/mixed/anchor.hxx33
-rw-r--r--xsd-examples/cxx/parser/mixed/buildfile25
-rw-r--r--xsd-examples/cxx/parser/mixed/driver.cxx100
-rw-r--r--xsd-examples/cxx/parser/mixed/text.map6
-rw-r--r--xsd-examples/cxx/parser/mixed/text.xml17
-rw-r--r--xsd-examples/cxx/parser/mixed/text.xsd28
-rw-r--r--xsd-examples/cxx/parser/mixin/README34
-rw-r--r--xsd-examples/cxx/parser/mixin/buildfile25
-rw-r--r--xsd-examples/cxx/parser/mixin/driver.cxx103
-rw-r--r--xsd-examples/cxx/parser/mixin/instance.xml16
-rw-r--r--xsd-examples/cxx/parser/mixin/schema.map7
-rw-r--r--xsd-examples/cxx/parser/mixin/schema.xsd30
-rw-r--r--xsd-examples/cxx/parser/mixin/types.hxx43
-rw-r--r--xsd-examples/cxx/parser/multiroot/README51
-rw-r--r--xsd-examples/cxx/parser/multiroot/balance.xml16
-rw-r--r--xsd-examples/cxx/parser/multiroot/buildfile24
-rw-r--r--xsd-examples/cxx/parser/multiroot/deposit.xml17
-rw-r--r--xsd-examples/cxx/parser/multiroot/driver.cxx161
-rw-r--r--xsd-examples/cxx/parser/multiroot/protocol-pimpl.cxx46
-rw-r--r--xsd-examples/cxx/parser/multiroot/protocol-pimpl.hxx48
-rw-r--r--xsd-examples/cxx/parser/multiroot/protocol.hxx61
-rw-r--r--xsd-examples/cxx/parser/multiroot/protocol.map11
-rw-r--r--xsd-examples/cxx/parser/multiroot/protocol.xsd50
-rw-r--r--xsd-examples/cxx/parser/multiroot/testscript6
-rw-r--r--xsd-examples/cxx/parser/multiroot/withdraw.xml17
-rw-r--r--xsd-examples/cxx/parser/performance/.gitignore7
-rw-r--r--xsd-examples/cxx/parser/performance/README46
-rw-r--r--xsd-examples/cxx/parser/performance/buildfile57
-rw-r--r--xsd-examples/cxx/parser/performance/driver.cxx346
-rw-r--r--xsd-examples/cxx/parser/performance/gen.cxx79
-rw-r--r--xsd-examples/cxx/parser/performance/gen.testscript9
-rw-r--r--xsd-examples/cxx/parser/performance/test-50k.xml1
-rw-r--r--xsd-examples/cxx/parser/performance/test.xsd49
-rw-r--r--xsd-examples/cxx/parser/performance/time.cxx46
-rw-r--r--xsd-examples/cxx/parser/performance/time.hxx110
-rw-r--r--xsd-examples/cxx/parser/polymorphism/README30
-rw-r--r--xsd-examples/cxx/parser/polymorphism/buildfile25
-rw-r--r--xsd-examples/cxx/parser/polymorphism/driver.cxx70
-rw-r--r--xsd-examples/cxx/parser/polymorphism/supermen-pimpl.cxx85
-rw-r--r--xsd-examples/cxx/parser/polymorphism/supermen-pimpl.hxx68
-rw-r--r--xsd-examples/cxx/parser/polymorphism/supermen.xml25
-rw-r--r--xsd-examples/cxx/parser/polymorphism/supermen.xsd48
-rw-r--r--xsd-examples/cxx/parser/polyroot/README36
-rw-r--r--xsd-examples/cxx/parser/polyroot/batman.xml16
-rw-r--r--xsd-examples/cxx/parser/polyroot/buildfile24
-rw-r--r--xsd-examples/cxx/parser/polyroot/driver.cxx138
-rw-r--r--xsd-examples/cxx/parser/polyroot/person.xml15
-rw-r--r--xsd-examples/cxx/parser/polyroot/superman.xml16
-rw-r--r--xsd-examples/cxx/parser/polyroot/supermen-pimpl.cxx85
-rw-r--r--xsd-examples/cxx/parser/polyroot/supermen-pimpl.hxx64
-rw-r--r--xsd-examples/cxx/parser/polyroot/supermen.xsd36
-rw-r--r--xsd-examples/cxx/parser/polyroot/testscript6
-rw-r--r--xsd-examples/cxx/parser/wildcard/README27
-rw-r--r--xsd-examples/cxx/parser/wildcard/buildfile24
-rw-r--r--xsd-examples/cxx/parser/wildcard/driver.cxx239
-rw-r--r--xsd-examples/cxx/parser/wildcard/email.xml31
-rw-r--r--xsd-examples/cxx/parser/wildcard/email.xsd50
80 files changed, 4219 insertions, 0 deletions
diff --git a/xsd-examples/cxx/parser/.gitignore b/xsd-examples/cxx/parser/.gitignore
new file mode 100644
index 0000000..5a7b950
--- /dev/null
+++ b/xsd-examples/cxx/parser/.gitignore
@@ -0,0 +1 @@
+*-pskel.?xx
diff --git a/xsd-examples/cxx/parser/README b/xsd-examples/cxx/parser/README
new file mode 100644
index 0000000..01906c7
--- /dev/null
+++ b/xsd-examples/cxx/parser/README
@@ -0,0 +1,45 @@
+This directory contains a number of examples that show how to use
+the C++/Parser mapping. The following list gives an overview of
+each example. See the README files in example directories for
+more information on each example.
+
+hello
+ A simple "Hello, world!" example that shows how to parse XML
+ documents.
+
+generated
+ Shows how to use the sample implementation and test driver
+ generation feature. This example does not have any hand-written
+ C++ code; everything is generated by the XSD compiler.
+
+library
+ Shows how to handle more complex data structures and construct
+ a custom in-memory object model.
+
+mixin
+ Shows how to reuse implementations of base parsers in derived
+ parsers using the mixin C++ idiom.
+
+wildcard
+ Shows how to parse the XML data matched by XML Schema wildcards
+ (any and anyAttribute).
+
+multiroot
+ Shows how to handle XML vocabularies with multiple root elements.
+
+polymorphism
+ Shows how to use XML Schema polymorphism features such as the
+ xsi:type attribute and substitution groups.
+
+polyroot
+ Shows how to handle the xsi:type attribute when it is used on root
+ elements.
+
+performance
+ Measures the performance of XML parsing. This example also shows how
+ to structure your code to achieve the maximum performance for this
+ operation.
+
+mixed
+ Shows how to handle raw, "type-less content" such as mixed content
+ models, anyType/anySimpleType, and any/anyAttribute. \ No newline at end of file
diff --git a/xsd-examples/cxx/parser/buildfile b/xsd-examples/cxx/parser/buildfile
new file mode 100644
index 0000000..fbbd35c
--- /dev/null
+++ b/xsd-examples/cxx/parser/buildfile
@@ -0,0 +1,4 @@
+# file : cxx/parser/buildfile
+# license : not copyrighted - public domain
+
+./: */ doc{README}
diff --git a/xsd-examples/cxx/parser/generated/.gitignore b/xsd-examples/cxx/parser/generated/.gitignore
new file mode 100644
index 0000000..a67418e
--- /dev/null
+++ b/xsd-examples/cxx/parser/generated/.gitignore
@@ -0,0 +1,2 @@
+library-pimpl.?xx
+library-driver.?xx
diff --git a/xsd-examples/cxx/parser/generated/README b/xsd-examples/cxx/parser/generated/README
new file mode 100644
index 0000000..ca56974
--- /dev/null
+++ b/xsd-examples/cxx/parser/generated/README
@@ -0,0 +1,32 @@
+This example shows how to use the sample implementation and test
+driver generation feature of the C++/Parser mapping. This example
+does not have any hand-written C++ code; everything is generated
+by the XSD compiler.
+
+The example consists of the following files:
+
+library.xsd
+ XML Schema which describes a library of books.
+
+library.xml
+ Sample XML instance document.
+
+library-pskel.hxx
+library-pskel.cxx
+ Parser skeletons generated by XSD from library.xsd.
+
+library-pimpl.hxx
+library-pimpl.cxx
+ Sample parser implementations that print the XML data to STDOUT.
+ These are generated by XSD from library.xsd with the
+ --generate-print-impl option.
+
+library-driver.cxx
+ Sample driver for the example. It is generated by XSD from
+ library.xsd with the --generate-test-driver option.
+
+
+To run the example on the sample XML instance document simply
+execute:
+
+$ ./library-driver library.xml
diff --git a/xsd-examples/cxx/parser/generated/buildfile b/xsd-examples/cxx/parser/generated/buildfile
new file mode 100644
index 0000000..5e4adac
--- /dev/null
+++ b/xsd-examples/cxx/parser/generated/buildfile
@@ -0,0 +1,32 @@
+# file : cxx/parser/generated/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 ixx cxx}{library-pskel} \
+ {hxx cxx}{library-pimpl} \
+ { cxx}{library-driver} \
+ $libs
+
+exe{driver}: xml{library}: test.input = true
+
+<{hxx ixx cxx}{library-pskel} \
+ {hxx cxx}{library-pimpl} \
+ { cxx}{library-driver}>: xsd{library} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-parser --std c++11 \
+ --generate-inline \
+ --skel-file-suffix -pskel \
+ --generate-print-impl \
+ --generate-test-driver \
+ --force-overwrite \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
diff --git a/xsd-examples/cxx/parser/generated/library.xml b/xsd-examples/cxx/parser/generated/library.xml
new file mode 100644
index 0000000..1c84b9b
--- /dev/null
+++ b/xsd-examples/cxx/parser/generated/library.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/library/library.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<lib:catalog xmlns:lib="http://www.codesynthesis.com/library"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/library library.xsd">
+
+ <book id="MM" available="false">
+ <isbn>0679760806</isbn>
+ <title>The Master and Margarita</title>
+ <genre>fiction</genre>
+
+ <author recommends="WP">
+ <name>Mikhail Bulgakov</name>
+ <born>1891-05-15</born>
+ <died>1940-03-10</died>
+ </author>
+ </book>
+
+
+ <book id="WP" available="true" >
+ <isbn>0679600841</isbn>
+ <title>War and Peace</title>
+ <genre>history</genre>
+
+ <author recommends="CP">
+ <name>Leo Tolstoy</name>
+ <born>1828-09-09</born>
+ <died>1910-11-20</died>
+ </author>
+ </book>
+
+
+ <book id="CP" available="false">
+ <isbn>0679420290</isbn>
+ <title>Crime and Punishment</title>
+ <genre>philosophy</genre>
+
+ <author>
+ <name>Fyodor Dostoevsky</name>
+ <born>1821-11-11</born>
+ <died>1881-02-09</died>
+ </author>
+ </book>
+
+</lib:catalog>
diff --git a/xsd-examples/cxx/parser/generated/library.xsd b/xsd-examples/cxx/parser/generated/library.xsd
new file mode 100644
index 0000000..4d64a48
--- /dev/null
+++ b/xsd-examples/cxx/parser/generated/library.xsd
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/library/library.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:lib="http://www.codesynthesis.com/library"
+ targetNamespace="http://www.codesynthesis.com/library">
+
+ <xsd:simpleType name="isbn">
+ <xsd:restriction base="xsd:unsignedInt"/>
+ </xsd:simpleType>
+
+
+ <xsd:complexType name="title">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="lang" type="xsd:string"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+
+ <xsd:simpleType name="genre">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="romance"/>
+ <xsd:enumeration value="fiction"/>
+ <xsd:enumeration value="horror"/>
+ <xsd:enumeration value="history"/>
+ <xsd:enumeration value="philosophy"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="born" type="xsd:string"/>
+ <xsd:element name="died" type="xsd:string" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <xsd:complexType name="author">
+ <xsd:complexContent>
+ <xsd:extension base="lib:person">
+ <xsd:attribute name="recommends" type="xsd:IDREF"/> <!-- Book -->
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+
+ <xsd:complexType name="book">
+ <xsd:sequence>
+ <xsd:element name="isbn" type="lib:isbn"/>
+ <xsd:element name="title" type="lib:title"/>
+ <xsd:element name="genre" type="lib:genre"/>
+ <xsd:element name="author" type="lib:author" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="available" type="xsd:boolean" use="required"/>
+ <xsd:attribute name="id" type="xsd:ID" use="required"/>
+ </xsd:complexType>
+
+
+ <xsd:complexType name="catalog">
+ <xsd:sequence>
+ <xsd:element name="book" type="lib:book" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <xsd:element name="catalog" type="lib:catalog"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/parser/hello/README b/xsd-examples/cxx/parser/hello/README
new file mode 100644
index 0000000..97449de
--- /dev/null
+++ b/xsd-examples/cxx/parser/hello/README
@@ -0,0 +1,28 @@
+This is a "Hello, world!" example that shows how to use the
+C++/Parser mapping to parse XML instance documents.
+
+The example consists of the following files:
+
+hello.xsd
+ XML Schema which describes "hello" instance documents.
+
+hello.xml
+ Sample XML instance document.
+
+hello-pskel.hxx
+hello-pskel.cxx
+ Parser skeletons generated by XSD from hello.xsd.
+
+driver.cxx
+ A parser implementation and a driver for the example. The
+ parser implementation simply prints the data to STDERR.
+ The driver first constructs a parser instance from the
+ parser implementation mentioned above and a couple of
+ predefined parsers for the XML Schema built-in types.
+ In then invokes this parser instance to parse the input
+ file.
+
+To run the example on the sample XML instance document simply
+execute:
+
+$ ./driver hello.xml
diff --git a/xsd-examples/cxx/parser/hello/buildfile b/xsd-examples/cxx/parser/hello/buildfile
new file mode 100644
index 0000000..2df4a7f
--- /dev/null
+++ b/xsd-examples/cxx/parser/hello/buildfile
@@ -0,0 +1,24 @@
+# file : cxx/parser/hello/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}{* -hello-pskel} {hxx ixx cxx}{hello-pskel} $libs
+
+exe{driver}: xml{hello}: test.input = true
+
+<{hxx ixx cxx}{hello-pskel}>: xsd{hello} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-parser --std c++11 \
+ --generate-inline \
+ --skel-file-suffix -pskel \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
diff --git a/xsd-examples/cxx/parser/hello/driver.cxx b/xsd-examples/cxx/parser/hello/driver.cxx
new file mode 100644
index 0000000..024d2fc
--- /dev/null
+++ b/xsd-examples/cxx/parser/hello/driver.cxx
@@ -0,0 +1,67 @@
+// file : cxx/parser/hello/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <string>
+#include <iostream>
+
+#include "hello-pskel.hxx"
+
+using namespace std;
+
+struct hello_pimpl: hello_pskel
+{
+ virtual void
+ greeting (const string& greeting)
+ {
+ greeting_ = greeting;
+ }
+
+ virtual void
+ name (const string& name)
+ {
+ cout << greeting_ << ", " << name << "!" << endl;
+ }
+
+private:
+ string greeting_;
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " hello.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ // Construct the parser.
+ //
+ xml_schema::string_pimpl string_p;
+ hello_pimpl hello_p;
+
+ hello_p.greeting_parser (string_p);
+ hello_p.name_parser (string_p);
+
+ // Parse the XML instance document. The second argument to the
+ // document's constructor is the document's root element name.
+ //
+ xml_schema::document doc_p (hello_p, "hello");
+
+ hello_p.pre ();
+ doc_p.parse (argv[1]);
+ hello_p.post_hello ();
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/parser/hello/hello.xml b/xsd-examples/cxx/parser/hello/hello.xml
new file mode 100644
index 0000000..1f5adad
--- /dev/null
+++ b/xsd-examples/cxx/parser/hello/hello.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/hello/hello.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="hello.xsd">
+
+ <greeting>Hello</greeting>
+
+ <name>sun</name>
+ <name>moon</name>
+ <name>world</name>
+
+</hello>
diff --git a/xsd-examples/cxx/parser/hello/hello.xsd b/xsd-examples/cxx/parser/hello/hello.xsd
new file mode 100644
index 0000000..81907d6
--- /dev/null
+++ b/xsd-examples/cxx/parser/hello/hello.xsd
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/hello/hello.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="hello">
+ <xsd:sequence>
+ <xsd:element name="greeting" type="xsd:string"/>
+ <xsd:element name="name" type="xsd:string" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="hello" type="hello"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/parser/library/README b/xsd-examples/cxx/parser/library/README
new file mode 100644
index 0000000..3f515f6
--- /dev/null
+++ b/xsd-examples/cxx/parser/library/README
@@ -0,0 +1,44 @@
+This example shows how to use the C++/Parser mapping to construct
+a custom in-memory object model from XML instance documents.
+
+The example consists of the following files:
+
+library.xsd
+ XML Schema which describes a library of books.
+
+library.xml
+ Sample XML instance document.
+
+library.hxx
+ Types that describe a library of books in C++. These are
+ hand-written.
+
+library.map
+ Type map. It maps XML Schema types defined in library.xsd
+ to the C++ types defined in library.hxx.
+
+library-pskel.hxx
+library-pskel.ixx
+library-pskel.cxx
+ Parser skeletons generated by XSD from library.xsd and
+ library.map.
+
+library-pimpl.hxx
+library-pimpl.cxx
+ Parser implementations that construct the custom in-memory
+ object model from an XML instance using the types from
+ library.hxx. These are hand-written implementations of
+ the parser skeletons defined in library-pskel.hxx.
+
+driver.cxx
+ Driver for the example. It first constructs a parser
+ instance from all the individual parsers found in
+ library-pimpl.hxx. In then invokes this parser instance
+ to parse the input file and produce the in-memory
+ object model. Finally, it prints the contents of the
+ in-memory object model to STDERR.
+
+To run the example on the sample XML instance document simply
+execute:
+
+$ ./driver library.xml
diff --git a/xsd-examples/cxx/parser/library/buildfile b/xsd-examples/cxx/parser/library/buildfile
new file mode 100644
index 0000000..40810b3
--- /dev/null
+++ b/xsd-examples/cxx/parser/library/buildfile
@@ -0,0 +1,25 @@
+# file : cxx/parser/library/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}{* -library-pskel} {hxx ixx cxx}{library-pskel} $libs
+
+exe{driver}: xml{library}: test.input = true
+
+<{hxx ixx cxx}{library-pskel}>: xsd{library} map{library} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-parser --std c++11 \
+ --generate-inline \
+ --skel-file-suffix -pskel \
+ --type-map $path($<[1]) \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
diff --git a/xsd-examples/cxx/parser/library/driver.cxx b/xsd-examples/cxx/parser/library/driver.cxx
new file mode 100644
index 0000000..d718e53
--- /dev/null
+++ b/xsd-examples/cxx/parser/library/driver.cxx
@@ -0,0 +1,109 @@
+// file : cxx/parser/library/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <iostream>
+
+#include "library.hxx"
+#include "library-pimpl.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " library.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace library;
+
+
+ // Construct the parser.
+ //
+ xml_schema::id_pimpl id_p;
+ xml_schema::idref_pimpl idref_p;
+ xml_schema::string_pimpl string_p;
+ xml_schema::boolean_pimpl boolean_p;
+
+ isbn_pimpl isbn_p;
+
+ title_pimpl title_p;
+ title_p.lang_parser (string_p);
+
+ genre_pimpl genre_p;
+
+ author_pimpl author_p;
+ author_p.parsers (string_p, // name
+ string_p, // born
+ string_p, // died
+ idref_p); // recommends
+
+ book_pimpl book_p;
+ book_p.parsers (isbn_p, // isbn
+ title_p, // title
+ genre_p, // genre
+ author_p, // author
+ boolean_p, // available
+ id_p); // id
+
+ catalog_pimpl catalog_p;
+ catalog_p.book_parser (book_p);
+
+
+ // Parse the XML instance document.
+ //
+ xml_schema::document doc_p (
+ catalog_p,
+ "http://www.codesynthesis.com/library", // root element namespace
+ "catalog"); // root element name
+
+ catalog_p.pre ();
+ doc_p.parse (argv[1]);
+ catalog c (catalog_p.post_catalog ());
+
+
+ // Let's print what we've got.
+ //
+ for (catalog::const_iterator bi (c.begin ()); bi != c.end (); ++bi)
+ {
+ cerr << endl
+ << "ID : " << bi->id () << endl
+ << "ISBN : " << bi->isbn () << endl
+ << "Title : " << bi->title () << endl
+ << "Genre : " << bi->genre () << endl;
+
+ for (book::authors::const_iterator ai (bi->author ().begin ());
+ ai != bi->author ().end ();
+ ++ai)
+ {
+ cerr << "Author : " << ai->name () << endl;
+ cerr << " Born : " << ai->born () << endl;
+
+ if (!ai->died ().empty ())
+ cerr << " Died : " << ai->died () << endl;
+
+ if (!ai->recommends ().empty ())
+ {
+ cerr << " Recommends : " << ai->recommends () << endl;
+ }
+ }
+
+ cerr << "Available : " << std::boolalpha << bi->available () << endl;
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/parser/library/library-pimpl.cxx b/xsd-examples/cxx/parser/library/library-pimpl.cxx
new file mode 100644
index 0000000..852b90d
--- /dev/null
+++ b/xsd-examples/cxx/parser/library/library-pimpl.cxx
@@ -0,0 +1,183 @@
+// file : cxx/parser/library/library-pimpl.cxx
+// copyright : not copyrighted - public domain
+
+#include "library-pimpl.hxx"
+
+namespace library
+{
+ // isbn_impl
+ //
+ isbn isbn_pimpl::
+ post_isbn ()
+ {
+ return post_unsigned_int ();
+ }
+
+ // title_pimpl
+ //
+ void title_pimpl::
+ _pre ()
+ {
+ title_.lang ("");
+ }
+
+ void title_pimpl::
+ lang (const std::string& lang)
+ {
+ title_.lang (lang);
+ }
+
+ title title_pimpl::
+ post_title ()
+ {
+ title_.assign (post_string ());
+ return title_;
+ }
+
+ // genre_pimpl
+ //
+ genre genre_pimpl::
+ post_genre ()
+ {
+ genre r (romance);
+ std::string v (post_string ());
+
+ if (v == "romance") r = romance; else
+ if (v == "fiction") r = fiction; else
+ if (v == "horror") r = horror; else
+ if (v == "history") r = history; else
+ if (v == "philosophy") r = philosophy;
+
+ return r;
+ }
+
+ // person_pimpl
+ //
+ void person_pimpl::
+ _pre ()
+ {
+ person_.died ("");
+ }
+
+ void person_pimpl::
+ name (const std::string& name)
+ {
+ person_.name (name);
+ }
+
+ void person_pimpl::
+ born (const std::string& born)
+ {
+ person_.born (born);
+ }
+
+ void person_pimpl::
+ died (const std::string& died)
+ {
+ person_.died (died);
+ }
+
+ person person_pimpl::
+ post_person ()
+ {
+ return person_;
+ }
+
+ // author_pimpl
+ //
+ void author_pimpl::
+ _pre ()
+ {
+ person_pimpl::_pre ();
+ author_.recommends ("");
+ }
+
+ void author_pimpl::
+ recommends (const std::string& recommends)
+ {
+ author_.recommends (recommends);
+ }
+
+ author author_pimpl::
+ post_author ()
+ {
+ person p (post_person ());
+
+ author_.name (p.name ());
+ author_.born (p.born ());
+ author_.died (p.died ());
+
+ return author_;
+ }
+
+ // book_pimpl
+ //
+ void book_pimpl::
+ _pre ()
+ {
+ book_.author ().clear ();
+ }
+
+ void book_pimpl::
+ isbn (library::isbn isbn)
+ {
+ book_.isbn (isbn);
+ }
+
+ void book_pimpl::
+ title (const library::title& title)
+ {
+ book_.title (title);
+ }
+
+ void book_pimpl::
+ genre (library::genre genre)
+ {
+ book_.genre (genre);
+ }
+
+ void book_pimpl::
+ author (const library::author& author)
+ {
+ book_.author ().push_back (author);
+ }
+
+ void book_pimpl::
+ available (bool available)
+ {
+ book_.available (available);
+ }
+
+ void book_pimpl::
+ id (const std::string& id)
+ {
+ book_.id (id);
+ }
+
+ book book_pimpl::
+ post_book ()
+ {
+ return book_;
+ }
+
+ // catalog_pimpl
+ //
+ void catalog_pimpl::
+ _pre ()
+ {
+ catalog_.clear ();
+ }
+
+ void catalog_pimpl::
+ book (const library::book& book)
+ {
+ catalog_.push_back (book);
+ }
+
+ catalog catalog_pimpl::
+ post_catalog ()
+ {
+ return catalog_;
+ }
+}
+
diff --git a/xsd-examples/cxx/parser/library/library-pimpl.hxx b/xsd-examples/cxx/parser/library/library-pimpl.hxx
new file mode 100644
index 0000000..fb8ba24
--- /dev/null
+++ b/xsd-examples/cxx/parser/library/library-pimpl.hxx
@@ -0,0 +1,135 @@
+// file : cxx/parser/library/library-pimpl.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef LIBRARY_PIMPL_HXX
+#define LIBRARY_PIMPL_HXX
+
+#include "library.hxx"
+#include "library-pskel.hxx"
+
+namespace library
+{
+ //
+ //
+ struct isbn_pimpl: isbn_pskel, xml_schema::unsigned_int_pimpl
+ {
+ virtual isbn
+ post_isbn ();
+ };
+
+ //
+ //
+ struct title_pimpl: title_pskel, xml_schema::string_pimpl
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ lang (const std::string&);
+
+ virtual title
+ post_title ();
+
+ private:
+ title title_;
+ };
+
+ //
+ //
+ struct genre_pimpl: genre_pskel, xml_schema::string_pimpl
+ {
+ virtual genre
+ post_genre ();
+ };
+
+ //
+ //
+ struct person_pimpl: virtual person_pskel
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ name (const std::string&);
+
+ virtual void
+ born (const std::string&);
+
+ virtual void
+ died (const std::string&);
+
+ virtual person
+ post_person ();
+
+ private:
+ person person_;
+ };
+
+ //
+ //
+ struct author_pimpl: author_pskel, person_pimpl
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ recommends (const std::string&);
+
+ virtual author
+ post_author ();
+
+ private:
+ author author_;
+ };
+
+ //
+ //
+ struct book_pimpl: book_pskel
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ isbn (library::isbn);
+
+ virtual void
+ title (const library::title&);
+
+ virtual void
+ genre (library::genre);
+
+ virtual void
+ author (const library::author&);
+
+ virtual void
+ available (bool);
+
+ virtual void
+ id (const std::string&);
+
+ virtual book
+ post_book ();
+
+ private:
+ book book_;
+ };
+
+ //
+ //
+ struct catalog_pimpl: catalog_pskel
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ book (const library::book&);
+
+ virtual catalog
+ post_catalog ();
+
+ private:
+ catalog catalog_;
+ };
+}
+
+#endif // LIBRARY_PIMPL_HXX
diff --git a/xsd-examples/cxx/parser/library/library.hxx b/xsd-examples/cxx/parser/library/library.hxx
new file mode 100644
index 0000000..844e474
--- /dev/null
+++ b/xsd-examples/cxx/parser/library/library.hxx
@@ -0,0 +1,241 @@
+// file : cxx/parser/library/library.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef LIBRARY_HXX
+#define LIBRARY_HXX
+
+#include <string>
+#include <vector>
+
+namespace library
+{
+ //
+ //
+ typedef unsigned int isbn;
+
+
+ //
+ //
+ struct title: std::string
+ {
+ // lang
+ //
+ const std::string&
+ lang () const
+ {
+ return lang_;
+ }
+
+ void
+ lang (const std::string& lang)
+ {
+ lang_ = lang;
+ }
+
+ private:
+ std::string lang_;
+ };
+
+
+ //
+ //
+ enum genre
+ {
+ romance,
+ fiction,
+ horror,
+ history,
+ philosophy
+ };
+
+
+ //
+ //
+ struct person
+ {
+ // name
+ //
+ const std::string&
+ name () const
+ {
+ return name_;
+ }
+
+ void
+ name (const std::string& name)
+ {
+ name_ = name;
+ }
+
+ // born
+ //
+ const std::string&
+ born () const
+ {
+ return born_;
+ }
+
+ void
+ born (const std::string& born)
+ {
+ born_ = born;
+ }
+
+
+ // died
+ //
+ const std::string&
+ died () const
+ {
+ return died_;
+ }
+
+ void
+ died (const std::string& died)
+ {
+ died_ = died;
+ }
+
+ private:
+ std::string name_;
+ std::string born_;
+ std::string died_;
+ };
+
+
+ //
+ //
+ struct author: person
+ {
+ // recommends
+ //
+ const std::string&
+ recommends () const
+ {
+ return recommends_;
+ }
+
+ void
+ recommends (const std::string& recommends)
+ {
+ recommends_ = recommends;
+ }
+
+ private:
+ std::string recommends_;
+ };
+
+
+ //
+ //
+ struct book
+ {
+ // isbn
+ //
+ library::isbn
+ isbn () const
+ {
+ return isbn_;
+ }
+
+ void
+ isbn (const library::isbn& isbn)
+ {
+ isbn_ = isbn;
+ }
+
+
+ // title
+ //
+ library::title
+ title () const
+ {
+ return title_;
+ }
+
+ void
+ title (const library::title& title)
+ {
+ title_ = title;
+ }
+
+
+ // genre
+ //
+ library::genre
+ genre () const
+ {
+ return genre_;
+ }
+
+ void
+ genre (const library::genre& genre)
+ {
+ genre_ = genre;
+ }
+
+
+ // author
+ //
+ typedef std::vector<library::author> authors;
+
+ const authors&
+ author () const
+ {
+ return author_;
+ }
+
+ authors&
+ author ()
+ {
+ return author_;
+ }
+
+
+ // available
+ //
+ bool
+ available () const
+ {
+ return available_;
+ }
+
+ void
+ available (bool available)
+ {
+ available_ = available;
+ }
+
+
+ // id
+ //
+ const std::string&
+ id () const
+ {
+ return id_;
+ }
+
+ void
+ id (const std::string& id)
+ {
+ id_ = id;
+ }
+
+ private:
+ library::isbn isbn_;
+ library::title title_;
+ library::genre genre_;
+
+ authors author_;
+
+ bool available_;
+ std::string id_;
+ };
+
+
+ //
+ //
+ typedef std::vector<book> catalog;
+}
+
+#endif // LIBRARY_HXX
diff --git a/xsd-examples/cxx/parser/library/library.map b/xsd-examples/cxx/parser/library/library.map
new file mode 100644
index 0000000..4bca410
--- /dev/null
+++ b/xsd-examples/cxx/parser/library/library.map
@@ -0,0 +1,15 @@
+# file : cxx/parser/library/library.map
+# copyright : not copyrighted - public domain
+
+namespace http://www.codesynthesis.com/library ::library
+{
+ include "library.hxx";
+
+ isbn isbn isbn;
+ title title;
+ genre genre genre;
+ person person;
+ author author;
+ book book;
+ catalog catalog;
+}
diff --git a/xsd-examples/cxx/parser/library/library.xml b/xsd-examples/cxx/parser/library/library.xml
new file mode 100644
index 0000000..1c84b9b
--- /dev/null
+++ b/xsd-examples/cxx/parser/library/library.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/library/library.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<lib:catalog xmlns:lib="http://www.codesynthesis.com/library"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/library library.xsd">
+
+ <book id="MM" available="false">
+ <isbn>0679760806</isbn>
+ <title>The Master and Margarita</title>
+ <genre>fiction</genre>
+
+ <author recommends="WP">
+ <name>Mikhail Bulgakov</name>
+ <born>1891-05-15</born>
+ <died>1940-03-10</died>
+ </author>
+ </book>
+
+
+ <book id="WP" available="true" >
+ <isbn>0679600841</isbn>
+ <title>War and Peace</title>
+ <genre>history</genre>
+
+ <author recommends="CP">
+ <name>Leo Tolstoy</name>
+ <born>1828-09-09</born>
+ <died>1910-11-20</died>
+ </author>
+ </book>
+
+
+ <book id="CP" available="false">
+ <isbn>0679420290</isbn>
+ <title>Crime and Punishment</title>
+ <genre>philosophy</genre>
+
+ <author>
+ <name>Fyodor Dostoevsky</name>
+ <born>1821-11-11</born>
+ <died>1881-02-09</died>
+ </author>
+ </book>
+
+</lib:catalog>
diff --git a/xsd-examples/cxx/parser/library/library.xsd b/xsd-examples/cxx/parser/library/library.xsd
new file mode 100644
index 0000000..4d64a48
--- /dev/null
+++ b/xsd-examples/cxx/parser/library/library.xsd
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/library/library.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:lib="http://www.codesynthesis.com/library"
+ targetNamespace="http://www.codesynthesis.com/library">
+
+ <xsd:simpleType name="isbn">
+ <xsd:restriction base="xsd:unsignedInt"/>
+ </xsd:simpleType>
+
+
+ <xsd:complexType name="title">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="lang" type="xsd:string"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+
+ <xsd:simpleType name="genre">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="romance"/>
+ <xsd:enumeration value="fiction"/>
+ <xsd:enumeration value="horror"/>
+ <xsd:enumeration value="history"/>
+ <xsd:enumeration value="philosophy"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="born" type="xsd:string"/>
+ <xsd:element name="died" type="xsd:string" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <xsd:complexType name="author">
+ <xsd:complexContent>
+ <xsd:extension base="lib:person">
+ <xsd:attribute name="recommends" type="xsd:IDREF"/> <!-- Book -->
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+
+ <xsd:complexType name="book">
+ <xsd:sequence>
+ <xsd:element name="isbn" type="lib:isbn"/>
+ <xsd:element name="title" type="lib:title"/>
+ <xsd:element name="genre" type="lib:genre"/>
+ <xsd:element name="author" type="lib:author" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="available" type="xsd:boolean" use="required"/>
+ <xsd:attribute name="id" type="xsd:ID" use="required"/>
+ </xsd:complexType>
+
+
+ <xsd:complexType name="catalog">
+ <xsd:sequence>
+ <xsd:element name="book" type="lib:book" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <xsd:element name="catalog" type="lib:catalog"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/parser/mixed/README b/xsd-examples/cxx/parser/mixed/README
new file mode 100644
index 0000000..23ace6f
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixed/README
@@ -0,0 +1,49 @@
+This example shows how to handle raw, "type-less content" such as
+mixed content models, anyType/anySimpleType, and any/anyAttribute
+in the C++/Parser mapping.
+
+In this example we use mixed content model to describe text
+with embedded links, e.g.,
+
+ This paragraph talks about <a href="uri">time</a>.
+
+The example transforms such text into plain text with
+references, e.g.,
+
+ This paragraph talks about time[0].
+
+ [0] uri
+
+The example consists of the following files:
+
+text.xsd
+ XML Schema which describes "text with links" instance
+ documents.
+
+text.xml
+ Sample XML instance document.
+
+anchor.hxx
+ Anchor type that captures the information about a link.
+
+text.map
+ Type map. It maps XML Schema anchor types defined in
+ text.xsd to C++ anchor class defined in anchor.hxx.
+
+text-pskel.hxx
+text-pskel.cxx
+ Parser skeletons generated by XSD from text.xsd and
+ text.map.
+
+driver.cxx
+ A parser implementation and a driver for the example. The
+ parser implementation prints the transformed text to STDOUT.
+ The driver first constructs a parser instance from the parser
+ implementation mentioned above and a couple of predefined
+ parsers for the XML Schema built-in types. In then invokes
+ this parser instance to parse the input file.
+
+To run the example on the sample XML instance document simply
+execute:
+
+$ ./driver text.xml
diff --git a/xsd-examples/cxx/parser/mixed/anchor.hxx b/xsd-examples/cxx/parser/mixed/anchor.hxx
new file mode 100644
index 0000000..6cc6cd4
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixed/anchor.hxx
@@ -0,0 +1,33 @@
+// file : cxx/parser/mixed/anchor.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef ANCHOR_HXX
+#define ANCHOR_HXX
+
+#include <string>
+
+struct anchor
+{
+ anchor (const std::string& text, const std::string& uri)
+ : uri_ (uri), text_ (text)
+ {
+ }
+
+ const std::string&
+ text () const
+ {
+ return text_;
+ }
+
+ const std::string&
+ uri () const
+ {
+ return uri_;
+ }
+
+private:
+ std::string uri_;
+ std::string text_;
+};
+
+#endif // ANCHOR_HXX
diff --git a/xsd-examples/cxx/parser/mixed/buildfile b/xsd-examples/cxx/parser/mixed/buildfile
new file mode 100644
index 0000000..0079444
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixed/buildfile
@@ -0,0 +1,25 @@
+# file : cxx/parser/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}{* -text-pskel} {hxx ixx cxx}{text-pskel} $libs
+
+exe{driver}: xml{text}: test.input = true
+
+<{hxx ixx cxx}{text-pskel}>: xsd{text} map{text} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-parser --std c++11 \
+ --generate-inline \
+ --skel-file-suffix -pskel \
+ --type-map $path($<[1]) \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
diff --git a/xsd-examples/cxx/parser/mixed/driver.cxx b/xsd-examples/cxx/parser/mixed/driver.cxx
new file mode 100644
index 0000000..c00bfd7
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixed/driver.cxx
@@ -0,0 +1,100 @@
+// file : cxx/parser/mixed/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <string>
+#include <vector>
+#include <iostream>
+
+#include "anchor.hxx"
+#include "text-pskel.hxx"
+
+using namespace std;
+
+struct anchor_pimpl: anchor_pskel, xml_schema::string_pimpl
+{
+ virtual void
+ href (const std::string& uri)
+ {
+ uri_ = uri;
+ }
+
+ virtual anchor
+ post_anchor ()
+ {
+ return anchor (post_string (), uri_);
+ }
+
+private:
+ std::string uri_;
+};
+
+
+struct text_pimpl: text_pskel
+{
+ virtual void
+ a (const anchor& a)
+ {
+ cout << a.text () << "[" << anchors_.size () << "]";
+ anchors_.push_back (a);
+ }
+
+ virtual void
+ _any_characters (const xml_schema::ro_string& s)
+ {
+ cout << s;
+ }
+
+ virtual void
+ post_text ()
+ {
+ for (anchors::const_iterator i (anchors_.begin ());
+ i != anchors_.end ();
+ ++i)
+ {
+ cout << "[" << i - anchors_.begin () << "] " << i->uri () << endl;
+ }
+ }
+
+private:
+ typedef vector<anchor> anchors;
+ anchors anchors_;
+};
+
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " text.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ // Construct the parser.
+ //
+ xml_schema::string_pimpl string_p;
+ anchor_pimpl anchor_p;
+ text_pimpl text_p;
+
+ anchor_p.href_parser (string_p);
+ text_p.a_parser (anchor_p);
+
+ xml_schema::document doc_p (text_p, "text");
+
+ text_p.pre ();
+ doc_p.parse (argv[1]);
+ text_p.post_text ();
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/parser/mixed/text.map b/xsd-examples/cxx/parser/mixed/text.map
new file mode 100644
index 0000000..0daa79b
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixed/text.map
@@ -0,0 +1,6 @@
+# file : cxx/parser/mixed/text.map
+# copyright : not copyrighted - public domain
+
+include "anchor.hxx";
+
+anchor ::anchor;
diff --git a/xsd-examples/cxx/parser/mixed/text.xml b/xsd-examples/cxx/parser/mixed/text.xml
new file mode 100644
index 0000000..1ce4eec
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixed/text.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/text/text.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<text xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="text.xsd">
+
+The first paragraph of this text talks about <a href="http://en.wikipedia.org/wiki/time">time</a>.
+
+And this paragraph talks about <a href="http://en.wikipedia.org/wiki/space">space</a>.
+
+</text>
diff --git a/xsd-examples/cxx/parser/mixed/text.xsd b/xsd-examples/cxx/parser/mixed/text.xsd
new file mode 100644
index 0000000..e9d6e39
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixed/text.xsd
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/mixed/text.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="anchor">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="href" type="xsd:string" use="required"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="text" mixed="true">
+ <xsd:sequence>
+ <xsd:element name="a" type="anchor" minOccurs="0" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="text" type="text"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/parser/mixin/README b/xsd-examples/cxx/parser/mixin/README
new file mode 100644
index 0000000..343e379
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixin/README
@@ -0,0 +1,34 @@
+This example shows how to reuse implementations of base parsers
+in derived parsers using the mixin C++ idiom.
+
+The example consists of the following files:
+
+schema.xsd
+ XML Schema which defined two data types: base and
+ derived.
+
+instance.xml
+ Sample XML instance document.
+
+types.hxx
+ C++ classes that correspond to the base and derived
+ types in schema.xsd.
+
+schema.map
+ Type map. It maps XML Schema types defined in schema.xsd
+ to C++ types defined in types.hxx.
+
+schema-pskel.hxx
+schema-pskel.cxx
+ Parser skeletons generated by XSD from schema.xsd and
+ schema.map.
+
+driver.cxx
+ Parser implementations and a driver for the example. It
+ shows how to mix the implementation of the base parser
+ into the derived parser.
+
+To run the example on the sample XML instance document simply
+execute:
+
+$ ./driver instance.xml
diff --git a/xsd-examples/cxx/parser/mixin/buildfile b/xsd-examples/cxx/parser/mixin/buildfile
new file mode 100644
index 0000000..4d4d751
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixin/buildfile
@@ -0,0 +1,25 @@
+# file : cxx/parser/mixin/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}{* -schema-pskel} {hxx ixx cxx}{schema-pskel} $libs
+
+exe{driver}: xml{instance}: test.input = true
+
+<{hxx ixx cxx}{schema-pskel}>: xsd{schema} map{schema} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-parser --std c++11 \
+ --generate-inline \
+ --skel-file-suffix -pskel \
+ --type-map $path($<[1]) \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
diff --git a/xsd-examples/cxx/parser/mixin/driver.cxx b/xsd-examples/cxx/parser/mixin/driver.cxx
new file mode 100644
index 0000000..7a5ac94
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixin/driver.cxx
@@ -0,0 +1,103 @@
+// file : cxx/parser/mixin/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory>
+#include <iostream>
+
+#include "types.hxx"
+#include "schema-pskel.hxx"
+
+using namespace std;
+
+struct base_pimpl: virtual base_pskel
+{
+ virtual void
+ pre ()
+ {
+ base_.reset (new ::base);
+ }
+
+ virtual void
+ a (bool v)
+ {
+ base_->a (v);
+ }
+
+ virtual base*
+ post_base ()
+ {
+ return base_.release ();
+ }
+
+protected:
+ unique_ptr<base> base_;
+};
+
+// Implement derived parser by mixing-in base's implementation.
+//
+struct derived_pimpl: derived_pskel, base_pimpl
+{
+ virtual void
+ pre ()
+ {
+ // Override base's pre() with the new implementation that
+ // instantiates derived instead of base.
+ //
+ base_.reset (new ::derived);
+ }
+
+ virtual void
+ b (int v)
+ {
+ // We could also store a pointer to derived in derived_impl to
+ // avoid casting.
+ //
+ static_cast< ::derived* > (base_.get ())->b (v);
+ }
+
+ virtual derived*
+ post_derived ()
+ {
+ return static_cast<derived*> (base_.release ());
+ }
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " instance.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ // Construct the parser.
+ //
+ xml_schema::boolean_pimpl bool_p;
+ xml_schema::int_pimpl int_p;
+ derived_pimpl derived_p;
+
+ derived_p.parsers (bool_p, int_p);
+
+ xml_schema::document doc_p (derived_p, "root");
+
+ derived_p.pre ();
+ doc_p.parse (argv[1]);
+ unique_ptr<derived> d (derived_p.post_derived ());
+
+ cerr << "a: " << boolalpha << d->a () << endl;
+ cerr << "b: " << d->b () << endl;
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/parser/mixin/instance.xml b/xsd-examples/cxx/parser/mixin/instance.xml
new file mode 100644
index 0000000..90e2757
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixin/instance.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/mixin/instance.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="schema.xsd">
+
+ <a>true</a>
+ <b>1</b>
+
+</root>
diff --git a/xsd-examples/cxx/parser/mixin/schema.map b/xsd-examples/cxx/parser/mixin/schema.map
new file mode 100644
index 0000000..a6ffa76
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixin/schema.map
@@ -0,0 +1,7 @@
+# file : cxx/parser/mixin/schema.map
+# copyright : not copyrighted - public domain
+
+include "types.hxx";
+
+base ::base*;
+derived ::derived*;
diff --git a/xsd-examples/cxx/parser/mixin/schema.xsd b/xsd-examples/cxx/parser/mixin/schema.xsd
new file mode 100644
index 0000000..891241e
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixin/schema.xsd
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/mixin/schema.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="base">
+ <xsd:sequence>
+ <xsd:element name="a" type="xsd:boolean"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="derived">
+ <xsd:complexContent>
+ <xsd:extension base="base">
+ <xsd:sequence>
+ <xsd:element name="b" type="xsd:int"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="root" type="derived"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/parser/mixin/types.hxx b/xsd-examples/cxx/parser/mixin/types.hxx
new file mode 100644
index 0000000..887b29e
--- /dev/null
+++ b/xsd-examples/cxx/parser/mixin/types.hxx
@@ -0,0 +1,43 @@
+// file : cxx/parser/mixin/types.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef TYPES_HXX
+#define TYPES_HXX
+
+struct base
+{
+ bool
+ a () const
+ {
+ return a_;
+ }
+
+ void
+ a (bool v)
+ {
+ a_ = v;
+ }
+
+private:
+ bool a_;
+};
+
+struct derived: base
+{
+ int
+ b () const
+ {
+ return b_;
+ }
+
+ void
+ b (int v)
+ {
+ b_ = v;
+ }
+
+private:
+ int b_;
+};
+
+#endif // TYPES_HXX
diff --git a/xsd-examples/cxx/parser/multiroot/README b/xsd-examples/cxx/parser/multiroot/README
new file mode 100644
index 0000000..041dfec
--- /dev/null
+++ b/xsd-examples/cxx/parser/multiroot/README
@@ -0,0 +1,51 @@
+This example shows how to handle XML vocabularies with multiple
+root elements using the C++/Parser mapping.
+
+The example consists of the following files:
+
+protocol.xsd
+ XML Schema which defines a simple bank account protocol with
+ requests such as withdraw and deposit.
+
+balance.xml
+withdraw.xml
+deposit.xml
+ Sample XML instances for the protocol requests.
+
+protocol.hxx
+ C++ types that describe the protocol requests. These are
+ hand-written.
+
+protocol.map
+ Type map. It maps XML Schema types defined in protocol.xsd
+ to the C++ types defined in protocol.hxx.
+
+protocol-pskel.hxx
+protocol-pskel.cxx
+ Parser skeletons generated by XSD from protocol.xsd and
+ protocol.map.
+
+protocol-pimpl.hxx
+protocol-pimpl.cxx
+ Parser implementations that construct the custom object
+ model from an XML instance using the types from protocol.hxx.
+ These are hand-written implementations of the parser skeletons
+ defined in protocol-pskel.hxx.
+
+driver.cxx
+ Driver for the example. It implements a custom document parser
+ that determines which request is being parsed and uses the
+ corresponding parser implementation. The document parser
+ intentionally does not support the deposit request to show
+ how to handle unknown documents. The driver first constructs
+ a parser instance from all the individual parsers found in
+ protocol-pimpl.hxx. In then invokes this parser instance to
+ parse the input file and produce the in-memory object model.
+ Finally, it prints the contents of the object model to STDERR.
+
+To run the example on the sample XML request documents simply
+execute:
+
+$ ./driver balance.xml
+$ ./driver withdraw.xml
+$ ./driver deposit.xml
diff --git a/xsd-examples/cxx/parser/multiroot/balance.xml b/xsd-examples/cxx/parser/multiroot/balance.xml
new file mode 100644
index 0000000..60a6882
--- /dev/null
+++ b/xsd-examples/cxx/parser/multiroot/balance.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/multiroot/balance.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<p:balance xmlns:p="http://www.codesynthesis.com/protocol"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/protocol protocol.xsd">
+
+ <account>123456789</account>
+
+</p:balance>
diff --git a/xsd-examples/cxx/parser/multiroot/buildfile b/xsd-examples/cxx/parser/multiroot/buildfile
new file mode 100644
index 0000000..6b0f604
--- /dev/null
+++ b/xsd-examples/cxx/parser/multiroot/buildfile
@@ -0,0 +1,24 @@
+# file : cxx/parser/multiroot/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README} xml{balance deposit withdraw}
+
+exe{driver}: {hxx cxx}{* -protocol-pskel} {hxx ixx cxx}{protocol-pskel} $libs \
+ testscript
+
+<{hxx ixx cxx}{protocol-pskel}>: xsd{protocol} map{protocol} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-parser --std c++11 \
+ --generate-inline \
+ --skel-file-suffix -pskel \
+ --type-map $path($<[1]) \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
diff --git a/xsd-examples/cxx/parser/multiroot/deposit.xml b/xsd-examples/cxx/parser/multiroot/deposit.xml
new file mode 100644
index 0000000..3d32c59
--- /dev/null
+++ b/xsd-examples/cxx/parser/multiroot/deposit.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/multiroot/deposit.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<p:deposit xmlns:p="http://www.codesynthesis.com/protocol"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/protocol protocol.xsd">
+
+ <account>123456789</account>
+ <amount>1000000</amount>
+
+</p:deposit>
diff --git a/xsd-examples/cxx/parser/multiroot/driver.cxx b/xsd-examples/cxx/parser/multiroot/driver.cxx
new file mode 100644
index 0000000..ea854b9
--- /dev/null
+++ b/xsd-examples/cxx/parser/multiroot/driver.cxx
@@ -0,0 +1,161 @@
+// file : cxx/parser/multiroot/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <iostream>
+
+#include "protocol.hxx"
+#include "protocol-pimpl.hxx"
+
+using std::cerr;
+using std::endl;
+using xml_schema::ro_string;
+
+namespace protocol
+{
+ // Customize the xml_schema::document object to handle our protocol
+ // vocabulary with multiple root elements.
+ //
+ class document: public xml_schema::document
+ {
+ public:
+ document (balance_pskel& balance_p, withdraw_pskel& withdraw_p)
+ : balance_p_ (balance_p), withdraw_p_ (withdraw_p)
+ {
+ }
+
+ request*
+ result ()
+ {
+ return result_.release ();
+ }
+
+ protected:
+ // This function is called to obtain the root element type parser.
+ // If the returned pointed is 0 then the whole document content
+ // is ignored. The type argument is used to handle polymorphic
+ // XML documents and is not used in this example (see the polyroot
+ // example for more information on this argument).
+ //
+ virtual xml_schema::parser_base*
+ start_root_element (const ro_string& ns,
+ const ro_string& name,
+ const ro_string* /* type */)
+ {
+ if (ns == "http://www.codesynthesis.com/protocol")
+ {
+ if (name == "balance")
+ {
+ balance_p_.pre ();
+
+ return &balance_p_;
+ }
+ else if (name == "withdraw")
+ {
+ balance_p_.pre ();
+
+ return &withdraw_p_;
+ }
+ }
+
+ cerr << "ignoring unknown request: " << ns << "#" << name << endl;
+
+ return 0;
+ }
+
+ // This function is called to indicate the completion of document
+ // parsing. The parser argument contains the pointer returned by
+ // start_root_element.
+ //
+ virtual void
+ end_root_element (const ro_string& /* ns */,
+ const ro_string& /* name */,
+ xml_schema::parser_base* parser)
+ {
+ // We could have handled the result directly in this function
+ // instead of storing it in the result_ variable.
+ //
+ if (parser == &balance_p_)
+ {
+ result_.reset (balance_p_.post_balance ());
+ }
+ else if (parser == &withdraw_p_)
+ {
+ result_.reset (withdraw_p_.post_withdraw ());
+ }
+ else
+ result_.reset (0);
+ }
+
+
+ private:
+ std::unique_ptr<request> result_;
+
+ balance_pskel& balance_p_;
+ withdraw_pskel& withdraw_p_;
+ };
+}
+
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " request.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace protocol;
+
+ // Construct the parser.
+ //
+ xml_schema::unsigned_int_pimpl unsigned_int_p;
+
+ balance_pimpl balance_p;
+ withdraw_pimpl withdraw_p;
+
+ balance_p.parsers (unsigned_int_p); // account
+
+ withdraw_p.parsers (unsigned_int_p, // account
+ unsigned_int_p); // amount
+
+ // Parse the XML instance document.
+ //
+ document doc_p (balance_p, withdraw_p);
+
+ // pre() and post() will be called as part of the start_root_element()
+ // and end_root_element() calls.
+ //
+ doc_p.parse (argv[1]);
+ std::unique_ptr<request> r (doc_p.result ());
+
+ // Let's print what we've got.
+ //
+ if (balance* b = dynamic_cast<balance*> (r.get ()))
+ {
+ cerr << "balance request for acc# " << b->account () << endl;
+ }
+ else if (withdraw* w = dynamic_cast<withdraw*> (r.get ()))
+ {
+ cerr << "withdrawal request for acc# " << w->account () << ", "
+ << "amount: " << w->amount () << endl;
+ }
+ else
+ {
+ cerr << "unknown request" << endl;
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/parser/multiroot/protocol-pimpl.cxx b/xsd-examples/cxx/parser/multiroot/protocol-pimpl.cxx
new file mode 100644
index 0000000..05fbd31
--- /dev/null
+++ b/xsd-examples/cxx/parser/multiroot/protocol-pimpl.cxx
@@ -0,0 +1,46 @@
+// file : cxx/parser/multiroot/protocol-pimpl.cxx
+// copyright : not copyrighted - public domain
+
+#include "protocol-pimpl.hxx"
+
+namespace protocol
+{
+ // request_pimpl
+ //
+ void request_pimpl::
+ account (unsigned int account)
+ {
+ account_ = account;
+ }
+
+ request* request_pimpl::
+ post_request ()
+ {
+ // This parser is never used directly.
+ //
+ return 0;
+ }
+
+ // balance_pimpl
+ //
+ balance* balance_pimpl::
+ post_balance ()
+ {
+ return new balance (account_);
+ }
+
+ // withdraw_pimpl
+ //
+ void withdraw_pimpl::
+ amount (unsigned int amount)
+ {
+ amount_ = amount;
+ }
+
+ withdraw* withdraw_pimpl::
+ post_withdraw ()
+ {
+ return new withdraw (account_, amount_);
+ }
+}
+
diff --git a/xsd-examples/cxx/parser/multiroot/protocol-pimpl.hxx b/xsd-examples/cxx/parser/multiroot/protocol-pimpl.hxx
new file mode 100644
index 0000000..1b53604
--- /dev/null
+++ b/xsd-examples/cxx/parser/multiroot/protocol-pimpl.hxx
@@ -0,0 +1,48 @@
+// file : cxx/parser/multiroot/protocol-pimpl.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef PROTOCOL_PIMPL_HXX
+#define PROTOCOL_PIMPL_HXX
+
+#include "protocol.hxx"
+#include "protocol-pskel.hxx"
+
+namespace protocol
+{
+ class request_pimpl: public virtual request_pskel
+ {
+ public:
+ virtual void
+ account (unsigned int);
+
+ virtual request*
+ post_request ();
+
+ protected:
+ unsigned int account_;
+ };
+
+ class balance_pimpl: public virtual balance_pskel,
+ public request_pimpl
+ {
+ public:
+ virtual balance*
+ post_balance ();
+ };
+
+ class withdraw_pimpl: public virtual withdraw_pskel,
+ public request_pimpl
+ {
+ public:
+ virtual void
+ amount (unsigned int);
+
+ virtual withdraw*
+ post_withdraw ();
+
+ private:
+ unsigned int amount_;
+ };
+}
+
+#endif // PROTOCOL_PIMPL_HXX
diff --git a/xsd-examples/cxx/parser/multiroot/protocol.hxx b/xsd-examples/cxx/parser/multiroot/protocol.hxx
new file mode 100644
index 0000000..3c1a10a
--- /dev/null
+++ b/xsd-examples/cxx/parser/multiroot/protocol.hxx
@@ -0,0 +1,61 @@
+// file : cxx/parser/multiroot/protocol.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef PROTOCOL_HXX
+#define PROTOCOL_HXX
+
+namespace protocol
+{
+ class request
+ {
+ public:
+ virtual
+ ~request ()
+ {
+ }
+
+ unsigned int
+ account () const
+ {
+ return account_;
+ }
+
+ protected:
+ request (unsigned int account)
+ : account_ (account)
+ {
+ }
+
+ private:
+ unsigned int account_;
+ };
+
+ class balance: public request
+ {
+ public:
+ balance (unsigned int account)
+ : request (account)
+ {
+ }
+ };
+
+ class withdraw: public request
+ {
+ public:
+ withdraw (unsigned int account, unsigned int amount)
+ : request (account), amount_ (amount)
+ {
+ }
+
+ unsigned int
+ amount () const
+ {
+ return amount_;
+ }
+
+ private:
+ unsigned int amount_;
+ };
+}
+
+#endif // PROTOCOL_HXX
diff --git a/xsd-examples/cxx/parser/multiroot/protocol.map b/xsd-examples/cxx/parser/multiroot/protocol.map
new file mode 100644
index 0000000..90536ea
--- /dev/null
+++ b/xsd-examples/cxx/parser/multiroot/protocol.map
@@ -0,0 +1,11 @@
+# file : cxx/parser/multiroot/protocol.map
+# copyright : not copyrighted - public domain
+
+namespace http://www.codesynthesis.com/protocol ::protocol
+{
+ include "protocol.hxx";
+
+ request request*;
+ balance balance*;
+ withdraw withdraw*;
+}
diff --git a/xsd-examples/cxx/parser/multiroot/protocol.xsd b/xsd-examples/cxx/parser/multiroot/protocol.xsd
new file mode 100644
index 0000000..a33fed2
--- /dev/null
+++ b/xsd-examples/cxx/parser/multiroot/protocol.xsd
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/multiroot/protocol.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:p="http://www.codesynthesis.com/protocol"
+ targetNamespace="http://www.codesynthesis.com/protocol">
+
+ <xsd:complexType name="request">
+ <xsd:sequence>
+ <xsd:element name="account" type="xsd:unsignedInt"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="balance">
+ <xsd:complexContent>
+ <xsd:extension base="p:request"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="withdraw">
+ <xsd:complexContent>
+ <xsd:extension base="p:request">
+ <xsd:sequence>
+ <xsd:element name="amount" type="xsd:unsignedInt"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="deposit">
+ <xsd:complexContent>
+ <xsd:extension base="p:request">
+ <xsd:sequence>
+ <xsd:element name="amount" type="xsd:unsignedInt"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="balance" type="p:balance"/>
+ <xsd:element name="withdraw" type="p:withdraw"/>
+ <xsd:element name="deposit" type="p:deposit"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/parser/multiroot/testscript b/xsd-examples/cxx/parser/multiroot/testscript
new file mode 100644
index 0000000..76329f7
--- /dev/null
+++ b/xsd-examples/cxx/parser/multiroot/testscript
@@ -0,0 +1,6 @@
+# file : cxx/parser/multiroot/testscript
+# license : not copyrighted - public domain
+
+$* $src_base/balance.xml 2>| : balance
+$* $src_base/deposit.xml 2>| : deposit
+$* $src_base/withdraw.xml 2>| : withdraw
diff --git a/xsd-examples/cxx/parser/multiroot/withdraw.xml b/xsd-examples/cxx/parser/multiroot/withdraw.xml
new file mode 100644
index 0000000..8b2efe0
--- /dev/null
+++ b/xsd-examples/cxx/parser/multiroot/withdraw.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/multiroot/withdraw.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<p:withdraw xmlns:p="http://www.codesynthesis.com/protocol"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/protocol protocol.xsd">
+
+ <account>123456789</account>
+ <amount>1000000</amount>
+
+</p:withdraw>
diff --git a/xsd-examples/cxx/parser/performance/.gitignore b/xsd-examples/cxx/parser/performance/.gitignore
new file mode 100644
index 0000000..19c9761
--- /dev/null
+++ b/xsd-examples/cxx/parser/performance/.gitignore
@@ -0,0 +1,7 @@
+driver-expat
+driver-xerces
+gen
+
+# Testscript output directory (can be symlink).
+#
+test-gen
diff --git a/xsd-examples/cxx/parser/performance/README b/xsd-examples/cxx/parser/performance/README
new file mode 100644
index 0000000..46137d0
--- /dev/null
+++ b/xsd-examples/cxx/parser/performance/README
@@ -0,0 +1,46 @@
+This example measures the performance of XML parsing in the C++/Parser
+mapping. It also shows how to structure your code to achieve the maximum
+performance for this operation.
+
+The example consists of the following files:
+
+test.xsd
+ XML Schema which describes the test vocabulary.
+
+test-50k.xml
+ Test XML document.
+
+gen.cxx
+ Program to generate a test document of desired size.
+
+time.hxx
+time.cxx
+ Class definition that represents time.
+
+test-pskel.hxx
+test-pskel.ixx
+test-pskel.cxx
+ Parser skeletons generated by the XSD compiler from test.xsd.
+
+driver.cxx
+ Driver for the example. It first parses the command line arguments
+ and reads the entire document into a memory buffer. It then creates
+ a SAX parser and pre-parses and caches the schema if validation is
+ enabled (Xerces-C++ only). Finally, it runs the performance
+ measurement loop which on each iteration parses the XML document
+ from the in-memory buffer.
+
+To run the example on a test XML document simply execute:
+
+$ ./driver test-50k.xml
+
+The -v option can be used to turn on validation in the underlying XML
+parser (only makes sense for Xerces-C++, off by default). The -i option
+can be used to specify the number of parsing iterations (1000 by default).
+For example:
+
+$ ./driver -v -i 100 test-50k.xml
+
+To generate the test document execute, for example:
+
+$ ./gen 633 test-100k.xml
diff --git a/xsd-examples/cxx/parser/performance/buildfile b/xsd-examples/cxx/parser/performance/buildfile
new file mode 100644
index 0000000..10111d6
--- /dev/null
+++ b/xsd-examples/cxx/parser/performance/buildfile
@@ -0,0 +1,57 @@
+# file : cxx/parser/performance/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+
+import libxerces = libxerces-c%lib{xerces-c}
+import libexpat = libexpat%lib{expat}
+
+./: doc{README}
+
+# exe{driver-{xerces,expat}}
+#
+for p: 'xerces' 'expat'
+{
+ # Make sure that obje{time} doesn't depend on the parser library that varies
+ # for different exe{driver-*} targets. Think of -I... options passed to the
+ # compiler while compiling time.cxx, which would vary depending on exe
+ # target time.cxx is a prerequisite of.
+ #
+ ./: exe{driver-$p}: obje{driver-$p time} \
+ {hxx ixx cxx}{test-$p-pskel} \
+ $libs $(lib$p)
+
+ exe{driver-$p}: xml{test-50k}: test.input = true
+
+ obje{driver-$p}: cxx{driver} $libs $(lib$p)
+
+ <{hxx ixx cxx}{test-$p-pskel}>: xsd{test} $xsd
+ {
+ # Note: we can't use $p in the buildscript since it will be substituted by
+ # the latest $p value.
+ #
+ parser = $p
+ }
+ {{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-parser --std c++11 \
+ --generate-inline \
+ --skel-file-suffix -$parser-pskel \
+ --xml-parser $parser \
+ --output-dir $out_base \
+ $path($<[0])
+ }}
+}
+
+obje{time}: {hxx cxx}{time}
+
+# exe{gen}
+#
+./: exe{gen}: cxx{gen} testscript{gen}
+
+# Build options.
+#
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+obje{driver-xerces}: cxx.poptions += -DXERCES_PARSER
diff --git a/xsd-examples/cxx/parser/performance/driver.cxx b/xsd-examples/cxx/parser/performance/driver.cxx
new file mode 100644
index 0000000..4ac0265
--- /dev/null
+++ b/xsd-examples/cxx/parser/performance/driver.cxx
@@ -0,0 +1,346 @@
+// file : cxx/parser/performance/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <string>
+#include <memory> // std::unique_ptr
+#include <cstddef> // std::size_t
+#include <fstream>
+#include <sstream>
+#include <iostream>
+
+#include "time.hxx"
+
+#ifdef XERCES_PARSER
+# include "test-xerces-pskel.hxx"
+
+# include <xercesc/sax2/SAX2XMLReader.hpp>
+# include <xercesc/sax2/XMLReaderFactory.hpp>
+# include <xercesc/framework/MemBufInputSource.hpp>
+# include <xercesc/validators/common/Grammar.hpp>
+# include <xercesc/util/PlatformUtils.hpp>
+# include <xercesc/util/XMLUni.hpp>
+
+# include <xsd/cxx/xml/sax/bits/error-handler-proxy.hxx>
+# include <xsd/cxx/parser/error-handler.hxx>
+#else
+# include "test-expat-pskel.hxx"
+#endif
+
+// No-op parser implementation.
+//
+namespace test
+{
+ struct enum_pimpl: enum_pskel, xml_schema::string_pimpl
+ {
+ virtual void
+ post_enum ()
+ {
+ }
+ };
+
+ struct record_pimpl: record_pskel
+ {
+ virtual void
+ int_ (unsigned int)
+ {
+ }
+
+ virtual void
+ double_ (double)
+ {
+ }
+
+ virtual void
+ name (const std::string&)
+ {
+ }
+
+ virtual void
+ string (const std::string&)
+ {
+ }
+
+ virtual void
+ choice1 (const std::string&)
+ {
+ }
+
+ virtual void
+ choice2 (const std::string&)
+ {
+ }
+
+ virtual void
+ choice3 (const std::string&)
+ {
+ }
+
+ virtual void
+ choice4 (const std::string&)
+ {
+ }
+
+ virtual void
+ apple (bool)
+ {
+ }
+
+ virtual void
+ orange (unsigned long long)
+ {
+ }
+ };
+
+ struct root_pimpl: root_pskel
+ {
+ };
+}
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc < 2)
+ {
+ cerr << "usage: " << argv[0] << " [-v] [-i <count>] test.xml" << endl
+ << "\t -v turn on validation (default is off)" << endl
+ << "\t -i number of iterations to perform (default is 1000)" << endl;
+ return 1;
+ }
+
+ bool validate (false);
+ unsigned long iter (1000);
+ const char* file (0);
+
+ // Parse command line arguments.
+ //
+ for (int i (1); i < argc; ++i)
+ {
+ string arg (argv[i]);
+
+ if (arg == "-v")
+ {
+ validate = true;
+ }
+ else if (arg == "-i")
+ {
+ if (++i == argc)
+ {
+ cerr << "argument expected for the -i option" << endl;
+ return 1;
+ }
+
+ iter = 0;
+ istringstream is (argv[i]);
+ is >> iter;
+
+ if (iter == 0)
+ {
+ cerr << "invalid argument for the -i option" << endl;
+ return 1;
+ }
+ }
+ else
+ {
+ file = argv[i];
+ break;
+ }
+ }
+
+ if (file == 0)
+ {
+ cerr << "no input file specified" << endl;
+ return 1;
+ }
+
+ try
+ {
+ // Instantiate and connect parsers.
+ //
+ xml_schema::unsigned_int_pimpl unsigned_int_p;
+ xml_schema::double_pimpl double_p;
+ xml_schema::ncname_pimpl ncname_p;
+ xml_schema::string_pimpl string_p;
+ xml_schema::boolean_pimpl boolean_p;
+ xml_schema::unsigned_long_pimpl unsigned_long_p;
+
+ test::enum_pimpl enum_p;
+ test::record_pimpl record_p;
+ test::root_pimpl root_p;
+
+ record_p.parsers (unsigned_int_p,
+ double_p,
+ ncname_p,
+ string_p,
+ string_p,
+ string_p,
+ string_p,
+ string_p,
+ enum_p,
+ boolean_p,
+ unsigned_long_p);
+
+ root_p.parsers (record_p);
+
+ // Read the fine into in-memory buffer.
+ //
+ ifstream ifs;
+ ifs.exceptions (ios_base::failbit);
+ ifs.open (file, ios::in | ios::ate);
+
+ size_t size (ifs.tellg ());
+ ifs.seekg (0, ios::beg);
+
+ char* buf = new char[size];
+ ifs.read (buf, size);
+ ifs.close ();
+
+ cerr << "document size: " << size << " bytes" << endl
+ << "iterations: " << iter << endl;
+
+ os::time time (0);
+ xml_schema::document doc (root_p, "test", "root");
+
+#ifdef _XERCES_VERSION
+
+ // Xerces-C++ as the underlying XML parser.
+ //
+ using namespace xercesc;
+
+ namespace xml = xsd::cxx::xml;
+ namespace parser = xsd::cxx::parser;
+
+ XMLPlatformUtils::Initialize ();
+
+ {
+ MemBufInputSource is (
+ reinterpret_cast<XMLByte*> (buf), size, file, false);
+ is.setCopyBufToStream (false);
+
+ unique_ptr<SAX2XMLReader> parser (XMLReaderFactory::createXMLReader ());
+
+ parser->setFeature (XMLUni::fgSAX2CoreNameSpaces, true);
+ parser->setFeature (XMLUni::fgSAX2CoreNameSpacePrefixes, true);
+ parser->setFeature (XMLUni::fgXercesValidationErrorAsFatal, true);
+
+ if (validate)
+ {
+ parser->setFeature (XMLUni::fgSAX2CoreValidation, true);
+ parser->setFeature (XMLUni::fgXercesSchema, true);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support.
+ //
+#if _XERCES_VERSION >= 30100
+ parser->setFeature (XMLUni::fgXercesHandleMultipleImports, true);
+#endif
+
+ // Initialize the schema cache. To detect schema errors we will
+ // need an error handler.
+ //
+ parser::error_handler<char> eh;
+ xml::sax::bits::error_handler_proxy<char> ehp (eh);
+ parser->setErrorHandler (&ehp);
+
+ if (!parser->loadGrammar ("test.xsd", Grammar::SchemaGrammarType, true))
+ {
+ // In Xerces-C++ grammar loading failure results in just a warning.
+ // Make it a fatal error.
+ //
+ eh.handle ("test.xsd", 0, 0,
+ parser::error_handler<char>::severity::fatal,
+ "unable to load schema");
+ }
+
+ eh.throw_if_failed ();
+ parser->setFeature (XMLUni::fgXercesUseCachedGrammarInParse, true);
+
+#if _XERCES_VERSION >= 30100
+ parser->setFeature (XMLUni::fgXercesLoadSchema, false);
+#endif
+ }
+ else
+ {
+ parser->setFeature (XMLUni::fgSAX2CoreValidation, false);
+ parser->setFeature (XMLUni::fgXercesSchema, false);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+
+ os::time start;
+
+ for (unsigned long i (0); i < iter; ++i)
+ {
+ root_p.pre ();
+ doc.parse (is, *parser);
+ root_p.post_root ();
+ }
+
+ os::time end;
+ time = end - start;
+ }
+
+ XMLPlatformUtils::Terminate ();
+
+#else
+
+ XSD_UNUSED (validate);
+
+ // Expat as the underlying XML parser.
+ //
+ XML_Parser xml_parser (XML_ParserCreateNS (0, ' '));
+ string public_id (file);
+
+ os::time start;
+
+ for (unsigned long i (0); i < iter; ++i)
+ {
+ // Using the low-level Expat-specific API to parse the memory
+ // buffer.
+ //
+ root_p.pre ();
+ doc.parse_begin (xml_parser, public_id);
+
+ XML_Parse (xml_parser, buf, size, 1);
+
+ doc.parse_end ();
+ root_p.post_root ();
+
+ XML_ParserReset (xml_parser, 0);
+ }
+
+ os::time end;
+ time = end - start;
+
+ XML_ParserFree (xml_parser);
+
+#endif
+
+ delete[] buf;
+
+ cerr << "time: " << time << " sec" << endl;
+
+ double ms (time.sec () * 1000000ULL + time.nsec () / 1000ULL);
+
+ // Calculate throughput in documents/sec.
+ //
+ double tpd ((iter / ms) * 1000000);
+ cerr << "throughput: " << tpd << " documents/sec" << endl;
+
+ // Calculate throughput in MBytes/sec.
+ //
+ double tpb (((size * iter) / ms) * 1000000/(1024*1024));
+ cerr << "throughput: " << tpb << " MBytes/sec" << endl;
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (std::ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/parser/performance/gen.cxx b/xsd-examples/cxx/parser/performance/gen.cxx
new file mode 100644
index 0000000..5c11343
--- /dev/null
+++ b/xsd-examples/cxx/parser/performance/gen.cxx
@@ -0,0 +1,79 @@
+// file : cxx/parser/performance/gen.cxx
+// copyright : not copyrighted - public domain
+
+#include <fstream>
+#include <sstream>
+#include <iostream>
+
+using namespace std;
+
+static const char* enums[] =
+{
+ "romance",
+ "fiction",
+ "horror",
+ "history",
+ "philosophy"
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 3)
+ {
+ cerr << "usage: " << argv[0] << " <count> <output-file>" << endl;
+ return 1;
+ }
+
+ unsigned long n (0);
+ istringstream is (argv[1]);
+ is >> n;
+
+ if (n == 0)
+ {
+ cerr << "record count argument should be a positive number" << endl;
+ return 1;
+ }
+
+ ofstream ofs (argv[2]);
+
+ if (!ofs.is_open ())
+ {
+ cerr << "unable to open '" << argv[2] << "' in write mode" << endl;
+ return 1;
+ }
+
+ ofs << "<t:root xmlns:t='test' " <<
+ "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " <<
+ "xsi:schemaLocation='test test.xsd'>";
+
+ unsigned short ch (1), en (0);
+
+ for (unsigned long i (0); i < n; ++i)
+ {
+ ofs << "<record orange=\"" << i << "\"";
+
+ if (i % 2 == 0)
+ ofs << " apple=\"true\"";
+
+ ofs << ">"
+ << "<int>42</int>"
+ << "<double>42345.4232</double>"
+ << "<name>name123_45</name>";
+
+ if (i % 2 == 1)
+ ofs << "<string>one two three</string>";
+
+ ofs << "<choice" << ch << ">" << ch << " choice</choice" << ch << ">"
+ << "<enum>" << enums[en] << "</enum>"
+ << "</record>";
+
+ if (++ch > 4)
+ ch = 1;
+
+ if (++en > 4)
+ en = 0;
+ }
+
+ ofs << "</t:root>";
+}
diff --git a/xsd-examples/cxx/parser/performance/gen.testscript b/xsd-examples/cxx/parser/performance/gen.testscript
new file mode 100644
index 0000000..1dc6d66
--- /dev/null
+++ b/xsd-examples/cxx/parser/performance/gen.testscript
@@ -0,0 +1,9 @@
+# file : cxx/parser/performance/gen.testscript
+# license : not copyrighted - public domain
+
+: 50k
+:
+{
+ $* 317 test-50k.xml &test-50k.xml;
+ cat test-50k.xml >>>$src_base/test-50k.xml
+}
diff --git a/xsd-examples/cxx/parser/performance/test-50k.xml b/xsd-examples/cxx/parser/performance/test-50k.xml
new file mode 100644
index 0000000..42e22f3
--- /dev/null
+++ b/xsd-examples/cxx/parser/performance/test-50k.xml
@@ -0,0 +1 @@
+<t:root xmlns:t='test' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='test test.xsd'><record orange="0" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="2" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="4" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="5"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="6" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="7"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="8" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="9"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="10" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="11"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="12" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="13"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="14" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="15"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="16" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="17"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="18" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="19"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="20" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="21"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="22" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="23"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="24" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="25"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="26" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="27"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="28" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="29"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="30" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="31"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="32" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="33"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="34" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="35"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="36" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="37"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="38" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="39"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="40" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="41"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="42" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="43"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="44" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="45"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="46" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="47"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="48" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="49"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="50" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="51"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="52" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="53"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="54" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="55"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="56" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="57"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="58" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="59"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="60" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="61"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="62" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="63"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="64" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="65"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="66" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="67"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="68" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="69"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="70" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="71"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="72" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="73"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="74" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="75"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="76" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="77"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="78" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="79"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="80" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="81"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="82" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="83"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="84" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="85"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="86" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="87"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="88" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="89"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="90" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="91"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="92" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="93"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="94" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="95"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="96" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="97"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="98" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="99"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="100" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="101"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="102" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="103"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="104" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="105"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="106" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="107"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="108" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="109"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="110" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="111"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="112" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="113"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="114" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="115"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="116" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="117"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="118" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="119"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="120" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="121"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="122" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="123"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="124" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="125"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="126" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="127"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="128" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="129"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="130" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="131"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="132" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="133"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="134" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="135"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="136" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="137"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="138" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="139"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="140" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="141"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="142" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="143"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="144" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="145"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="146" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="147"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="148" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="149"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="150" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="151"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="152" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="153"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="154" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="155"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="156" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="157"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="158" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="159"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="160" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="161"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="162" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="163"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="164" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="165"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="166" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="167"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="168" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="169"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="170" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="171"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="172" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="173"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="174" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="175"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="176" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="177"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="178" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="179"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="180" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="181"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="182" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="183"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="184" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="185"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="186" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="187"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="188" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="189"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="190" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="191"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="192" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="193"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="194" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="195"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="196" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="197"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="198" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="199"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="200" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="201"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="202" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="203"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="204" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="205"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="206" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="207"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="208" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="209"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="210" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="211"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="212" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="213"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="214" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="215"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="216" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="217"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="218" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="219"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="220" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="221"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="222" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="223"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="224" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="225"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="226" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="227"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="228" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="229"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="230" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="231"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="232" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="233"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="234" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="235"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="236" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="237"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="238" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="239"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="240" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="241"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="242" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="243"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="244" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="245"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="246" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="247"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="248" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="249"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="250" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="251"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="252" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="253"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="254" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="255"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="256" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="257"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="258" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="259"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="260" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="261"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="262" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="263"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="264" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="265"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="266" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="267"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="268" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="269"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="270" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="271"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="272" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="273"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="274" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="275"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="276" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="277"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="278" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="279"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="280" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="281"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="282" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="283"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="284" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="285"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="286" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="287"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="288" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="289"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="290" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="291"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="292" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="293"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="294" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="295"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="296" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="297"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>horror</enum></record><record orange="298" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="299"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>philosophy</enum></record><record orange="300" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="301"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>fiction</enum></record><record orange="302" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="303"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>history</enum></record><record orange="304" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="305"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>romance</enum></record><record orange="306" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="307"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>horror</enum></record><record orange="308" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="309"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record><record orange="310" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="311"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>fiction</enum></record><record orange="312" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="313"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>history</enum></record><record orange="314" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="315"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice4>4 choice</choice4><enum>romance</enum></record><record orange="316" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record></t:root> \ No newline at end of file
diff --git a/xsd-examples/cxx/parser/performance/test.xsd b/xsd-examples/cxx/parser/performance/test.xsd
new file mode 100644
index 0000000..450a800
--- /dev/null
+++ b/xsd-examples/cxx/parser/performance/test.xsd
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/performance/test.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<schema targetNamespace="test" xmlns:t="test"
+ xmlns="http://www.w3.org/2001/XMLSchema">
+
+ <simpleType name="enum">
+ <restriction base="string">
+ <enumeration value="romance"/>
+ <enumeration value="fiction"/>
+ <enumeration value="horror"/>
+ <enumeration value="history"/>
+ <enumeration value="philosophy"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="record">
+ <sequence>
+ <element name="int" type="unsignedInt"/>
+ <element name="double" type="double"/>
+ <element name="name" type="NCName"/>
+ <element name="string" type="string" minOccurs="0" maxOccurs="1"/>
+ <choice>
+ <element name="choice1" type="string"/>
+ <element name="choice2" type="string"/>
+ <element name="choice3" type="string"/>
+ <element name="choice4" type="string"/>
+ </choice>
+ <element name="enum" type="t:enum"/>
+ </sequence>
+ <attribute name="apple" type="boolean"/>
+ <attribute name="orange" type="unsignedLong" use="required"/>
+ </complexType>
+
+ <complexType name="root">
+ <sequence>
+ <element name="record" type="t:record" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:root"/>
+
+</schema>
diff --git a/xsd-examples/cxx/parser/performance/time.cxx b/xsd-examples/cxx/parser/performance/time.cxx
new file mode 100644
index 0000000..c8c1002
--- /dev/null
+++ b/xsd-examples/cxx/parser/performance/time.cxx
@@ -0,0 +1,46 @@
+// file : cxx/parser/performance/time.cxx
+// copyright : not copyrighted - public domain
+
+#include "time.hxx"
+
+#if defined (WIN32) || defined (__WIN32__)
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h> // GetSystemTimeAsFileTime
+#else
+# include <time.h> // gettimeofday
+# include <sys/time.h> // timeval
+#endif
+
+#include <ostream> // std::ostream
+#include <iomanip> // std::setfill, std::setw
+
+namespace os
+{
+ time::
+ time ()
+ {
+#if defined (WIN32) || defined (__WIN32__)
+ FILETIME ft;
+ GetSystemTimeAsFileTime (&ft);
+ unsigned long long v (
+ ((unsigned long long) (ft.dwHighDateTime) << 32) + ft.dwLowDateTime);
+
+ sec_ = static_cast<unsigned long> (v / 10000000ULL);
+ nsec_ = static_cast<unsigned long> ((v % 10000000ULL) * 100);
+#else
+ timeval tv;
+ if (gettimeofday(&tv, 0) != 0)
+ throw failed ();
+
+ sec_ = static_cast<unsigned long> (tv.tv_sec);
+ nsec_ = static_cast<unsigned long> (tv.tv_usec * 1000);
+#endif
+ }
+
+ std::ostream&
+ operator<< (std::ostream& o, time const& t)
+ {
+ return o << t.sec () << '.'
+ << std::setfill ('0') << std::setw (9) << t.nsec ();
+ }
+}
diff --git a/xsd-examples/cxx/parser/performance/time.hxx b/xsd-examples/cxx/parser/performance/time.hxx
new file mode 100644
index 0000000..a22f671
--- /dev/null
+++ b/xsd-examples/cxx/parser/performance/time.hxx
@@ -0,0 +1,110 @@
+// file : cxx/parser/performance/time.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef TIME_HXX
+#define TIME_HXX
+
+#include <iosfwd> // std::ostream&
+
+namespace os
+{
+ class time
+ {
+ public:
+ class failed {};
+
+ // Create a time object representing the current time.
+ //
+ time ();
+
+ time (unsigned long long nsec)
+ {
+ sec_ = static_cast<unsigned long> (nsec / 1000000000ULL);
+ nsec_ = static_cast<unsigned long> (nsec % 1000000000ULL);
+ }
+
+ time (unsigned long sec, unsigned long nsec)
+ {
+ sec_ = sec;
+ nsec_ = nsec;
+ }
+
+ public:
+ unsigned long
+ sec () const
+ {
+ return sec_;
+ }
+
+ unsigned long
+ nsec () const
+ {
+ return nsec_;
+ }
+
+ public:
+ class overflow {};
+ class underflow {};
+
+ time
+ operator+= (time const& b)
+ {
+ unsigned long long tmp = 0ULL + nsec_ + b.nsec_;
+
+ sec_ += static_cast<unsigned long> (b.sec_ + tmp / 1000000000ULL);
+ nsec_ = static_cast<unsigned long> (tmp % 1000000000ULL);
+
+ return *this;
+ }
+
+ time
+ operator-= (time const& b)
+ {
+ if (*this < b)
+ throw underflow ();
+
+ sec_ -= b.sec_;
+
+ if (nsec_ < b.nsec_)
+ {
+ --sec_;
+ nsec_ += 1000000000ULL - b.nsec_;
+ }
+ else
+ nsec_ -= b.nsec_;
+
+ return *this;
+ }
+
+ friend time
+ operator+ (time const& a, time const& b)
+ {
+ time r (a);
+ r += b;
+ return r;
+ }
+
+ friend time
+ operator- (time const& a, time const& b)
+ {
+ time r (a);
+ r -= b;
+ return r;
+ }
+
+ friend bool
+ operator < (time const& a, time const& b)
+ {
+ return (a.sec_ < b.sec_) || (a.sec_ == b.sec_ && a.nsec_ < b.nsec_);
+ }
+
+ private:
+ unsigned long sec_;
+ unsigned long nsec_;
+ };
+
+ std::ostream&
+ operator<< (std::ostream&, time const&);
+}
+
+#endif // TIME_HXX
diff --git a/xsd-examples/cxx/parser/polymorphism/README b/xsd-examples/cxx/parser/polymorphism/README
new file mode 100644
index 0000000..60a97e9
--- /dev/null
+++ b/xsd-examples/cxx/parser/polymorphism/README
@@ -0,0 +1,30 @@
+This example shows how to handle XML Schema polymorphism features such
+as xsi:type attributes and substitution groups in the C++/Parser mapping.
+The case when xsi:type is used on root elements is covered in the
+polyroot examples.
+
+The example consists of the following files:
+
+supermen.xsd
+ XML Schema which describes the "supermen" instance documents.
+
+supermen.xml
+ Sample XML instance document.
+
+supermen-pskel.hxx
+supermen-pskel.cxx
+ Parser skeletons generated by the XSD compiler from supermen.xsd.
+ Note the use of the --generate-polymorphic command line option.
+
+supermen-pimpl.hxx
+supermen-pimpl.cxx
+ Parser implementations that print the XML data to STDOUT.
+
+driver.cxx
+ Driver for the example. It first constructs a parser instance from
+ all the individual parsers found in supermen-pimpl.hxx. It then invokes
+ this parser instance to parse the input file.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver supermen.xml
diff --git a/xsd-examples/cxx/parser/polymorphism/buildfile b/xsd-examples/cxx/parser/polymorphism/buildfile
new file mode 100644
index 0000000..de088cf
--- /dev/null
+++ b/xsd-examples/cxx/parser/polymorphism/buildfile
@@ -0,0 +1,25 @@
+# file : cxx/parser/polymorphism/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}{* -supermen-pskel} {hxx ixx cxx}{supermen-pskel} $libs
+
+exe{driver}: xml{supermen}: test.input = true
+
+<{hxx ixx cxx}{supermen-pskel}>: xsd{supermen} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-parser --std c++11 \
+ --generate-inline \
+ --skel-file-suffix -pskel \
+ --generate-polymorphic \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
diff --git a/xsd-examples/cxx/parser/polymorphism/driver.cxx b/xsd-examples/cxx/parser/polymorphism/driver.cxx
new file mode 100644
index 0000000..879aa5c
--- /dev/null
+++ b/xsd-examples/cxx/parser/polymorphism/driver.cxx
@@ -0,0 +1,70 @@
+// file : cxx/parser/polymorphism/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <iostream>
+
+#include "supermen-pimpl.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " supermen.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ // Construct the parser.
+ //
+ xml_schema::string_pimpl string_p;
+ xml_schema::boolean_pimpl boolean_p;
+ xml_schema::unsigned_int_pimpl unsigned_int_p;
+
+ person_pimpl person_p;
+ superman_pimpl superman_p;
+ batman_pimpl batman_p;
+
+ xml_schema::parser_map_impl person_map;
+
+ supermen_pimpl supermen_p;
+
+
+ person_p.parsers (string_p);
+ superman_p.parsers (string_p, boolean_p);
+ batman_p.parsers (string_p, boolean_p, unsigned_int_p);
+
+ // Here we are specifying a parser map which containes several parsers
+ // that can be used to parse the person element.
+ //
+ person_map.insert (person_p);
+ person_map.insert (superman_p);
+ person_map.insert (batman_p);
+
+ supermen_p.person_parser (person_map);
+
+ // Parse the XML document. The last argument to the document's
+ // constructor indicates that we are parsing polymorphic XML
+ // documents.
+ //
+ xml_schema::document doc_p (supermen_p, "supermen", true);
+
+ supermen_p.pre ();
+ doc_p.parse (argv[1]);
+ supermen_p.post_supermen ();
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/parser/polymorphism/supermen-pimpl.cxx b/xsd-examples/cxx/parser/polymorphism/supermen-pimpl.cxx
new file mode 100644
index 0000000..efed827
--- /dev/null
+++ b/xsd-examples/cxx/parser/polymorphism/supermen-pimpl.cxx
@@ -0,0 +1,85 @@
+// file : cxx/parser/polymorphism/supermen-pimpl.cxx
+// copyright : not copyrighted - public domain
+//
+
+#include <iostream>
+
+#include "supermen-pimpl.hxx"
+
+using std::cout;
+using std::endl;
+
+// person_pimpl
+//
+void person_pimpl::
+pre ()
+{
+ cout << "starting to parse person" << endl;
+}
+
+void person_pimpl::
+name (const std::string& v)
+{
+ cout << "name: " << v << endl;
+}
+
+void person_pimpl::
+post_person ()
+{
+ cout << "finished parsing person" << endl
+ << endl;
+}
+
+// superman_pimpl
+//
+void superman_pimpl::
+pre ()
+{
+ cout << "starting to parse superman" << endl;
+}
+
+void superman_pimpl::
+can_fly (bool v)
+{
+ cout << "can-fly: " << v << endl;
+}
+
+void superman_pimpl::
+post_person ()
+{
+ post_superman ();
+}
+
+void superman_pimpl::
+post_superman ()
+{
+ cout << "finished parsing superman" << endl
+ << endl;
+}
+
+// batman_pimpl
+//
+void batman_pimpl::
+pre ()
+{
+ cout << "starting to parse batman" << endl;
+}
+
+void batman_pimpl::
+wing_span (unsigned int v)
+{
+ cout << "wing-span: " << v << endl;
+}
+
+void batman_pimpl::
+post_superman ()
+{
+ post_batman ();
+}
+
+void batman_pimpl::
+post_batman ()
+{
+ cout << "finished parsing batman" << endl
+ << endl;
+}
diff --git a/xsd-examples/cxx/parser/polymorphism/supermen-pimpl.hxx b/xsd-examples/cxx/parser/polymorphism/supermen-pimpl.hxx
new file mode 100644
index 0000000..0d103b5
--- /dev/null
+++ b/xsd-examples/cxx/parser/polymorphism/supermen-pimpl.hxx
@@ -0,0 +1,68 @@
+// file : cxx/parser/polymorphism/supermen-pimpl.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef SUPERMEN_PIMPL_HXX
+#define SUPERMEN_PIMPL_HXX
+
+#include "supermen-pskel.hxx"
+
+class person_pimpl: public virtual person_pskel
+{
+public:
+ virtual void
+ pre ();
+
+ virtual void
+ name (const std::string&);
+
+ virtual void
+ post_person ();
+};
+
+class superman_pimpl: public virtual superman_pskel,
+ public person_pimpl
+{
+public:
+ virtual void
+ pre ();
+
+ virtual void
+ can_fly (bool);
+
+ // By default, post_superman() calls post_person(). In case of
+ // polymorphic parsing we want the opposite: post_person() calls
+ // post_superman().
+ //
+ virtual void
+ post_person ();
+
+ virtual void
+ post_superman ();
+};
+
+class batman_pimpl: public virtual batman_pskel,
+ public superman_pimpl
+{
+public:
+ virtual void
+ pre ();
+
+ virtual void
+ wing_span (unsigned int);
+
+ // By default, post_batman() calls post_superman(). In case of
+ // polymorphic parsing we want the opposite: post_superman()
+ // calls post_batman().
+ //
+ virtual void
+ post_superman ();
+
+ virtual void
+ post_batman ();
+};
+
+class supermen_pimpl: public supermen_pskel
+{
+};
+
+#endif // SUPERMEN_PIMPL_HXX
diff --git a/xsd-examples/cxx/parser/polymorphism/supermen.xml b/xsd-examples/cxx/parser/polymorphism/supermen.xml
new file mode 100644
index 0000000..f569161
--- /dev/null
+++ b/xsd-examples/cxx/parser/polymorphism/supermen.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/polymorphism/supermen.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<supermen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="supermen.xsd">
+
+ <person>
+ <name>John Doe</name>
+ </person>
+
+ <superman can-fly="false">
+ <name>James "007" Bond</name>
+ </superman>
+
+ <superman can-fly="true" wing-span="10" xsi:type="batman">
+ <name>Bruce Wayne</name>
+ </superman>
+
+</supermen>
diff --git a/xsd-examples/cxx/parser/polymorphism/supermen.xsd b/xsd-examples/cxx/parser/polymorphism/supermen.xsd
new file mode 100644
index 0000000..d63762b
--- /dev/null
+++ b/xsd-examples/cxx/parser/polymorphism/supermen.xsd
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/polymorphism/supermen.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- substitution group root -->
+ <xsd:element name="person" type="person"/>
+
+
+ <xsd:complexType name="superman">
+ <xsd:complexContent>
+ <xsd:extension base="person">
+ <xsd:attribute name="can-fly" type="xsd:boolean" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="superman" type="superman" substitutionGroup="person"/>
+
+ <xsd:complexType name="batman">
+ <xsd:complexContent>
+ <xsd:extension base="superman">
+ <xsd:attribute name="wing-span" type="xsd:unsignedInt" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="supermen">
+ <xsd:sequence>
+ <xsd:element ref="person" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="supermen" type="supermen"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/parser/polyroot/README b/xsd-examples/cxx/parser/polyroot/README
new file mode 100644
index 0000000..f41b91c
--- /dev/null
+++ b/xsd-examples/cxx/parser/polyroot/README
@@ -0,0 +1,36 @@
+This example shows how to handle the xsi:type attributes when it is used
+on root elements. For general coverage of XML Schema polymorphism handling
+in the C++/Parser mapping see the polymorphism example.
+
+The example consists of the following files:
+
+supermen.xsd
+ XML Schema which describes the "supermen" instance documents.
+
+person.xml
+superman.xml
+batman.xml
+ Sample XML instance documents.
+
+supermen-pskel.hxx
+supermen-pskel.cxx
+ Parser skeletons generated by the XSD compiler from supermen.xsd.
+ Note the use of the --generate-polymorphic command line option.
+
+supermen-pimpl.hxx
+supermen-pimpl.cxx
+ Parser implementations that print the XML data to STDOUT.
+
+driver.cxx
+ Driver for the example. It implements a custom document parser
+ that determines which XML Schema type is being parsed and uses
+ the corresponding parser implementation. The driver first
+ constructs a parser instance from all the individual parsers
+ found in supermen-pimpl.hxx. In then invokes this parser instance
+ to parse the input file.
+
+To run the example on the sample XML instance documents simply execute:
+
+$ ./driver person.xml
+$ ./driver superman.xml
+$ ./driver batman.xml
diff --git a/xsd-examples/cxx/parser/polyroot/batman.xml b/xsd-examples/cxx/parser/polyroot/batman.xml
new file mode 100644
index 0000000..600ad6f
--- /dev/null
+++ b/xsd-examples/cxx/parser/polyroot/batman.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/polyroot/batman.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="supermen.xsd"
+ xsi:type="batman" can-fly="true" wing-span="10">
+
+ <name>Bruce Wayne</name>
+
+</person>
diff --git a/xsd-examples/cxx/parser/polyroot/buildfile b/xsd-examples/cxx/parser/polyroot/buildfile
new file mode 100644
index 0000000..6ae0fdc
--- /dev/null
+++ b/xsd-examples/cxx/parser/polyroot/buildfile
@@ -0,0 +1,24 @@
+# file : cxx/parser/polyroot/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README} xml{batman person superman}
+
+exe{driver}: {hxx cxx}{* -supermen-pskel} {hxx ixx cxx}{supermen-pskel} $libs \
+ testscript
+
+<{hxx ixx cxx}{supermen-pskel}>: xsd{supermen} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-parser --std c++11 \
+ --generate-inline \
+ --skel-file-suffix -pskel \
+ --generate-polymorphic \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
diff --git a/xsd-examples/cxx/parser/polyroot/driver.cxx b/xsd-examples/cxx/parser/polyroot/driver.cxx
new file mode 100644
index 0000000..986c8c0
--- /dev/null
+++ b/xsd-examples/cxx/parser/polyroot/driver.cxx
@@ -0,0 +1,138 @@
+// file : cxx/parser/polyroot/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <map>
+#include <string>
+#include <iostream>
+
+#include "supermen-pimpl.hxx"
+
+using std::cerr;
+using std::endl;
+using xml_schema::ro_string;
+
+// Customize the xml_schema::document object to handle polymorphic
+// root element. For more information see the multiroot example.
+//
+class document: public xml_schema::document
+{
+public:
+ document (const xml_schema::parser_map& parser_map)
+ : xml_schema::document (true), // Indicate polymorphic parsing.
+ parser_map_ (parser_map)
+ {
+ }
+
+protected:
+ // This function is called to obtain the root element type parser.
+ // If the returned pointer is 0 then the whole document content
+ // is ignored. The type argument contains the XML Schema type
+ // if xsi:type attribute was specified for this element and 0
+ // otherwise.
+ //
+ virtual xml_schema::parser_base*
+ start_root_element (const ro_string& ns,
+ const ro_string& name,
+ const ro_string* type)
+ {
+ if (name != "person" || !ns.empty ())
+ return 0;
+
+ xml_schema::parser_base* base;
+
+ // Search the parser map.
+ //
+ if (type == 0)
+ {
+ // No xsi:type. Static type should be used.
+ //
+ ro_string st (person_pskel::_static_type ());
+ base = parser_map_.find (st);
+ }
+ else
+ {
+ base = parser_map_.find (*type);
+ }
+
+ if (base != 0)
+ {
+ parser_used_ = dynamic_cast<person_pskel*> (base);
+ parser_used_->pre ();
+ }
+ else
+ parser_used_ = 0; // No parser for this type.
+
+ return parser_used_;
+ }
+
+ // This function is called to indicate the completion of document
+ // parsing. The parser argument contains the pointer returned by
+ // start_root_element.
+ //
+ virtual void
+ end_root_element (const ro_string& /* ns */,
+ const ro_string& /* name */,
+ xml_schema::parser_base* /* parser */)
+ {
+ // Instead of caching the current parser in parser_used_, we
+ // could also dynamic_cast the parser argument to the person_pskel
+ // type.
+ //
+ if (parser_used_)
+ parser_used_->post_person ();
+ }
+
+
+private:
+ const xml_schema::parser_map& parser_map_;
+ person_pskel* parser_used_;
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " instance.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ // Construct the parser.
+ //
+ xml_schema::string_pimpl string_p;
+ xml_schema::boolean_pimpl boolean_p;
+ xml_schema::unsigned_int_pimpl unsigned_int_p;
+
+ person_pimpl person_p;
+ superman_pimpl superman_p;
+ batman_pimpl batman_p;
+
+ person_p.parsers (string_p);
+ superman_p.parsers (string_p, boolean_p);
+ batman_p.parsers (string_p, boolean_p, unsigned_int_p);
+
+ // Parse the XML document.
+ //
+ xml_schema::parser_map_impl person_map;
+
+ person_map.insert (person_p);
+ person_map.insert (superman_p);
+ person_map.insert (batman_p);
+
+ document doc_p (person_map);
+
+ doc_p.parse (argv[1]);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/parser/polyroot/person.xml b/xsd-examples/cxx/parser/polyroot/person.xml
new file mode 100644
index 0000000..2182457
--- /dev/null
+++ b/xsd-examples/cxx/parser/polyroot/person.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/polyroot/person.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="supermen.xsd">
+
+ <name>John Doe</name>
+
+</person>
diff --git a/xsd-examples/cxx/parser/polyroot/superman.xml b/xsd-examples/cxx/parser/polyroot/superman.xml
new file mode 100644
index 0000000..97dbf1b
--- /dev/null
+++ b/xsd-examples/cxx/parser/polyroot/superman.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/polyroot/superman.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="supermen.xsd"
+ xsi:type="superman" can-fly="false">
+
+ <name>James "007" Bond</name>
+
+</person>
diff --git a/xsd-examples/cxx/parser/polyroot/supermen-pimpl.cxx b/xsd-examples/cxx/parser/polyroot/supermen-pimpl.cxx
new file mode 100644
index 0000000..d35e1fd
--- /dev/null
+++ b/xsd-examples/cxx/parser/polyroot/supermen-pimpl.cxx
@@ -0,0 +1,85 @@
+// file : cxx/parser/polyroot/supermen-pimpl.cxx
+// copyright : not copyrighted - public domain
+//
+
+#include <iostream>
+
+#include "supermen-pimpl.hxx"
+
+using std::cout;
+using std::endl;
+
+// person_pimpl
+//
+void person_pimpl::
+pre ()
+{
+ cout << "starting to parse person" << endl;
+}
+
+void person_pimpl::
+name (const std::string& v)
+{
+ cout << "name: " << v << endl;
+}
+
+void person_pimpl::
+post_person ()
+{
+ cout << "finished parsing person" << endl
+ << endl;
+}
+
+// superman_pimpl
+//
+void superman_pimpl::
+pre ()
+{
+ cout << "starting to parse superman" << endl;
+}
+
+void superman_pimpl::
+can_fly (bool v)
+{
+ cout << "can-fly: " << v << endl;
+}
+
+void superman_pimpl::
+post_person ()
+{
+ post_superman ();
+}
+
+void superman_pimpl::
+post_superman ()
+{
+ cout << "finished parsing superman" << endl
+ << endl;
+}
+
+// batman_pimpl
+//
+void batman_pimpl::
+pre ()
+{
+ cout << "starting to parse batman" << endl;
+}
+
+void batman_pimpl::
+wing_span (unsigned int v)
+{
+ cout << "wing-span: " << v << endl;
+}
+
+void batman_pimpl::
+post_superman ()
+{
+ post_batman ();
+}
+
+void batman_pimpl::
+post_batman ()
+{
+ cout << "finished parsing batman" << endl
+ << endl;
+}
diff --git a/xsd-examples/cxx/parser/polyroot/supermen-pimpl.hxx b/xsd-examples/cxx/parser/polyroot/supermen-pimpl.hxx
new file mode 100644
index 0000000..17ce7ff
--- /dev/null
+++ b/xsd-examples/cxx/parser/polyroot/supermen-pimpl.hxx
@@ -0,0 +1,64 @@
+// file : cxx/parser/polyroot/supermen-pimpl.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef SUPERMEN_PIMPL_HXX
+#define SUPERMEN_PIMPL_HXX
+
+#include "supermen-pskel.hxx"
+
+class person_pimpl: public virtual person_pskel
+{
+public:
+ virtual void
+ pre ();
+
+ virtual void
+ name (const std::string&);
+
+ virtual void
+ post_person ();
+};
+
+class superman_pimpl: public virtual superman_pskel,
+ public person_pimpl
+{
+public:
+ virtual void
+ pre ();
+
+ virtual void
+ can_fly (bool);
+
+ // By default, post_superman() calls post_person(). In case of
+ // polymorphic parsing we want the opposite: post_person() calls
+ // post_superman().
+ //
+ virtual void
+ post_person ();
+
+ virtual void
+ post_superman ();
+};
+
+class batman_pimpl: public virtual batman_pskel,
+ public superman_pimpl
+{
+public:
+ virtual void
+ pre ();
+
+ virtual void
+ wing_span (unsigned int);
+
+ // By default, post_batman() calls post_superman(). In case of
+ // polymorphic parsing we want the opposite: post_superman()
+ // calls post_batman().
+ //
+ virtual void
+ post_superman ();
+
+ virtual void
+ post_batman ();
+};
+
+#endif // SUPERMEN_PIMPL_HXX
diff --git a/xsd-examples/cxx/parser/polyroot/supermen.xsd b/xsd-examples/cxx/parser/polyroot/supermen.xsd
new file mode 100644
index 0000000..e397b50
--- /dev/null
+++ b/xsd-examples/cxx/parser/polyroot/supermen.xsd
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/polyroot/supermen.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="person" type="person"/>
+
+ <xsd:complexType name="superman">
+ <xsd:complexContent>
+ <xsd:extension base="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="superman">
+ <xsd:attribute name="wing-span" type="xsd:unsignedInt" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/parser/polyroot/testscript b/xsd-examples/cxx/parser/polyroot/testscript
new file mode 100644
index 0000000..c5ad682
--- /dev/null
+++ b/xsd-examples/cxx/parser/polyroot/testscript
@@ -0,0 +1,6 @@
+# file : cxx/parser/polyroot/testscript
+# license : not copyrighted - public domain
+
+$* $src_base/batman.xml >| : batman
+$* $src_base/person.xml >| : person
+$* $src_base/superman.xml >| : superman
diff --git a/xsd-examples/cxx/parser/wildcard/README b/xsd-examples/cxx/parser/wildcard/README
new file mode 100644
index 0000000..89f9aa9
--- /dev/null
+++ b/xsd-examples/cxx/parser/wildcard/README
@@ -0,0 +1,27 @@
+This example shows how to parse the XML data matched by XML Schema
+wildcards (any and anyAttribute) in the C++/Parser mapping. The
+example consists of the following files:
+
+email.xsd
+ XML Schema which describes a simple email format with the
+ extensible envelope type.
+
+email.xml
+ Sample email message.
+
+email-pskel.hxx
+email-pskel.cxx
+ Parser skeletons generated by XSD from email.xsd.
+
+driver.cxx
+ Parser implementations and a driver for the example. The
+ parser implementations simply print the data to STDERR.
+ The driver first constructs parser instances from the
+ parser implementations mentioned above and a couple of
+ predefined parsers for the XML Schema built-in types.
+ In then invokes the parser instances to parse the input
+ file.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver email.xml
diff --git a/xsd-examples/cxx/parser/wildcard/buildfile b/xsd-examples/cxx/parser/wildcard/buildfile
new file mode 100644
index 0000000..93e2dc8
--- /dev/null
+++ b/xsd-examples/cxx/parser/wildcard/buildfile
@@ -0,0 +1,24 @@
+# file : cxx/parser/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}{* -email-pskel} {hxx ixx cxx}{email-pskel} $libs
+
+exe{driver}: xml{email}: test.input = true
+
+<{hxx ixx cxx}{email-pskel}>: xsd{email} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-parser --std c++11 \
+ --generate-inline \
+ --skel-file-suffix -pskel \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
diff --git a/xsd-examples/cxx/parser/wildcard/driver.cxx b/xsd-examples/cxx/parser/wildcard/driver.cxx
new file mode 100644
index 0000000..cb7a754
--- /dev/null
+++ b/xsd-examples/cxx/parser/wildcard/driver.cxx
@@ -0,0 +1,239 @@
+// file : cxx/parser/wildcard/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <string>
+#include <memory>
+#include <iostream>
+
+#include "email-pskel.hxx"
+
+using namespace std;
+using xml_schema::ro_string;
+
+class binary_pimpl: public email::binary_pskel,
+ public xml_schema::base64_binary_pimpl
+{
+public:
+ virtual void
+ name (const string& n)
+ {
+ cerr << "binary: " << n << endl;
+ }
+
+ virtual void
+ mime (const string& t)
+ {
+ cerr << "type: " << t << endl
+ << endl;
+ }
+
+ virtual void
+ post_binary ()
+ {
+ unique_ptr<xml_schema::buffer> buf (post_base64_binary ());
+
+ cerr << "size: " << buf->size () << endl
+ << endl;
+ }
+};
+
+class envelope_pimpl: public email::envelope_pskel
+{
+public:
+ envelope_pimpl (xml_schema::unsigned_int_pskel& uint_p,
+ xml_schema::string_pskel& string_p,
+ email::binary_pskel& binary_p)
+ : depth_ (0), cur_ (0),
+ uint_p_ (uint_p), string_p_ (string_p), binary_p_ (binary_p)
+ {
+ }
+
+ virtual void
+ to (const string& addr)
+ {
+ cerr << "To: " << addr << endl;
+ }
+
+ virtual void
+ from (const string& addr)
+ {
+ cerr << "From: " << addr << endl;
+ }
+
+ virtual void
+ subject (const string& s)
+ {
+ cerr << "Subject: " << s << endl;
+ }
+
+ // Wildcard handling. All wildcard events are routed to these
+ // four functions. It is our job to dispatch them to the right
+ // parsers.
+ //
+ virtual void
+ _start_any_element (const ro_string& ns,
+ const ro_string& name,
+ const ro_string* type)
+ {
+ if (depth_++ > 0)
+ {
+ // Nested wildcard element.
+ //
+ if (cur_)
+ cur_->_start_element (ns, name, type);
+ }
+ else
+ {
+ // Top-level element matched by the any wildcard.
+ //
+ if (ns == "http://www.codesynthesis.com/email")
+ {
+ if (name == "text")
+ {
+ cur_ = &string_p_;
+ string_p_.pre ();
+ string_p_._pre_impl ();
+ }
+ else if (name == "binary")
+ {
+ cur_ = &binary_p_;
+ binary_p_.pre ();
+ binary_p_._pre_impl ();
+ }
+ }
+
+ if (cur_ == 0)
+ {
+ cerr << "Unknown wildcard content: " << ns << "#" << name << endl;
+ }
+ }
+ }
+
+ virtual void
+ _end_any_element (const ro_string& ns, const ro_string& name)
+ {
+ if (--depth_ > 0)
+ {
+ if (cur_)
+ cur_->_end_element (ns, name);
+ }
+ else
+ {
+ if (ns == "http://www.codesynthesis.com/email")
+ {
+ if (name == "text")
+ {
+ string_p_._post_impl ();
+ string text (string_p_.post_string ());
+
+ cerr << text << endl
+ << endl;
+ }
+ else if (name == "binary")
+ {
+ binary_p_._post_impl ();
+ binary_p_.post_binary ();
+ }
+ }
+
+ cur_ = 0;
+ }
+ }
+
+ virtual void
+ _any_attribute (const ro_string& ns,
+ const ro_string& name,
+ const ro_string& value)
+ {
+ if (depth_ > 0)
+ {
+ // Nested wildcard attribute.
+ //
+ if (cur_)
+ cur_->_attribute (ns, name, value);
+ }
+ else
+ {
+ // Top-level attribute matched by the anyAttribute wildcard.
+ //
+ if (ns == "http://www.codesynthesis.com/email" && name == "thread-id")
+ {
+ uint_p_.pre ();
+ uint_p_._pre_impl ();
+ uint_p_._characters (value);
+ uint_p_._post_impl ();
+ unsigned int tid (uint_p_.post_unsigned_int ());
+
+ cerr << "Thread-id: " << tid << endl;
+ }
+ }
+ }
+
+ virtual void
+ _any_characters (const ro_string& s)
+ {
+ if (depth_ > 0)
+ {
+ if (cur_)
+ cur_->_characters (s);
+ }
+ }
+
+private:
+ size_t depth_;
+ xml_schema::parser_base* cur_;
+
+ // Parsers for the unsigned int, string and binary types.
+ //
+private:
+ xml_schema::unsigned_int_pskel& uint_p_;
+ xml_schema::string_pskel& string_p_;
+ email::binary_pskel& binary_p_;
+};
+
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " email.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ // Construct the parser.
+ //
+ xml_schema::unsigned_int_pimpl unsigned_int_p;
+ xml_schema::string_pimpl string_p;
+ binary_pimpl binary_p;
+ envelope_pimpl envelope_p (unsigned_int_p, string_p, binary_p);
+
+ binary_p.parsers (string_p, // name
+ string_p); // mime
+
+ envelope_p.parsers (string_p, // to
+ string_p, // from
+ string_p); // subject
+
+ // Parse the XML instance document.
+ //
+ xml_schema::document doc_p (envelope_p,
+ "http://www.codesynthesis.com/email",
+ "message");
+ envelope_p.pre ();
+ doc_p.parse (argv[1]);
+ envelope_p.post_envelope ();
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/parser/wildcard/email.xml b/xsd-examples/cxx/parser/wildcard/email.xml
new file mode 100644
index 0000000..482103b
--- /dev/null
+++ b/xsd-examples/cxx/parser/wildcard/email.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/wildcard/email.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<eml:message xmlns:eml="http://www.codesynthesis.com/email"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/email email.xsd"
+ eml:thread-id="123456789">
+
+ <to>Jane Doe &lt;jane@doe.com></to>
+ <from>John Doe &lt;john@doe.com></from>
+ <subject>Surfing pictures</subject>
+
+ <eml:text>
+Hi Jane,
+
+Here are cool pictures of me surfing.
+
+Cheers,
+John
+ </eml:text>
+
+ <eml:binary name="pic1.jpg" mime="image/jpeg">YmFzZTY0IGJpbmFyeQ==</eml:binary>
+ <eml:binary name="pic2.jpg" mime="image/jpeg">YmFzZTY0IGJpbmFyeQ==</eml:binary>
+
+</eml:message>
diff --git a/xsd-examples/cxx/parser/wildcard/email.xsd b/xsd-examples/cxx/parser/wildcard/email.xsd
new file mode 100644
index 0000000..6aec20c
--- /dev/null
+++ b/xsd-examples/cxx/parser/wildcard/email.xsd
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/parser/wildcard/email.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:eml="http://www.codesynthesis.com/email"
+ targetNamespace="http://www.codesynthesis.com/email">
+
+ <!-- Predefined envolop body types. -->
+
+ <xsd:element name="text" type="xsd:string"/>
+
+ <xsd:complexType name="binary">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:base64Binary">
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ <xsd:attribute name="mime" type="xsd:string" use="required"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:element name="binary" type="eml:binary"/>
+
+ <!-- Predefined envelop attributes. -->
+
+ <xsd:attribute name="thread-id" type="xsd:unsignedInt"/>
+
+
+ <xsd:complexType name="envelope">
+ <xsd:sequence>
+ <xsd:element name="to" type="xsd:string"/>
+ <xsd:element name="from" type="xsd:string"/>
+ <xsd:element name="subject" type="xsd:string"/>
+
+ <!-- Extensible envelope body. -->
+
+ <xsd:any namespace="##targetNamespace" processContents="strict"
+ maxOccurs="unbounded" />
+ </xsd:sequence>
+ <xsd:anyAttribute namespace="##targetNamespace" processContents="strict"/>
+ </xsd:complexType>
+
+ <xsd:element name="message" type="eml:envelope"/>
+
+</xsd:schema>