summaryrefslogtreecommitdiff
path: root/xsd-examples/cxx
diff options
context:
space:
mode:
Diffstat (limited to 'xsd-examples/cxx')
-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
-rw-r--r--xsd-examples/cxx/tree/README84
-rw-r--r--xsd-examples/cxx/tree/binary/README16
-rw-r--r--xsd-examples/cxx/tree/binary/boost/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/binary/boost/README49
-rw-r--r--xsd-examples/cxx/tree/binary/boost/boost-archive-extraction.hxx188
-rw-r--r--xsd-examples/cxx/tree/binary/boost/boost-archive-insertion.hxx177
-rw-r--r--xsd-examples/cxx/tree/binary/boost/buildfile32
-rw-r--r--xsd-examples/cxx/tree/binary/boost/driver.cxx72
-rw-r--r--xsd-examples/cxx/tree/binary/boost/library-prologue.hxx9
-rw-r--r--xsd-examples/cxx/tree/binary/boost/library.xml52
-rw-r--r--xsd-examples/cxx/tree/binary/boost/library.xsd75
-rw-r--r--xsd-examples/cxx/tree/binary/cdr/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/binary/cdr/README36
-rw-r--r--xsd-examples/cxx/tree/binary/cdr/buildfile28
-rw-r--r--xsd-examples/cxx/tree/binary/cdr/driver.cxx87
-rw-r--r--xsd-examples/cxx/tree/binary/cdr/library.xml52
-rw-r--r--xsd-examples/cxx/tree/binary/cdr/library.xsd75
-rw-r--r--xsd-examples/cxx/tree/binary/xdr/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/binary/xdr/README36
-rw-r--r--xsd-examples/cxx/tree/binary/xdr/buildfile30
-rw-r--r--xsd-examples/cxx/tree/binary/xdr/driver.cxx148
-rw-r--r--xsd-examples/cxx/tree/binary/xdr/library.xml52
-rw-r--r--xsd-examples/cxx/tree/binary/xdr/library.xsd75
-rw-r--r--xsd-examples/cxx/tree/buildfile6
-rw-r--r--xsd-examples/cxx/tree/caching/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/caching/README29
-rw-r--r--xsd-examples/cxx/tree/caching/buildfile27
-rw-r--r--xsd-examples/cxx/tree/caching/driver.cxx165
-rw-r--r--xsd-examples/cxx/tree/caching/library.xml52
-rw-r--r--xsd-examples/cxx/tree/caching/library.xsd72
-rw-r--r--xsd-examples/cxx/tree/compression/.gitignore2
-rw-r--r--xsd-examples/cxx/tree/compression/README48
-rw-r--r--xsd-examples/cxx/tree/compression/buildfile28
-rw-r--r--xsd-examples/cxx/tree/compression/compressed-format-target.cxx152
-rw-r--r--xsd-examples/cxx/tree/compression/compressed-format-target.hxx91
-rw-r--r--xsd-examples/cxx/tree/compression/compressed-input-source.cxx195
-rw-r--r--xsd-examples/cxx/tree/compression/compressed-input-source.hxx121
-rw-r--r--xsd-examples/cxx/tree/compression/driver.cxx124
-rw-r--r--xsd-examples/cxx/tree/compression/library.xml.gzbin0 -> 486 bytes
-rw-r--r--xsd-examples/cxx/tree/compression/library.xsd72
-rw-r--r--xsd-examples/cxx/tree/compression/testscript4
-rw-r--r--xsd-examples/cxx/tree/custom/README40
-rw-r--r--xsd-examples/cxx/tree/custom/buildfile6
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/.gitignore2
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/README47
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/buildfile47
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/calendar.xml22
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/calendar.xsd31
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/driver.cxx39
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/xml-schema-custom.cxx56
-rw-r--r--xsd-examples/cxx/tree/custom/calendar/xml-schema-custom.hxx33
-rw-r--r--xsd-examples/cxx/tree/custom/comments/.gitignore2
-rw-r--r--xsd-examples/cxx/tree/custom/comments/README57
-rw-r--r--xsd-examples/cxx/tree/custom/comments/buildfile48
-rw-r--r--xsd-examples/cxx/tree/custom/comments/dom-parse.cxx93
-rw-r--r--xsd-examples/cxx/tree/custom/comments/dom-parse.hxx23
-rw-r--r--xsd-examples/cxx/tree/custom/comments/driver.cxx90
-rw-r--r--xsd-examples/cxx/tree/custom/comments/people.xml20
-rw-r--r--xsd-examples/cxx/tree/custom/comments/people.xsd29
-rw-r--r--xsd-examples/cxx/tree/custom/comments/xml-schema-custom.cxx117
-rw-r--r--xsd-examples/cxx/tree/custom/comments/xml-schema-custom.hxx60
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/README40
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/buildfile25
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/contacts-custom.cxx50
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/contacts-custom.hxx43
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/contacts.xml20
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/contacts.xsd31
-rw-r--r--xsd-examples/cxx/tree/custom/contacts/driver.cxx38
-rw-r--r--xsd-examples/cxx/tree/custom/double/.gitignore2
-rw-r--r--xsd-examples/cxx/tree/custom/double/README62
-rw-r--r--xsd-examples/cxx/tree/custom/double/buildfile46
-rw-r--r--xsd-examples/cxx/tree/custom/double/double-custom.cxx96
-rw-r--r--xsd-examples/cxx/tree/custom/double/double-custom.hxx67
-rw-r--r--xsd-examples/cxx/tree/custom/double/driver.cxx31
-rw-r--r--xsd-examples/cxx/tree/custom/double/order.xsd25
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/README50
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/buildfile30
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/driver.cxx122
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/people-custom.cxx89
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/people-custom.hxx83
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/people.xml38
-rw-r--r--xsd-examples/cxx/tree/custom/mixed/people.xsd45
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/.gitignore2
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/README53
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/buildfile31
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/driver.cxx38
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx19
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/people-custom.cxx156
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/people-custom.hxx105
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/people.xml26
-rw-r--r--xsd-examples/cxx/tree/custom/taxonomy/people.xsd44
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/README45
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/buildfile27
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/driver.cxx47
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/wildcard-custom.cxx84
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/wildcard-custom.hxx66
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/wildcard.xml14
-rw-r--r--xsd-examples/cxx/tree/custom/wildcard/wildcard.xsd25
-rw-r--r--xsd-examples/cxx/tree/embedded/.gitignore3
-rw-r--r--xsd-examples/cxx/tree/embedded/README48
-rw-r--r--xsd-examples/cxx/tree/embedded/buildfile46
-rw-r--r--xsd-examples/cxx/tree/embedded/driver.cxx183
-rw-r--r--xsd-examples/cxx/tree/embedded/grammar-input-stream.cxx95
-rw-r--r--xsd-examples/cxx/tree/embedded/grammar-input-stream.hxx40
-rw-r--r--xsd-examples/cxx/tree/embedded/library.xml52
-rw-r--r--xsd-examples/cxx/tree/embedded/library.xsd72
-rw-r--r--xsd-examples/cxx/tree/embedded/xsdbin.cxx494
-rw-r--r--xsd-examples/cxx/tree/hello/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/hello/README26
-rw-r--r--xsd-examples/cxx/tree/hello/buildfile23
-rw-r--r--xsd-examples/cxx/tree/hello/driver.cxx36
-rw-r--r--xsd-examples/cxx/tree/hello/hello.xml19
-rw-r--r--xsd-examples/cxx/tree/hello/hello.xsd52
-rw-r--r--xsd-examples/cxx/tree/library/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/library/README32
-rw-r--r--xsd-examples/cxx/tree/library/buildfile25
-rw-r--r--xsd-examples/cxx/tree/library/driver.cxx130
-rw-r--r--xsd-examples/cxx/tree/library/library.xml52
-rw-r--r--xsd-examples/cxx/tree/library/library.xsd72
-rw-r--r--xsd-examples/cxx/tree/messaging/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/messaging/README58
-rw-r--r--xsd-examples/cxx/tree/messaging/balance.xml16
-rw-r--r--xsd-examples/cxx/tree/messaging/buildfile29
-rw-r--r--xsd-examples/cxx/tree/messaging/deposit.xml17
-rw-r--r--xsd-examples/cxx/tree/messaging/dom-parse.cxx93
-rw-r--r--xsd-examples/cxx/tree/messaging/dom-parse.hxx22
-rw-r--r--xsd-examples/cxx/tree/messaging/dom-serialize.cxx64
-rw-r--r--xsd-examples/cxx/tree/messaging/dom-serialize.hxx20
-rw-r--r--xsd-examples/cxx/tree/messaging/driver.cxx146
-rw-r--r--xsd-examples/cxx/tree/messaging/protocol.xsd53
-rw-r--r--xsd-examples/cxx/tree/messaging/testscript6
-rw-r--r--xsd-examples/cxx/tree/messaging/withdraw.xml17
-rw-r--r--xsd-examples/cxx/tree/mixed/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/mixed/README45
-rw-r--r--xsd-examples/cxx/tree/mixed/buildfile27
-rw-r--r--xsd-examples/cxx/tree/mixed/driver.cxx122
-rw-r--r--xsd-examples/cxx/tree/mixed/text.xml17
-rw-r--r--xsd-examples/cxx/tree/mixed/text.xsd28
-rw-r--r--xsd-examples/cxx/tree/multiroot/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/multiroot/README45
-rw-r--r--xsd-examples/cxx/tree/multiroot/balance.xml16
-rw-r--r--xsd-examples/cxx/tree/multiroot/buildfile26
-rw-r--r--xsd-examples/cxx/tree/multiroot/deposit.xml17
-rw-r--r--xsd-examples/cxx/tree/multiroot/dom-parse.cxx93
-rw-r--r--xsd-examples/cxx/tree/multiroot/dom-parse.hxx22
-rw-r--r--xsd-examples/cxx/tree/multiroot/driver.cxx124
-rw-r--r--xsd-examples/cxx/tree/multiroot/protocol.xsd50
-rw-r--r--xsd-examples/cxx/tree/multiroot/testscript6
-rw-r--r--xsd-examples/cxx/tree/multiroot/withdraw.xml17
-rw-r--r--xsd-examples/cxx/tree/order/README11
-rw-r--r--xsd-examples/cxx/tree/order/element/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/order/element/README35
-rw-r--r--xsd-examples/cxx/tree/order/element/buildfile30
-rw-r--r--xsd-examples/cxx/tree/order/element/driver.cxx147
-rw-r--r--xsd-examples/cxx/tree/order/element/transactions.xml32
-rw-r--r--xsd-examples/cxx/tree/order/element/transactions.xsd58
-rw-r--r--xsd-examples/cxx/tree/order/mixed/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/order/mixed/README45
-rw-r--r--xsd-examples/cxx/tree/order/mixed/buildfile25
-rw-r--r--xsd-examples/cxx/tree/order/mixed/driver.cxx89
-rw-r--r--xsd-examples/cxx/tree/order/mixed/text.xml17
-rw-r--r--xsd-examples/cxx/tree/order/mixed/text.xsd28
-rw-r--r--xsd-examples/cxx/tree/performance/.gitignore5
-rw-r--r--xsd-examples/cxx/tree/performance/README62
-rw-r--r--xsd-examples/cxx/tree/performance/buildfile36
-rw-r--r--xsd-examples/cxx/tree/performance/driver.cxx90
-rw-r--r--xsd-examples/cxx/tree/performance/gen.cxx76
-rw-r--r--xsd-examples/cxx/tree/performance/gen.testscript9
-rw-r--r--xsd-examples/cxx/tree/performance/parsing.cxx172
-rw-r--r--xsd-examples/cxx/tree/performance/serialization.cxx132
-rw-r--r--xsd-examples/cxx/tree/performance/test-50k.xml1
-rw-r--r--xsd-examples/cxx/tree/performance/test.xsd49
-rw-r--r--xsd-examples/cxx/tree/performance/time.cxx46
-rw-r--r--xsd-examples/cxx/tree/performance/time.hxx110
-rw-r--r--xsd-examples/cxx/tree/polymorphism/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/polymorphism/README32
-rw-r--r--xsd-examples/cxx/tree/polymorphism/buildfile26
-rw-r--r--xsd-examples/cxx/tree/polymorphism/driver.cxx59
-rw-r--r--xsd-examples/cxx/tree/polymorphism/supermen.xml25
-rw-r--r--xsd-examples/cxx/tree/polymorphism/supermen.xsd48
-rw-r--r--xsd-examples/cxx/tree/secure/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/secure/README41
-rw-r--r--xsd-examples/cxx/tree/secure/buildfile27
-rw-r--r--xsd-examples/cxx/tree/secure/driver.cxx141
-rw-r--r--xsd-examples/cxx/tree/secure/library.xml59
-rw-r--r--xsd-examples/cxx/tree/secure/library.xsd72
-rw-r--r--xsd-examples/cxx/tree/secure/secure-dom-parser.cxx24
-rw-r--r--xsd-examples/cxx/tree/secure/secure-dom-parser.hxx25
-rw-r--r--xsd-examples/cxx/tree/streaming/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/streaming/README51
-rw-r--r--xsd-examples/cxx/tree/streaming/buildfile26
-rw-r--r--xsd-examples/cxx/tree/streaming/driver.cxx139
-rw-r--r--xsd-examples/cxx/tree/streaming/grammar-input-stream.cxx96
-rw-r--r--xsd-examples/cxx/tree/streaming/grammar-input-stream.hxx41
-rw-r--r--xsd-examples/cxx/tree/streaming/parser.cxx371
-rw-r--r--xsd-examples/cxx/tree/streaming/parser.hxx67
-rw-r--r--xsd-examples/cxx/tree/streaming/position.xml29
-rw-r--r--xsd-examples/cxx/tree/streaming/position.xsd37
-rw-r--r--xsd-examples/cxx/tree/streaming/serializer.cxx636
-rw-r--r--xsd-examples/cxx/tree/streaming/serializer.hxx209
-rw-r--r--xsd-examples/cxx/tree/streaming/testscript10
-rw-r--r--xsd-examples/cxx/tree/wildcard/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/wildcard/README34
-rw-r--r--xsd-examples/cxx/tree/wildcard/buildfile30
-rw-r--r--xsd-examples/cxx/tree/wildcard/driver.cxx159
-rw-r--r--xsd-examples/cxx/tree/wildcard/email.xml31
-rw-r--r--xsd-examples/cxx/tree/wildcard/email.xsd50
-rw-r--r--xsd-examples/cxx/tree/xpath/.gitignore1
-rw-r--r--xsd-examples/cxx/tree/xpath/README43
-rw-r--r--xsd-examples/cxx/tree/xpath/buildfile28
-rw-r--r--xsd-examples/cxx/tree/xpath/dom-parse.cxx88
-rw-r--r--xsd-examples/cxx/tree/xpath/dom-parse.hxx25
-rw-r--r--xsd-examples/cxx/tree/xpath/driver.cxx137
-rw-r--r--xsd-examples/cxx/tree/xpath/people.xml28
-rw-r--r--xsd-examples/cxx/tree/xpath/people.xsd38
298 files changed, 16459 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>
diff --git a/xsd-examples/cxx/tree/README b/xsd-examples/cxx/tree/README
new file mode 100644
index 0000000..83ffcab
--- /dev/null
+++ b/xsd-examples/cxx/tree/README
@@ -0,0 +1,84 @@
+This directory contains a number of examples that show how to use
+the C++/Tree 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.
+
+library
+ Shows hot to handle more complex data structures, use the
+ ID/IDREF cross-referencing mechanism, use the xsd:enumeration
+ to C++ enum mapping, modify the object model, and serialize
+ the modified object model back to XML.
+
+polymorphism
+ Shows how to use XML Schema polymorphism features such as the
+ xsi:type attribute and substitution groups.
+
+order/
+ A collection of examples that show how to use ordered types to
+ capture and maintain content order.
+
+xpath
+ Shows how to use the C++/Tree mapping together with XPath.
+
+wildcard
+ Shows how to use the optional wildcard mapping to parse, access,
+ modify, and serialize the XML data matched by XML Schema wildcards
+ (any and anyAttribute).
+
+mixed
+ Shows how to access the underlying DOM nodes to handle raw, "type-
+ less content" such as mixed content models, anyType/anySimpleType,
+ and any/anyAttribute.
+
+multiroot
+ Shows how to handle XML vocabularies with multiple root elements.
+ See also the messaging example.
+
+messaging
+ Shows how to handle XML vocabularies with multiple root elements
+ using the element type and element map features of the C++/Tree
+ mapping.
+
+caching
+ Shows how to parse several XML documents while reusing the
+ underlying XML parser and caching the schemas used for validation.
+
+embedded
+ Shows how to embed the binary representation of the schema grammar
+ into an application and then use it with the C++/Tree mapping to
+ parse and validate XML documents.
+
+secure
+ Shows how to perform more secure XML parsing by disabling the XML
+ External Entity (XXE) Processing.
+
+performance
+ Measures the performance of parsing and serialization. This example
+ also shows how to structure your code to achieve the maximum
+ performance for these two operations.
+
+custom/
+ A collection of examples that show how to customize the C++/Tree
+ mapping by using custom C++ classes instead of or in addition to
+ the generated ones. See the accompanying README file for an
+ overview of each example in this directory.
+
+streaming
+ Shows how to perform stream-oriented, partially in-memory XML
+ processing using the C++/Tree mapping. With the partially in-memory
+ parsing and serialization only a part of the object model is in
+ memory at any given time. With this approach we can process parts
+ of the document as they become available as well as handle documents
+ that are too large to fit into memory.
+
+compression
+ Shows how to compress an XML document during serialization and decompress
+ it during parsing using the zlib library.
+
+binary/
+ A collection of examples that show how to serialize the object model
+ into a number of predefined and custom binary formats.
diff --git a/xsd-examples/cxx/tree/binary/README b/xsd-examples/cxx/tree/binary/README
new file mode 100644
index 0000000..365551e
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/README
@@ -0,0 +1,16 @@
+This directory contains a number of examples that show how to serialize
+the object model into a number of predefined and custom binary formats.
+The following list gives an overview of each example:
+
+boost
+ Shows how to save/load the object model to/from a custom format
+ using the Boost serialization library as an example.
+
+cdr
+ Shows how to save/load the object model to/from CDR (Common Data
+ Representation) binary format using ACE CDR streams.
+
+xdr
+ Shows how to save/load the object model to/from XDR (eXternal Data
+ Representation) binary format using the XDR API provided as part of
+ Sun RPC.
diff --git a/xsd-examples/cxx/tree/binary/boost/.gitignore b/xsd-examples/cxx/tree/binary/boost/.gitignore
new file mode 100644
index 0000000..c116ec1
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/boost/.gitignore
@@ -0,0 +1 @@
+library.?xx
diff --git a/xsd-examples/cxx/tree/binary/boost/README b/xsd-examples/cxx/tree/binary/boost/README
new file mode 100644
index 0000000..6cdd2dd
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/boost/README
@@ -0,0 +1,49 @@
+This example shows how to save/load the object model to/from a custom
+format using the Boost serialization library as an example. You will
+need the Boost serialization library[1] installed in order to build
+and run this example.
+
+[1] http://www.boost.org
+
+The example consists of the following files:
+
+library.xsd
+ XML Schema which describes a library of books.
+
+library.xml
+ Sample XML instance document.
+
+boost-archive-extraction.hxx
+boost-archive-insertion.hxx
+ Boost archive insertion and extraction operators for fundamental
+ types. You will need to provide a similar set of operators for
+ your own stream types.
+
+library-prologue.hxx
+ Contains a number of #include directives that are inserted into
+ the generated code by the XSD compiler. The included files are:
+ boost/archive/text_oarchive.hpp, boost/archive/text_oarchive.hpp,
+ boost-archive-insertion.hxx, and boost-archive-insertion.hxx.
+
+library.hxx
+library.cxx
+ C++ types that represent the given vocabulary as well as Boost
+ archive insertion and extraction operations. These are generated
+ by the XSD compiler from library.xsd. The --hxx-prologue-file
+ option is used to insert the contents of the library-prologue.hxx
+ file into the generated header file. The --generate-insertion and
+ --generate-extraction options are used to generate the insertion
+ and extraction operations for text_oarchive and text_iarchive
+ types.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input XML file. It then
+ saves the object model to text_oarchive and loads it back from
+ text_iarchive. Additionally, it prints the resulting text
+ representation as well as the content of the object model before
+ saving it to text_oarchive and after loading it from text_iarchive.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver library.xml
diff --git a/xsd-examples/cxx/tree/binary/boost/boost-archive-extraction.hxx b/xsd-examples/cxx/tree/binary/boost/boost-archive-extraction.hxx
new file mode 100644
index 0000000..93241da
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/boost/boost-archive-extraction.hxx
@@ -0,0 +1,188 @@
+// file : cxx/tree/binary/boost/boost-archive-insertion.cxx
+// copyright : not copyrighted - public domain
+
+#ifndef BOOST_ARCHIVE_EXTRACTION_HXX
+#define BOOST_ARCHIVE_EXTRACTION_HXX
+
+#include <cstddef> // std::size_t
+#include <string>
+
+#include <xsd/cxx/tree/buffer.hxx>
+#include <xsd/cxx/tree/istream.hxx>
+
+#include <boost/cstdint.hpp>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // as_size
+ //
+ template <typename Archive, typename T>
+ inline istream<Archive>&
+ operator>> (istream<Archive>& s, istream_common::as_size<T>& x)
+ {
+ std::size_t r;
+ s.impl () >> r;
+ x.x_ = static_cast<T> (r);
+ return s;
+ }
+
+ // 8-bit
+ //
+ template <typename Archive, typename T>
+ inline istream<Archive>&
+ operator>> (istream<Archive>& s, istream_common::as_int8<T>& x)
+ {
+ boost::int8_t r;
+ s.impl () >> r;
+ x.x_ = static_cast<T> (r);
+ return s;
+ }
+
+ template <typename Archive, typename T>
+ inline istream<Archive>&
+ operator>> (istream<Archive>& s, istream_common::as_uint8<T>& x)
+ {
+ boost::uint8_t r;
+ s.impl () >> r;
+ x.x_ = static_cast<T> (r);
+ return s;
+ }
+
+
+ // 16-bit
+ //
+ template <typename Archive, typename T>
+ inline istream<Archive>&
+ operator>> (istream<Archive>& s, istream_common::as_int16<T>& x)
+ {
+ boost::int16_t r;
+ s.impl () >> r;
+ x.x_ = static_cast<T> (r);
+ return s;
+ }
+
+ template <typename Archive, typename T>
+ inline istream<Archive>&
+ operator>> (istream<Archive>& s, istream_common::as_uint16<T>& x)
+ {
+ boost::uint16_t r;
+ s.impl () >> r;
+ x.x_ = static_cast<T> (r);
+ return s;
+ }
+
+
+ // 32-bit
+ //
+ template <typename Archive, typename T>
+ inline istream<Archive>&
+ operator>> (istream<Archive>& s, istream_common::as_int32<T>& x)
+ {
+ boost::int32_t r;
+ s.impl () >> r;
+ x.x_ = static_cast<T> (r);
+ return s;
+ }
+
+ template <typename Archive, typename T>
+ inline istream<Archive>&
+ operator>> (istream<Archive>& s, istream_common::as_uint32<T>& x)
+ {
+ boost::uint32_t r;
+ s.impl () >> r;
+ x.x_ = static_cast<T> (r);
+ return s;
+ }
+
+
+ // 64-bit
+ //
+ template <typename Archive, typename T>
+ inline istream<Archive>&
+ operator>> (istream<Archive>& s, istream_common::as_int64<T>& x)
+ {
+ boost::int64_t r;
+ s.impl () >> r;
+ x.x_ = static_cast<T> (r);
+ return s;
+ }
+
+ template <typename Archive, typename T>
+ inline istream<Archive>&
+ operator>> (istream<Archive>& s, istream_common::as_uint64<T>& x)
+ {
+ boost::uint64_t r;
+ s.impl () >> r;
+ x.x_ = static_cast<T> (r);
+ return s;
+ }
+
+
+ // Boolean
+ //
+ template <typename Archive, typename T>
+ inline istream<Archive>&
+ operator>> (istream<Archive>& s, istream_common::as_bool<T>& x)
+ {
+ bool r;
+ s.impl () >> r;
+ x.x_ = static_cast<T> (r);
+ return s;
+ }
+
+
+ // Floating-point
+ //
+ template <typename Archive, typename T>
+ inline istream<Archive>&
+ operator>> (istream<Archive>& s, istream_common::as_float32<T>& x)
+ {
+ float r;
+ s.impl () >> r;
+ x.x_ = static_cast<T> (r);
+ return s;
+ }
+
+ template <typename Archive, typename T>
+ inline istream<Archive>&
+ operator>> (istream<Archive>& s, istream_common::as_float64<T>& x)
+ {
+ double r;
+ s.impl () >> r;
+ x.x_ = static_cast<T> (r);
+ return s;
+ }
+
+ // Extraction of std::basic_string.
+ //
+
+ template <typename Archive, typename C>
+ inline istream<Archive>&
+ operator>> (istream<Archive>& s, std::basic_string<C>& x)
+ {
+ s.impl () >> x;
+ return s;
+ }
+
+
+ // Extraction of a binary buffer.
+ //
+ template <typename Archive, typename C>
+ istream<Archive>&
+ operator>> (istream<Archive>& s, buffer<C>& x)
+ {
+ std::size_t size;
+ s.impl () >> size;
+ x.size (size);
+ s.impl ().load_binary (x.data (), size);
+ return s;
+ }
+ }
+ }
+}
+
+#endif // BOOST_ARCHIVE_EXTRACTION_HXX
diff --git a/xsd-examples/cxx/tree/binary/boost/boost-archive-insertion.hxx b/xsd-examples/cxx/tree/binary/boost/boost-archive-insertion.hxx
new file mode 100644
index 0000000..b2f7936
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/boost/boost-archive-insertion.hxx
@@ -0,0 +1,177 @@
+// file : cxx/tree/binary/boost/boost-archive-insertion.cxx
+// copyright : not copyrighted - public domain
+
+#ifndef BOOST_ARCHIVE_INSERTION_HXX
+#define BOOST_ARCHIVE_INSERTION_HXX
+
+#include <cstddef> // std::size_t
+#include <string>
+
+#include <xsd/cxx/tree/buffer.hxx>
+#include <xsd/cxx/tree/ostream.hxx>
+
+#include <boost/cstdint.hpp>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // as_size
+ //
+ template <typename Archive, typename T>
+ inline ostream<Archive>&
+ operator<< (ostream<Archive>& s, ostream_common::as_size<T> x)
+ {
+ std::size_t v (static_cast<std::size_t> (x.x_));
+ s.impl () << v;
+ return s;
+ }
+
+ // 8-bit
+ //
+ template <typename Archive, typename T>
+ inline ostream<Archive>&
+ operator<< (ostream<Archive>& s, ostream_common::as_int8<T> x)
+ {
+ boost::int8_t v (static_cast<boost::int8_t> (x.x_));
+ s.impl () << v;
+ return s;
+ }
+
+ template <typename Archive, typename T>
+ inline ostream<Archive>&
+ operator<< (ostream<Archive>& s, ostream_common::as_uint8<T> x)
+ {
+ boost::uint8_t v (static_cast<boost::uint8_t> (x.x_));
+ s.impl () << v;
+ return s;
+ }
+
+
+ // 16-bit
+ //
+ template <typename Archive, typename T>
+ inline ostream<Archive>&
+ operator<< (ostream<Archive>& s, ostream_common::as_int16<T> x)
+ {
+ boost::int16_t v (static_cast<boost::int16_t> (x.x_));
+ s.impl () << v;
+ return s;
+ }
+
+ template <typename Archive, typename T>
+ inline ostream<Archive>&
+ operator<< (ostream<Archive>& s, ostream_common::as_uint16<T> x)
+ {
+ boost::uint16_t v (static_cast<boost::uint16_t> (x.x_));
+ s.impl () << v;
+ return s;
+ }
+
+
+ // 32-bit
+ //
+ template <typename Archive, typename T>
+ inline ostream<Archive>&
+ operator<< (ostream<Archive>& s, ostream_common::as_int32<T> x)
+ {
+ boost::int32_t v (static_cast<boost::int32_t> (x.x_));
+ s.impl () << v;
+ return s;
+ }
+
+ template <typename Archive, typename T>
+ inline ostream<Archive>&
+ operator<< (ostream<Archive>& s, ostream_common::as_uint32<T> x)
+ {
+ boost::uint32_t v (static_cast<boost::uint32_t> (x.x_));
+ s.impl () << v;
+ return s;
+ }
+
+
+ // 64-bit
+ //
+ template <typename Archive, typename T>
+ inline ostream<Archive>&
+ operator<< (ostream<Archive>& s, ostream_common::as_int64<T> x)
+ {
+ boost::int64_t v (static_cast<boost::int64_t> (x.x_));
+ s.impl () << v;
+ return s;
+ }
+
+ template <typename Archive, typename T>
+ inline ostream<Archive>&
+ operator<< (ostream<Archive>& s, ostream_common::as_uint64<T> x)
+ {
+ boost::uint64_t v (static_cast<boost::uint64_t> (x.x_));
+ s.impl () << v;
+ return s;
+ }
+
+
+ // Boolean
+ //
+ template <typename Archive, typename T>
+ inline ostream<Archive>&
+ operator<< (ostream<Archive>& s, ostream_common::as_bool<T> x)
+ {
+ bool v (static_cast<bool> (x.x_));
+ s.impl () << v;
+ return s;
+ }
+
+
+ // Floating-point
+ //
+ template <typename Archive, typename T>
+ inline ostream<Archive>&
+ operator<< (ostream<Archive>& s, ostream_common::as_float32<T> x)
+ {
+ float v (static_cast<float> (x.x_));
+ s.impl () << v;
+ return s;
+ }
+
+ template <typename Archive, typename T>
+ inline ostream<Archive>&
+ operator<< (ostream<Archive>& s, ostream_common::as_float64<T> x)
+ {
+ double v (static_cast<double> (x.x_));
+ s.impl () << v;
+ return s;
+ }
+
+
+ // Insertion of std::basic_string.
+ //
+ template <typename Archive, typename C>
+ inline ostream<Archive>&
+ operator<< (ostream<Archive>& s, const std::basic_string<C>& x)
+ {
+ s.impl () << x;
+ return s;
+ }
+
+
+ // Insertion of a binary buffer.
+ //
+ template <typename Archive, typename C>
+ ostream<Archive>&
+ operator<< (ostream<Archive>& s, const buffer<C>& x)
+ {
+ // Boost.Serialization needs an lvalue.
+ //
+ std::size_t size (x.size());
+ s.impl () << size;
+ s.impl ().save_binary (x.data (), x.size ());
+ return s;
+ }
+ }
+ }
+}
+
+#endif // BOOST_ARCHIVE_INSERTION_HXX
diff --git a/xsd-examples/cxx/tree/binary/boost/buildfile b/xsd-examples/cxx/tree/binary/boost/buildfile
new file mode 100644
index 0000000..4306273
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/boost/buildfile
@@ -0,0 +1,32 @@
+# file : cxx/tree/binary/boost/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+import libs += libboost-serialization%lib{boost_serialization}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -library} {hxx ixx cxx}{library} $libs
+
+exe{driver}: xml{library}: test.input = true
+
+<{hxx ixx cxx}{library}>: xsd{library} hxx{library-prologue} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-ostream \
+ --hxx-prologue-file $path($<[1]) \
+ --generate-insertion 'boost::archive::text_oarchive' \
+ --generate-extraction 'boost::archive::text_iarchive' \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/binary/boost/driver.cxx b/xsd-examples/cxx/tree/binary/boost/driver.cxx
new file mode 100644
index 0000000..d1d08d9
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/boost/driver.cxx
@@ -0,0 +1,72 @@
+// file : cxx/tree/binary/boost/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <cstring> // std::memcpy
+#include <sstream>
+#include <iostream>
+
+// You can generate insertion/extraction code for other archive
+// types (for example, binary, XML, etc).
+//
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#include "library.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;
+ using boost::archive::text_oarchive;
+ using boost::archive::text_iarchive;
+
+ // Read in the file.
+ //
+ std::unique_ptr<catalog> c (catalog_ (argv[1]));
+
+ cerr << *c << endl;
+
+ // Save into a text archive.
+ //
+ std::ostringstream ostr;
+ text_oarchive oa (ostr);
+ xml_schema::ostream<text_oarchive> os (oa);
+
+ os << *c;
+
+ // Print the text representation.
+ //
+ std::string str (ostr.str ());
+
+ cerr << endl
+ << "text representation: " << endl
+ << str << endl;
+
+ // Load from a text archive.
+ //
+ std::istringstream istr (str);
+ text_iarchive ia (istr);
+ xml_schema::istream<text_iarchive> is (ia);
+
+ std::unique_ptr<catalog> copy (new catalog (is));
+
+ cerr << *copy << endl;
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/tree/binary/boost/library-prologue.hxx b/xsd-examples/cxx/tree/binary/boost/library-prologue.hxx
new file mode 100644
index 0000000..ba0d35f
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/boost/library-prologue.hxx
@@ -0,0 +1,9 @@
+// Include declarations for the archive types.
+//
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+// Include insertion/extraction operators for fundamental types.
+//
+#include "boost-archive-insertion.hxx"
+#include "boost-archive-extraction.hxx"
diff --git a/xsd-examples/cxx/tree/binary/boost/library.xml b/xsd-examples/cxx/tree/binary/boost/library.xml
new file mode 100644
index 0000000..6368f44
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/boost/library.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/binary/boost/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">
+ <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/tree/binary/boost/library.xsd b/xsd-examples/cxx/tree/binary/boost/library.xsd
new file mode 100644
index 0000000..3959788
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/boost/library.xsd
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/binary/boost/library.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension"
+ 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:language"/>
+ </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:date"/>
+ <xsd:element name="died" type="xsd:date" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="author">
+ <xsd:complexContent>
+ <xsd:extension base="lib:person">
+ <xsd:attribute name="recommends" type="xsd:IDREF" xse:refType="lib: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" default="true"/>
+ <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/tree/binary/cdr/.gitignore b/xsd-examples/cxx/tree/binary/cdr/.gitignore
new file mode 100644
index 0000000..c116ec1
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/cdr/.gitignore
@@ -0,0 +1 @@
+library.?xx
diff --git a/xsd-examples/cxx/tree/binary/cdr/README b/xsd-examples/cxx/tree/binary/cdr/README
new file mode 100644
index 0000000..914d27c
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/cdr/README
@@ -0,0 +1,36 @@
+This example shows how to save/load the object model to/from CDR
+(Common Data Representation) binary format using ACE CDR streams.
+Support for other data representation streams can be easily added. You
+will need the ACE library[1] installed in order to build and run this
+example.
+
+[1] http://www.cs.wustl.edu/~schmidt/ACE.html
+
+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
+library.cxx
+ C++ types that represent the given vocabulary as well as data
+ representation stream insertion and extraction operations. These
+ are generated by XSD from library.xsd. Note that the
+ --generate-insertion and --generate-extraction options are used
+ to generate the insertion and extraction operations for ACE CDR
+ stream.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input XML file. It then
+ saves the object model to ACE_OuputCDR and loads it back from
+ ACE_InputCDR. Additionally, it prints the resulting binary
+ representation as well as the content of the object model before
+ saving it to the CDR stream and after loading it from the CDR stream.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver library.xml
diff --git a/xsd-examples/cxx/tree/binary/cdr/buildfile b/xsd-examples/cxx/tree/binary/cdr/buildfile
new file mode 100644
index 0000000..d78a56a
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/cdr/buildfile
@@ -0,0 +1,28 @@
+# file : cxx/tree/binary/cdr/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+import libs += libace%lib{ACE}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -library} {hxx ixx cxx}{library} $libs
+
+exe{driver}: xml{library}: test.input = true
+
+<{hxx ixx cxx}{library}>: xsd{library} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-ostream \
+ --generate-insertion 'ACE_OutputCDR' \
+ --generate-extraction 'ACE_InputCDR' \
+ --generate-comparison \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
diff --git a/xsd-examples/cxx/tree/binary/cdr/driver.cxx b/xsd-examples/cxx/tree/binary/cdr/driver.cxx
new file mode 100644
index 0000000..2ab0674
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/cdr/driver.cxx
@@ -0,0 +1,87 @@
+// file : cxx/tree/binary/cdr/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <cstring> // std::memcpy
+#include <iostream>
+
+#include <ace/Log_Msg.h> // ACE_HEX_DUMP
+#include <ace/CDR_Stream.h>
+
+// The following two headers define XSD-specific insertion/extraction
+// operations for ACE CDR streams. You can use the content of these
+// headers as a guide to implementing insertion/extraction to/from
+// your own data representation streams:
+//
+// xsd/cxx/tree/ace-cdr-stream-insertion.hxx
+// xsd/cxx/tree/ace-cdr-stream-extraction.hxx
+
+#include "library.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;
+
+ // Read in the file.
+ //
+ std::unique_ptr<catalog> c (catalog_ (argv[1]));
+
+ cerr << *c << endl;
+
+ // Save to a CDR stream.
+ //
+ ACE_OutputCDR ace_ocdr;
+ xml_schema::ostream<ACE_OutputCDR> ocdr (ace_ocdr);
+
+ ocdr << *c;
+
+ // Print the binary representation and at the same time save
+ // it into a continuous buffer.
+ //
+ cerr << endl
+ << "binary representation size: " << ace_ocdr.total_length () << endl;
+
+ xml_schema::buffer buf (ace_ocdr.total_length ());
+ char* data (buf.data ());
+
+ for (const ACE_Message_Block* mb = ace_ocdr.begin ();
+ mb != 0;
+ mb = mb->cont ())
+ {
+ std::memcpy (data, mb->rd_ptr (), mb->length ());
+ data += mb->length ();
+
+ ACE_HEX_DUMP ((LM_DEBUG, mb->rd_ptr (), mb->length ()));
+ }
+
+ // Load from a CDR stream. Note that ACE_InputCDR expects the
+ // buffer to be properly aligned. Since our buffer is dynamically
+ // allocated, its alignment should be good enough.
+ //
+ ACE_InputCDR ace_icdr (buf.data (), buf.size ());
+ xml_schema::istream<ACE_InputCDR> icdr (ace_icdr);
+
+ std::unique_ptr<catalog> copy (new catalog (icdr));
+
+ cerr << *copy << endl;
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+
+ return 0; // ACE makes our main() an ordinary function.
+}
diff --git a/xsd-examples/cxx/tree/binary/cdr/library.xml b/xsd-examples/cxx/tree/binary/cdr/library.xml
new file mode 100644
index 0000000..5700131
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/cdr/library.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/binary/cdr/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">
+ <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/tree/binary/cdr/library.xsd b/xsd-examples/cxx/tree/binary/cdr/library.xsd
new file mode 100644
index 0000000..c7f056e
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/cdr/library.xsd
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/binary/cdr/library.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension"
+ 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:language"/>
+ </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:date"/>
+ <xsd:element name="died" type="xsd:date" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="author">
+ <xsd:complexContent>
+ <xsd:extension base="lib:person">
+ <xsd:attribute name="recommends" type="xsd:IDREF" xse:refType="lib: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" default="true"/>
+ <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/tree/binary/xdr/.gitignore b/xsd-examples/cxx/tree/binary/xdr/.gitignore
new file mode 100644
index 0000000..c116ec1
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/xdr/.gitignore
@@ -0,0 +1 @@
+library.?xx
diff --git a/xsd-examples/cxx/tree/binary/xdr/README b/xsd-examples/cxx/tree/binary/xdr/README
new file mode 100644
index 0000000..e02b2b9
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/xdr/README
@@ -0,0 +1,36 @@
+This example shows how to save/load the object model to/from XDR
+(eXternal Data Representation) binary format using XDR streams.
+The XDR API is available on most UNIX and GNU/Linux systems as part
+of Sun RPC (libtirpc-dev package on Debian/Ubuntu, libtirpc-devel
+package on Fedora/RHEL, and as a part of the Standard C Library on
+FreeBSD and MacOS). On Windows you may need to install a third-party
+library which provides the XDR API.
+
+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
+library.cxx
+ C++ types that represent the given vocabulary as well as data
+ representation stream insertion and extraction operations. These
+ are generated by XSD from library.xsd. Note that the
+ --generate-insertion and --generate-extraction options are used
+ to generate the insertion and extraction operations for XDR
+ stream.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input XML file. It then
+ saves the object model to the XDR representation and loads it back.
+ Additionally, it prints the content of the object model before saving
+ it to the XDR representation and after loading it from the XDR
+ representation.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver library.xml
diff --git a/xsd-examples/cxx/tree/binary/xdr/buildfile b/xsd-examples/cxx/tree/binary/xdr/buildfile
new file mode 100644
index 0000000..92f0c48
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/xdr/buildfile
@@ -0,0 +1,30 @@
+# file : cxx/tree/binary/xdr/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+if ($cxx.target.class == 'linux')
+ import libs += libtirpc%lib{tirpc}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -library} {hxx ixx cxx}{library} $libs
+
+exe{driver}: xml{library}: test.input = true
+
+<{hxx ixx cxx}{library}>: xsd{library} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-ostream \
+ --generate-insertion 'XDR' \
+ --generate-extraction 'XDR' \
+ --generate-comparison \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
diff --git a/xsd-examples/cxx/tree/binary/xdr/driver.cxx b/xsd-examples/cxx/tree/binary/xdr/driver.cxx
new file mode 100644
index 0000000..f706ebf
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/xdr/driver.cxx
@@ -0,0 +1,148 @@
+// file : cxx/tree/binary/xdr/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <cstring> // std::memcpy
+#include <cstddef> // std::size_t
+#include <iostream>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#include "library.hxx"
+
+using std::cerr;
+using std::endl;
+using std::size_t;
+
+// XDR output functions. Their implementations are provided after main().
+//
+struct underflow_info
+{
+ xml_schema::buffer* buf;
+ size_t pos;
+};
+
+extern "C" int
+overflow (void* user_data, char* buf, int n);
+
+extern "C" int
+underflow (void* user_data, char* buf, int n);
+
+// The xdrrec_create function (used below) has slightly different
+// prototypes on different platforms. To make this example portable
+// we will need to cast the actual function to the following common
+// prototype.
+//
+extern "C"
+typedef void (*xdrrec_create_p) (
+ XDR*,
+ unsigned int write_size,
+ unsigned int read_size,
+ void* user_data,
+ int (*read) (void* user_data, char* buf, int n),
+ int (*write) (void* user_data, char* buf, int n));
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " library.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace library;
+
+ xdrrec_create_p xdrrec_create_ =
+ reinterpret_cast<xdrrec_create_p> (::xdrrec_create);
+
+ // Read in the file.
+ //
+ std::unique_ptr<catalog> c (catalog_ (argv[1]));
+
+ cerr << *c << endl;
+
+ // Save to an XDR stream.
+ //
+ XDR xdr;
+ xml_schema::buffer buf;
+
+ xdrrec_create_ (&xdr, 0, 0, reinterpret_cast<char*> (&buf), 0, &overflow);
+ xdr.x_op = XDR_ENCODE;
+
+ xml_schema::ostream<XDR> oxdr (xdr);
+
+ oxdr << *c;
+
+ xdrrec_endofrecord (&xdr, true); // Flush the data.
+ xdr_destroy (&xdr);
+
+ // The binary representation is now in the memory buffer 'buf'.
+ // To get to the raw data use buf.data() and buf.size().
+ //
+ cerr << endl
+ << "binary representation size: " << buf.size () << endl;
+
+ // Load from an XDR stream.
+ //
+ underflow_info ui;
+ ui.buf = &buf;
+ ui.pos = 0;
+
+ xdrrec_create_ (&xdr, 0, 0, reinterpret_cast<char*> (&ui), &underflow, 0);
+ xdr.x_op = XDR_DECODE;
+
+ xdrrec_skiprecord (&xdr);
+
+ xml_schema::istream<XDR> ixdr (xdr);
+
+ std::unique_ptr<catalog> copy (new catalog (ixdr));
+
+ xdr_destroy (&xdr);
+
+ cerr << *copy << endl;
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
+
+extern "C" int
+overflow (void* p, char* buf, int n_)
+{
+ xml_schema::buffer* dst (reinterpret_cast<xml_schema::buffer*> (p));
+ size_t n (static_cast<size_t> (n_));
+
+ size_t size (dst->size ());
+ size_t capacity (dst->capacity ());
+
+ // Implement exponential growth.
+ //
+ if (size + n > capacity && size + n < capacity * 2)
+ dst->capacity (capacity * 2);
+
+ dst->size (size + n);
+ std::memcpy (dst->data () + size, buf, n);
+
+ return n;
+}
+
+extern "C" int
+underflow (void* p, char* buf, int n_)
+{
+ underflow_info* ui (reinterpret_cast<underflow_info*> (p));
+ size_t n (static_cast<size_t> (n_));
+
+ size_t size (ui->buf->size () - ui->pos);
+ n = size > n ? n : size;
+
+ std::memcpy (buf, ui->buf->data () + ui->pos, n);
+ ui->pos += n;
+
+ return n;
+}
diff --git a/xsd-examples/cxx/tree/binary/xdr/library.xml b/xsd-examples/cxx/tree/binary/xdr/library.xml
new file mode 100644
index 0000000..05ed593
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/xdr/library.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/binary/xdr/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">
+ <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/tree/binary/xdr/library.xsd b/xsd-examples/cxx/tree/binary/xdr/library.xsd
new file mode 100644
index 0000000..8e1b316
--- /dev/null
+++ b/xsd-examples/cxx/tree/binary/xdr/library.xsd
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/binary/xdr/library.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension"
+ 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:language"/>
+ </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:date"/>
+ <xsd:element name="died" type="xsd:date" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="author">
+ <xsd:complexContent>
+ <xsd:extension base="lib:person">
+ <xsd:attribute name="recommends" type="xsd:IDREF" xse:refType="lib: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" default="true"/>
+ <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/tree/buildfile b/xsd-examples/cxx/tree/buildfile
new file mode 100644
index 0000000..3345cfb
--- /dev/null
+++ b/xsd-examples/cxx/tree/buildfile
@@ -0,0 +1,6 @@
+# file : cxx/tree/buildfile
+# license : not copyrighted - public domain
+
+# Exclude examples which depend on not yet packaged libraries.
+#
+./: {*/ -binary/ -xpath/} doc{README}
diff --git a/xsd-examples/cxx/tree/caching/.gitignore b/xsd-examples/cxx/tree/caching/.gitignore
new file mode 100644
index 0000000..c116ec1
--- /dev/null
+++ b/xsd-examples/cxx/tree/caching/.gitignore
@@ -0,0 +1 @@
+library.?xx
diff --git a/xsd-examples/cxx/tree/caching/README b/xsd-examples/cxx/tree/caching/README
new file mode 100644
index 0000000..64dffb3
--- /dev/null
+++ b/xsd-examples/cxx/tree/caching/README
@@ -0,0 +1,29 @@
+This example shows how to use the C++/Tree mapping to parse several
+XML documents while reusing the underlying XML parser and caching the
+schemas used for validation.
+
+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
+library.cxx
+ C++ types that represent the given vocabulary and a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model. These are generated by XSD from library.xsd.
+
+driver.cxx
+ Driver for the example. It first sets up the Xerces-C++ DOM parser
+ and caches the library.xsd schema for validation. It then performs
+ ten iterations that parse the input file to a DOM document using
+ the DOM parser and call one of the parsing functions that constructs
+ the object model from this DOM document. On each iteration the driver
+ prints a number of books in the object model to STDERR.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver library.xml library.xsd
diff --git a/xsd-examples/cxx/tree/caching/buildfile b/xsd-examples/cxx/tree/caching/buildfile
new file mode 100644
index 0000000..cb369b7
--- /dev/null
+++ b/xsd-examples/cxx/tree/caching/buildfile
@@ -0,0 +1,27 @@
+# file : cxx/tree/caching/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} {hxx ixx cxx}{library} $libs
+
+exe{driver}: {xml xsd}{library}: test.input = true
+
+<{hxx ixx cxx}{library}>: xsd{library} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/caching/driver.cxx b/xsd-examples/cxx/tree/caching/driver.cxx
new file mode 100644
index 0000000..9cabbd4
--- /dev/null
+++ b/xsd-examples/cxx/tree/caching/driver.cxx
@@ -0,0 +1,165 @@
+// file : cxx/tree/caching/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_*
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/validators/common/Grammar.hpp> // xercesc::Grammar
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+
+#include <xsd/cxx/tree/error-handler.hxx>
+
+#include "library.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 3)
+ {
+ cerr << "usage: " << argv[0] << " library.xml library.xsd" << endl;
+ return 1;
+ }
+
+ int r (0);
+
+ // We need to initialize the Xerces-C++ runtime because we
+ // are doing the XML-to-DOM parsing ourselves.
+ //
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ using namespace xercesc;
+ namespace xml = xsd::cxx::xml;
+ namespace tree = xsd::cxx::tree;
+
+ const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+ xml::dom::unique_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, true);
+ conf->setParameter (XMLUni::fgXercesSchema, true);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support.
+ //
+#if _XERCES_VERSION >= 30100
+ conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+#endif
+
+ // Set error handler.
+ //
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+ // Initialize the schema cache.
+ //
+ if (!parser->loadGrammar (argv[2], Grammar::SchemaGrammarType, true))
+ {
+ // In Xerces-C++ grammar loading failure results in just a warning.
+ // Make it a fatal error.
+ //
+ eh.handle (argv[2], 0, 0,
+ tree::error_handler<char>::severity::fatal,
+ "unable to load schema");
+ }
+
+ eh.throw_if_failed<xml_schema::parsing> ();
+
+ // Use the loaded grammar during parsing.
+ //
+ conf->setParameter (XMLUni::fgXercesUseCachedGrammarInParse, true);
+
+ // Disable loading schemas via other means (e.g., schemaLocation).
+ //
+ conf->setParameter (XMLUni::fgXercesLoadSchema, false);
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ // Parse XML documents.
+ //
+ for (unsigned long i (0); i < 10; ++i)
+ {
+ ifstream ifs;
+ ifs.exceptions (ifstream::badbit | ifstream::failbit);
+ ifs.open (argv[1]);
+
+ // Wrap the standard input stream.
+ //
+ xml::sax::std_input_source isrc (ifs, argv[1]);
+ Wrapper4InputSource wrap (&isrc, false);
+
+ // Parse XML to DOM.
+ //
+ xml_schema::dom::unique_ptr<DOMDocument> doc (parser->parse (&wrap));
+
+ eh.throw_if_failed<xml_schema::parsing> ();
+
+ // Parse DOM to the object model.
+ //
+ unique_ptr<library::catalog> c (library::catalog_ (*doc));
+
+ cerr << "catalog with " << c->book ().size () << " books" << endl;
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ r = 1;
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+ return r;
+}
diff --git a/xsd-examples/cxx/tree/caching/library.xml b/xsd-examples/cxx/tree/caching/library.xml
new file mode 100644
index 0000000..b36786f
--- /dev/null
+++ b/xsd-examples/cxx/tree/caching/library.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/caching/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">
+ <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/tree/caching/library.xsd b/xsd-examples/cxx/tree/caching/library.xsd
new file mode 100644
index 0000000..2dd5037
--- /dev/null
+++ b/xsd-examples/cxx/tree/caching/library.xsd
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/caching/library.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension"
+ 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:language"/>
+ </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:date"/>
+ <xsd:element name="died" type="xsd:date" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="author">
+ <xsd:complexContent>
+ <xsd:extension base="lib:person">
+ <xsd:attribute name="recommends" type="xsd:IDREF" xse:refType="lib: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" default="true"/>
+ <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/tree/compression/.gitignore b/xsd-examples/cxx/tree/compression/.gitignore
new file mode 100644
index 0000000..f7293f9
--- /dev/null
+++ b/xsd-examples/cxx/tree/compression/.gitignore
@@ -0,0 +1,2 @@
+library.?xx
+out.xml.gz
diff --git a/xsd-examples/cxx/tree/compression/README b/xsd-examples/cxx/tree/compression/README
new file mode 100644
index 0000000..f163970
--- /dev/null
+++ b/xsd-examples/cxx/tree/compression/README
@@ -0,0 +1,48 @@
+This example shows how to compress an XML document during serialization
+and decompress it during parsing. The example uses the compression
+functionality provided by the zlib library[1] which needs to be installed
+in order to build and run this example. It should also be fairly straight-
+forward to modify the code in this example to use other compression
+libraries.
+
+[1] http://www.zlib.net
+
+The example consists of the following files:
+
+library.xsd
+ XML Schema which describes a library of books.
+
+library.xml.gz
+ Sample XML instance document compressed using the gzip format.
+
+compressed-format-target.hxx
+compressed-format-target.cxx
+ Implementation of the Xerces-C++ XMLFormatTarget interface with the on-
+ the-fly compression support. You can use it in your application to add
+ XML compression.
+
+compressed-input-source.hxx
+compressed-input-source.cxx
+ Implementation of the Xerces-C++ InputSource interface with the on-the-
+ fly decompression support. You can use it in your application to add
+ XML decompression.
+
+library.hxx
+library.cxx
+ C++ types that represent the given vocabulary and a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model. These are generated by XSD from library.xsd.
+
+driver.cxx
+ Driver for the example. It first creates the compressed_input_source
+ object and passes it to one of the parsing functions that constructs
+ the object model from the compressed input file. It then prints the
+ content of the object model to STDERR. Finally, the driver creates the
+ compressed_format_target object and passes it to one of the serialization
+ functions which converts the object model back to the compressed XML.
+
+To run the example on the sample XML document simply execute:
+
+$ ./driver library.xml.gz
+
+The serialization output is written to the out.xml.gz file.
diff --git a/xsd-examples/cxx/tree/compression/buildfile b/xsd-examples/cxx/tree/compression/buildfile
new file mode 100644
index 0000000..6997339
--- /dev/null
+++ b/xsd-examples/cxx/tree/compression/buildfile
@@ -0,0 +1,28 @@
+# file : cxx/tree/compression/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+import libs += libz%lib{z}
+
+./: exe{driver} file{library.xml.gz} doc{README}
+
+exe{driver}: {hxx cxx}{* -library} {hxx ixx cxx}{library} $libs testscript
+
+<{hxx ixx cxx}{library}>: xsd{library} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-serialization \
+ --generate-ostream \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/compression/compressed-format-target.cxx b/xsd-examples/cxx/tree/compression/compressed-format-target.cxx
new file mode 100644
index 0000000..2d150a0
--- /dev/null
+++ b/xsd-examples/cxx/tree/compression/compressed-format-target.cxx
@@ -0,0 +1,152 @@
+// file : cxx/tree/compression/compressed-format-target.cxx
+// copyright : not copyrighted - public domain
+
+#include <ostream>
+#include <cstring> // std::memcpy
+
+#include "compressed-format-target.hxx"
+
+using namespace std;
+
+//
+// compression_failure
+//
+
+const char* compression_failure::
+what () const throw ()
+{
+ return "compression failure";
+}
+
+//
+// compressed_format_target
+//
+
+compressed_format_target::
+compressed_format_target (ostream& os, compression_type t)
+ : os_ (os), closed_ (false), n_ (0)
+ {
+ zs_.zalloc = Z_NULL;
+ zs_.zfree = Z_NULL;
+ zs_.opaque = Z_NULL;
+
+ int window = 0;
+
+ switch (t)
+ {
+ case raw:
+ {
+ window = -15;
+ break;
+ }
+ case zlib:
+ {
+ window = 15;
+ break;
+ }
+ case gzip:
+ {
+ window = 16 + 15;
+ break;
+ }
+ }
+
+ int r (deflateInit2 (&zs_,
+ Z_DEFAULT_COMPRESSION,
+ Z_DEFLATED,
+ window,
+ 8,
+ Z_DEFAULT_STRATEGY));
+ if (r != Z_OK)
+ throw compression_failure (r);
+ }
+
+compressed_format_target::
+~compressed_format_target ()
+{
+ try
+ {
+ // Close the free the compression stream.
+ //
+ if (!closed_)
+ close ();
+ }
+ catch (...)
+ {
+ }
+
+ deflateEnd (&zs_);
+}
+
+void compressed_format_target::
+writeChars (const XMLByte* const buf,
+ const XMLSize_t size,
+ xercesc::XMLFormatter* const)
+{
+ // Flush the buffer if the block is too large or if we don't have
+ // any space left.
+ //
+ if ((size >= buf_size_ / 8 || n_ + size > buf_size_) && n_ != 0)
+ {
+ write (in_, n_);
+ n_ = 0;
+ }
+
+ if (size < buf_size_ / 8)
+ {
+ memcpy (in_ + n_, reinterpret_cast<const char*> (buf), size);
+ n_ += size;
+ }
+ else
+ write (reinterpret_cast<const char*> (buf), size);
+}
+
+
+void compressed_format_target::
+flush ()
+{
+ if (n_ != 0)
+ {
+ write (in_, n_);
+ n_ = 0;
+ }
+
+ if (!os_.fail ())
+ os_.flush ();
+}
+
+void compressed_format_target::
+close ()
+{
+ write (in_, n_, true);
+ n_ = 0;
+
+ if (!os_.fail ())
+ os_.flush ();
+
+ closed_ = true;
+}
+
+void compressed_format_target::
+write (const char* buf, size_t size, bool flush)
+{
+ zs_.next_in = reinterpret_cast<Bytef*> (const_cast<char*> (buf));
+ zs_.avail_in = static_cast<uInt> (size);
+
+ do
+ {
+ zs_.next_out = reinterpret_cast<Bytef*> (out_);
+ zs_.avail_out = buf_size_;
+
+ int r (deflate (&zs_, flush ? Z_FINISH : Z_NO_FLUSH));
+
+ if (r != Z_OK && r != Z_BUF_ERROR && r != Z_STREAM_END)
+ throw compression_failure (r);
+
+ size_t n (buf_size_ - zs_.avail_out);
+
+ if (!os_.fail () && n > 0)
+ os_.write (out_, static_cast<streamsize> (n));
+
+ } while (zs_.avail_out == 0);
+}
diff --git a/xsd-examples/cxx/tree/compression/compressed-format-target.hxx b/xsd-examples/cxx/tree/compression/compressed-format-target.hxx
new file mode 100644
index 0000000..0061cfa
--- /dev/null
+++ b/xsd-examples/cxx/tree/compression/compressed-format-target.hxx
@@ -0,0 +1,91 @@
+// file : cxx/tree/compression/compressed-format-target.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef COMPRESSED_FORMAT_TARGET_HXX
+#define COMPRESSED_FORMAT_TARGET_HXX
+
+#include <zlib.h>
+
+#include <iosfwd>
+#include <cstddef> // std::size_t
+#include <exception>
+
+#include <xercesc/framework/XMLFormatter.hpp>
+
+struct compression_failure: std::exception
+{
+ explicit
+ compression_failure (int code)
+ : code_ (code)
+ {
+ }
+
+ int
+ code () const
+ {
+ return code_;
+ }
+
+ const char*
+ message () const
+ {
+ return zError (code_);
+ }
+
+ virtual const char*
+ what () const throw ();
+
+private:
+ int code_;
+};
+
+// Xerces-C++ XMLFormatTarget interface implementation with on-the-fly,
+// zlib-based compression.
+//
+class compressed_format_target: public xercesc::XMLFormatTarget
+{
+public:
+ enum compression_type
+ {
+ raw,
+ zlib,
+ gzip
+ };
+
+ compressed_format_target (std::ostream&, compression_type);
+
+ virtual
+ ~compressed_format_target ();
+
+ virtual void
+ writeChars (const XMLByte* const buf,
+ const XMLSize_t size,
+ xercesc::XMLFormatter* const);
+
+ virtual void
+ flush ();
+
+ // Close the compressed stream by writing out the zlib or gzip trailer.
+ // This function is automatically called from the destructor but you
+ // may want to call it explicitly to be able to catch any exceptions
+ // that it might throw.
+ //
+ void
+ close ();
+
+private:
+ void
+ write (const char* buf, std::size_t size, bool flush = false);
+
+private:
+ std::ostream& os_;
+ z_stream zs_;
+ bool closed_;
+
+ static const std::size_t buf_size_ = 65536;
+ char in_[buf_size_];
+ char out_[buf_size_];
+ size_t n_;
+};
+
+#endif // COMPRESSED_FORMAT_TARGET_HXX
diff --git a/xsd-examples/cxx/tree/compression/compressed-input-source.cxx b/xsd-examples/cxx/tree/compression/compressed-input-source.cxx
new file mode 100644
index 0000000..03be960
--- /dev/null
+++ b/xsd-examples/cxx/tree/compression/compressed-input-source.cxx
@@ -0,0 +1,195 @@
+// file : cxx/tree/compression/compressed-input-source.cxx
+// copyright : not copyrighted - public domain
+
+#include <istream>
+
+#include <xsd/cxx/xml/string.hxx>
+
+#include "compressed-input-source.hxx"
+
+using namespace std;
+using namespace xercesc;
+namespace xml = xsd::cxx::xml;
+
+//
+// decompression_failure
+//
+
+const char* decompression_failure::
+what () const throw ()
+{
+ return "decompression failure";
+}
+
+//
+// compressed_input_source
+//
+
+compressed_input_source::
+compressed_input_source (istream& is, compression_type t)
+ : is_ (&is), type_ (t)
+{
+}
+
+compressed_input_source::
+compressed_input_source (istream& is,
+ compression_type t,
+ const string& sysid)
+ : InputSource (xml::string (sysid).c_str ()), is_ (&is), type_ (t)
+{
+}
+
+compressed_input_source::
+compressed_input_source (istream& is,
+ compression_type t,
+ const string& sysid,
+ const string& pubid)
+ : xercesc::InputSource (xml::string (sysid).c_str (),
+ xml::string (pubid).c_str ()),
+ is_ (&is),
+ type_ (t)
+{
+}
+
+BinInputStream* compressed_input_source::
+makeStream () const
+{
+ if (is_ == 0)
+ throw copy ();
+
+ istream& is (*is_);
+ is_ = 0;
+ return new compressed_input_stream (
+ is, static_cast<compressed_input_stream::compression_type> (type_));
+}
+
+//
+// compressed_input_stream
+//
+
+compressed_input_stream::
+compressed_input_stream (istream& is, compression_type t)
+ : is_ (is), end_ (false), pos_ (0)
+{
+ zs_.zalloc = Z_NULL;
+ zs_.zfree = Z_NULL;
+ zs_.opaque = Z_NULL;
+ zs_.next_in = Z_NULL;
+ zs_.avail_in = 0;
+
+ int window = 0;
+
+ switch (t)
+ {
+ case raw:
+ {
+ window = -15;
+ break;
+ }
+ case zlib:
+ {
+ window = 15;
+ break;
+ }
+ case gzip:
+ {
+ window = 16 + 15;
+ break;
+ }
+ }
+
+ int r (inflateInit2 (&zs_, window));
+
+ if (r != Z_OK)
+ throw decompression_failure (r);
+}
+
+compressed_input_stream::
+~compressed_input_stream ()
+{
+ inflateEnd (&zs_);
+}
+
+XMLFilePos compressed_input_stream::
+curPos () const
+{
+ return static_cast<XMLFilePos> (pos_);
+}
+
+XMLSize_t compressed_input_stream::
+readBytes (XMLByte* const buf, const XMLSize_t size)
+{
+ if (end_)
+ return 0;
+
+ // Keep calling inflate() until we fill up the buffer or reach the
+ // end of stream. If we run out of input data, call the underlying
+ // stream for more.
+ //
+ zs_.next_out = reinterpret_cast<Bytef*> (buf);
+ zs_.avail_out = static_cast<uInt> (size);
+
+ int r;
+
+ do
+ {
+ if (zs_.avail_in == 0)
+ {
+ zs_.avail_in = static_cast<uInt> (read ());
+ zs_.next_in = reinterpret_cast<Bytef*> (const_cast<char*> (in_));
+
+ if (zs_.avail_in == 0)
+ throw decompression_failure (Z_DATA_ERROR);
+ }
+
+ r = inflate (&zs_, Z_NO_FLUSH);
+
+ if (r != Z_OK && r != Z_STREAM_END)
+ throw decompression_failure (r);
+
+ } while (r != Z_STREAM_END && zs_.avail_out != 0);
+
+ if (r == Z_STREAM_END)
+ end_ = true;
+
+ size_t n (size - zs_.avail_out);
+ pos_ += n;
+
+ return static_cast<XMLSize_t> (n);
+}
+
+const XMLCh* compressed_input_stream::
+getContentType () const
+{
+ return 0;
+}
+
+size_t compressed_input_stream::
+read ()
+{
+ // Some implementations don't clear gcount if you call read() on a
+ // stream that is in the eof state.
+ //
+ if (is_.eof ())
+ return 0;
+
+ // Unset the exception failbit while we are working with the stream.
+ //
+ ios_base::iostate old (is_.exceptions ());
+ is_.exceptions (old & ~ios_base::failbit);
+
+ is_.read (in_, static_cast<streamsize> (buf_size_));
+
+ // Clear the fail bit if it was caused by eof and restore the original
+ // exception state. If there are any pending errors then the exception
+ // will be thrown now.
+ //
+ if (is_.fail () && is_.eof ())
+ is_.clear (is_.rdstate () & ~ios_base::failbit);
+
+ is_.exceptions (old);
+
+ // Make sure that if we failed, we won't be called again.
+ //
+ return !is_.fail () ? static_cast<size_t> (is_.gcount ()) : 0;
+}
diff --git a/xsd-examples/cxx/tree/compression/compressed-input-source.hxx b/xsd-examples/cxx/tree/compression/compressed-input-source.hxx
new file mode 100644
index 0000000..706433b
--- /dev/null
+++ b/xsd-examples/cxx/tree/compression/compressed-input-source.hxx
@@ -0,0 +1,121 @@
+// file : cxx/tree/compression/compressed-input-source.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef COMPRESSED_INPUT_SOURCE_HXX
+#define COMPRESSED_INPUT_SOURCE_HXX
+
+#include <zlib.h>
+
+#include <iosfwd>
+#include <string>
+#include <cstddef> // std::size_t
+#include <exception>
+
+#include <xercesc/sax/InputSource.hpp>
+#include <xercesc/util/BinInputStream.hpp>
+
+struct decompression_failure: std::exception
+{
+ explicit
+ decompression_failure (int code)
+ : code_ (code)
+ {
+ }
+
+ int
+ code () const
+ {
+ return code_;
+ }
+
+ const char*
+ message () const
+ {
+ return zError (code_);
+ }
+
+ virtual const char*
+ what () const throw ();
+
+private:
+ int code_;
+};
+
+// Xerces-C++ InputSource interface implementation with on-the-fly, zlib-
+// based decompression.
+//
+class compressed_input_source: public xercesc::InputSource
+{
+public:
+ enum compression_type
+ {
+ raw,
+ zlib,
+ gzip
+ };
+
+ compressed_input_source (std::istream&, compression_type);
+
+ compressed_input_source (std::istream&,
+ compression_type,
+ const std::string& system_id);
+
+ compressed_input_source (std::istream&,
+ compression_type,
+ const std::string& system_id,
+ const std::string& public_id);
+
+ struct copy {};
+
+ // Throws the copy exception if this function is called more than once.
+ //
+ virtual xercesc::BinInputStream*
+ makeStream () const;
+
+private:
+ mutable std::istream* is_;
+ compression_type type_;
+};
+
+// Xerces-C++ BinInputStream interface implementation with on-the-fly, zlib-
+// based decompression.
+//
+class compressed_input_stream: public xercesc::BinInputStream
+{
+public:
+ enum compression_type
+ {
+ raw,
+ zlib,
+ gzip
+ };
+
+ compressed_input_stream (std::istream&, compression_type);
+
+ virtual
+ ~compressed_input_stream ();
+
+ virtual XMLFilePos
+ curPos () const;
+
+ virtual XMLSize_t
+ readBytes (XMLByte* const buf, const XMLSize_t size);
+
+ virtual const XMLCh*
+ getContentType () const;
+
+private:
+ std::size_t
+ read ();
+
+private:
+ std::istream& is_;
+ z_stream zs_;
+ bool end_;
+
+ static const std::size_t buf_size_ = 65536;
+ char in_[buf_size_];
+ std::size_t pos_; // Current decompressed stream position.
+};
+
+#endif // COMPRESSED_INPUT_SOURCE_HXX
diff --git a/xsd-examples/cxx/tree/compression/driver.cxx b/xsd-examples/cxx/tree/compression/driver.cxx
new file mode 100644
index 0000000..15d842b
--- /dev/null
+++ b/xsd-examples/cxx/tree/compression/driver.cxx
@@ -0,0 +1,124 @@
+// file : cxx/tree/compression/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include "library.hxx"
+
+#include "compressed-input-source.hxx"
+#include "compressed-format-target.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " library.xml.gz" << endl;
+ return 1;
+ }
+
+ int r (0);
+
+ // We need to initialize the Xerces-C++ runtime because we are
+ // using the Xerces-C++ input/output interfaces.
+ //
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ using namespace library;
+
+ // Read in the XML file and obtain its object model.
+ //
+ ifstream ifs;
+ ifs.exceptions (ifstream::badbit | ifstream::failbit);
+ ifs.open (argv[1], ifstream::in | ifstream::binary);
+
+ compressed_input_source cis (ifs, compressed_input_source::gzip, argv[1]);
+
+ unique_ptr<catalog> c (
+ catalog_ (cis, xml_schema::flags::dont_initialize));
+
+
+ // Let's print what we've got.
+ //
+ for (catalog::book_const_iterator bi (c->book ().begin ());
+ bi != c->book ().end ();
+ ++bi)
+ {
+ cerr << endl
+ << "ID : " << bi->id () << endl
+ << "ISBN : " << bi->isbn () << endl
+ << "Title : " << bi->title () << endl
+ << "Genre : " << bi->genre () << endl;
+
+ for (book::author_const_iterator ai (bi->author ().begin ());
+ ai != bi->author ().end ();
+ ++ai)
+ {
+ cerr << "Author : " << ai->name () << endl;
+ cerr << " Born : " << ai->born () << endl;
+
+ if (ai->died ())
+ cerr << " Died : " << *ai->died () << endl;
+
+ if (ai->recommends ())
+ cerr << " Recommends : " << (*ai->recommends ())->title () << endl;
+ }
+
+ cerr << "Available : " << std::boolalpha << bi->available () << endl;
+ }
+
+ // Prepare namespace mapping and schema location information.
+ //
+ xml_schema::namespace_infomap map;
+
+ map["lib"].name = "http://www.codesynthesis.com/library";
+ map["lib"].schema = "library.xsd";
+
+ ofstream ofs;
+ ofs.exceptions (ofstream::badbit | ofstream::failbit | ofstream::eofbit);
+ ofs.open ("out.xml.gz", ofstream::out | ofstream::binary);
+
+ compressed_format_target cft (ofs, compressed_format_target::gzip);
+
+ // Write it out.
+ //
+ catalog_ (cft, *c, map, "UTF-8", xml_schema::flags::dont_initialize);
+
+ // Write out the compression stream trailer. If we don't do this
+ // explicitly, it will be done automatically in the cft's destructor
+ // but then any exceptions that might be throws will be ignored.
+ //
+ cft.close();
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+ catch (const compression_failure& e)
+ {
+ cerr << "compression failure: " << e.message () << endl;
+ r = 1;
+ }
+ catch (const decompression_failure& e)
+ {
+ cerr << "decompression failure: " << e.message () << endl;
+ r = 1;
+ }
+ catch (const ios_base::failure&)
+ {
+ cerr << "file open or read/write failure" << endl;
+ r = 1;
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+ return r;
+}
diff --git a/xsd-examples/cxx/tree/compression/library.xml.gz b/xsd-examples/cxx/tree/compression/library.xml.gz
new file mode 100644
index 0000000..dd71159
--- /dev/null
+++ b/xsd-examples/cxx/tree/compression/library.xml.gz
Binary files differ
diff --git a/xsd-examples/cxx/tree/compression/library.xsd b/xsd-examples/cxx/tree/compression/library.xsd
new file mode 100644
index 0000000..a741e7e
--- /dev/null
+++ b/xsd-examples/cxx/tree/compression/library.xsd
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/compression/library.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension"
+ 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:language"/>
+ </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:date"/>
+ <xsd:element name="died" type="xsd:date" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="author">
+ <xsd:complexContent>
+ <xsd:extension base="lib:person">
+ <xsd:attribute name="recommends" type="xsd:IDREF" xse:refType="lib: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" default="true"/>
+ <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/tree/compression/testscript b/xsd-examples/cxx/tree/compression/testscript
new file mode 100644
index 0000000..649de5a
--- /dev/null
+++ b/xsd-examples/cxx/tree/compression/testscript
@@ -0,0 +1,4 @@
+# file : cxx/tree/compression/testscript
+# license : not copyrighted - public domain
+
+$* $src_base/library.xml.gz &out.xml.gz 2>| : compressed-out
diff --git a/xsd-examples/cxx/tree/custom/README b/xsd-examples/cxx/tree/custom/README
new file mode 100644
index 0000000..b2a65b5
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/README
@@ -0,0 +1,40 @@
+This directory contains a number of examples that show how to customize the
+C++/Tree mapping. The following list gives an overview of each example:
+
+calendar
+ Shows how to customize XML Schema built-in types by mapping xsd:date
+ built-in type to the date class from the Boost date_time library.
+
+comments
+ This example shows how to customize the anyType XML Schema built-in
+ type to implement preservation of comments stored in XML documents.
+ Because anyType is a base type for every generated type, you can use
+ this technique to implement custom functionality that spans the
+ entire type system.
+
+contacts
+ Shows how to map a user-defined XML Schema type to a custom C++ class.
+ This example presents the simple case where the customized type is not
+ used as a base in the same schema.
+
+double
+ Shows how to customize parsing and serialization code for the xsd:double
+ XML Schema built-in type. It can be used as a guide on how to customize
+ built-in XML Schema types that are mapped to fundamental C++ types.
+
+mixed
+ Shows how to use type customization to parse and serialize mixed content.
+
+taxonomy
+ Shows how to map user-defined XML Schema types to custom C++ classes.
+ This example presents the complex case where the customized types are
+ inherited from in the same schema.
+
+wildcard
+ Shows how to use type customization to parse and serialize a specific
+ attribute that is matched by a wildcard (anyAttribute).
+
+For more information on the C++/Tree mapping customization see the
+C++/Tree Mapping Customization Guide[1].
+
+[1] http://wiki.codesynthesis.com/Tree/Customization_guide
diff --git a/xsd-examples/cxx/tree/custom/buildfile b/xsd-examples/cxx/tree/custom/buildfile
new file mode 100644
index 0000000..e650f99
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/buildfile
@@ -0,0 +1,6 @@
+# file : cxx/tree/custom/buildfile
+# license : not copyrighted - public domain
+
+# Exclude examples which depend on not yet packaged libraries.
+#
+./: {*/ -calendar/}
diff --git a/xsd-examples/cxx/tree/custom/calendar/.gitignore b/xsd-examples/cxx/tree/custom/calendar/.gitignore
new file mode 100644
index 0000000..2f35b6b
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/.gitignore
@@ -0,0 +1,2 @@
+calendar.?xx
+xml-schema.hxx
diff --git a/xsd-examples/cxx/tree/custom/calendar/README b/xsd-examples/cxx/tree/custom/calendar/README
new file mode 100644
index 0000000..f7f6989
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/README
@@ -0,0 +1,47 @@
+This example shows how to customize the XML Schema built-in types by mapping
+xsd:date built-in type to the date class from the Boost date_time library.
+You will need the Boost date_time library[1] installed in order to build
+and run this example. For more information on the C++/Tree mapping
+customization see the C++/Tree Mapping Customization Guide[2].
+
+[1] http://www.boost.org
+[2] http://wiki.codesynthesis.com/Tree/Customization_guide
+
+The example consists of the following files:
+
+calendar.xsd
+ XML Schema definition for a simple calendar format.
+
+calendar.xml
+ Sample XML instance document.
+
+xml-schema.hxx
+ C++ types for XML Schema built-in types. This header file is generated
+ by XSD using the --generate-xml-schema option. The --custom-type option
+ is also used to customize the xsd:date type.
+
+calendar.hxx
+calendar.ixx
+calendar.cxx
+ C++ types that represent the given vocabulary and a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model. These are generated by XSD from calendar.xsd with the
+ --extern-xml-schema option in order to include xml-schema.hxx.
+
+xml-schema-custom.hxx
+ Header file which defines our own xml_schema::date class. It is
+ included at the end of xml-schema.hxx using the --hxx-epilogue
+ option.
+
+xml-schema-custom.cxx
+ Source file which contains the implementation of our xml_schema:date
+ class.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input file. It then prints
+ the calendar events to STDERR.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver calendar.xml
diff --git a/xsd-examples/cxx/tree/custom/calendar/buildfile b/xsd-examples/cxx/tree/custom/calendar/buildfile
new file mode 100644
index 0000000..3c26122
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/buildfile
@@ -0,0 +1,47 @@
+# file : cxx/tree/custom/calendar/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+import libs += libboost-date-time%lib{boost_date_time}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -calendar -xml-schema} \
+ {hxx ixx cxx}{calendar} \
+ {hxx }{xml-schema} \
+ $libs
+
+exe{driver}: xml{calendar}: test.input = true
+
+<{hxx ixx cxx}{calendar}>: xsd{calendar} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --extern-xml-schema xml-schema.xsd \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+hxx{xml-schema}: $xsd
+{{
+ diag xsd gen ($>[0])
+
+ # Note that the specified xml-schema.xsd doesn't exist and is only used to
+ # deduce the generated header name.
+ #
+ $xsd cxx-tree --std c++11 \
+ --generate-xml-schema \
+ --custom-type date \
+ --hxx-epilogue '#include "xml-schema-custom.hxx"' \
+ --output-dir $out_base \
+ xml-schema.xsd
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/custom/calendar/calendar.xml b/xsd-examples/cxx/tree/custom/calendar/calendar.xml
new file mode 100644
index 0000000..8fff59c
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/calendar.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/calendar/calendar.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<cal:events xmlns:cal="http://www.codesynthesis.com/calendar"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/calendar calendar.xsd">
+
+ <event title="Bike ride" date="2006-09-04">
+ Don't forget to change the tire.
+ </event>
+
+ <event title="Mountain hike" date="2006-09-05">
+ Can be cancelled if it is too cold.
+ </event>
+
+</cal:events>
diff --git a/xsd-examples/cxx/tree/custom/calendar/calendar.xsd b/xsd-examples/cxx/tree/custom/calendar/calendar.xsd
new file mode 100644
index 0000000..8b36c34
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/calendar.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/calendar/calendar.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:cal="http://www.codesynthesis.com/calendar"
+ targetNamespace="http://www.codesynthesis.com/calendar">
+
+ <xsd:complexType name="event">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="title" type="xsd:string" use="required"/>
+ <xsd:attribute name="date" type="xsd:date" use="required"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="events">
+ <xsd:sequence>
+ <xsd:element name="event" type="cal:event" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="events" type="cal:events"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/tree/custom/calendar/driver.cxx b/xsd-examples/cxx/tree/custom/calendar/driver.cxx
new file mode 100644
index 0000000..fdecf57
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/driver.cxx
@@ -0,0 +1,39 @@
+// file : cxx/tree/custom/calendar/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <iostream>
+
+#include "calendar.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " calendar.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace calendar;
+
+ std::unique_ptr<events> e (events_ (argv[1]));
+
+ for (events::event_const_iterator i (e->event ().begin ());
+ i != e->event ().end (); ++i)
+ {
+ cerr << i->date () << " " << i->title () << endl
+ << *i << endl;
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/tree/custom/calendar/xml-schema-custom.cxx b/xsd-examples/cxx/tree/custom/calendar/xml-schema-custom.cxx
new file mode 100644
index 0000000..2bfe0f2
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/xml-schema-custom.cxx
@@ -0,0 +1,56 @@
+// file : cxx/tree/custom/calendar/xml-schema-custom.cxx
+// copyright : not copyrighted - public domain
+
+// Include xml-schema.hxx instead of xml-schema-custom.hxx here.
+//
+#include "xml-schema.hxx"
+
+#include <xsd/cxx/xml/string.hxx> // xsd::cxx::xml::transcode
+#include <xsd/cxx/tree/text.hxx> // xsd::cxx::tree::text_content
+
+using namespace boost;
+using namespace boost::gregorian;
+
+namespace xml_schema
+{
+ date::
+ date (const xercesc::DOMElement& e, flags f, container* c)
+ : simple_type (e, f, c),
+ gregorian::date (
+ from_simple_string (
+ xsd::cxx::tree::text_content<char> (e)))
+ {
+ }
+
+ date::
+ date (const xercesc::DOMAttr& a, flags f, container* c)
+ : simple_type (a, f, c),
+ gregorian::date (
+ from_simple_string (
+ xsd::cxx::xml::transcode<char> (a.getValue ())))
+ {
+ }
+
+ date::
+ date (const std::string& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : simple_type (s, e, f, c),
+ gregorian::date (from_simple_string (s))
+ {
+ }
+
+ date::
+ date (const date& d, flags f, container* c)
+ : simple_type (d, f, c),
+ gregorian::date (d)
+ {
+ }
+
+ date* date::
+ _clone (flags f, container* c) const
+ {
+ return new date (*this, f, c);
+ }
+}
diff --git a/xsd-examples/cxx/tree/custom/calendar/xml-schema-custom.hxx b/xsd-examples/cxx/tree/custom/calendar/xml-schema-custom.hxx
new file mode 100644
index 0000000..f8f8218
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/calendar/xml-schema-custom.hxx
@@ -0,0 +1,33 @@
+// file : cxx/tree/custom/calendar/xml-schema-custom.hxx
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use xml-schema.hxx instead. This
+// file is included into generated xml-schema.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <boost/date_time/gregorian/gregorian.hpp> // boost::gregorian::date
+
+namespace xml_schema
+{
+ class date: public simple_type,
+ public boost::gregorian::date
+ {
+ public:
+ // Parsing c-tors: element, attribute, and list item.
+ //
+ date (const xercesc::DOMElement&, flags = 0, container* = 0);
+ date (const xercesc::DOMAttr&, flags = 0, container* = 0);
+ date (const std::string&,
+ const xercesc::DOMElement*,
+ flags = 0,
+ container* = 0);
+
+ // Copy c-tor and _clone.
+ //
+ date (const date&, flags = 0, container* = 0);
+
+ virtual date*
+ _clone (flags = 0, container* = 0) const;
+ };
+}
diff --git a/xsd-examples/cxx/tree/custom/comments/.gitignore b/xsd-examples/cxx/tree/custom/comments/.gitignore
new file mode 100644
index 0000000..78cfc67
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/.gitignore
@@ -0,0 +1,2 @@
+people.?xx
+xml-schema.hxx
diff --git a/xsd-examples/cxx/tree/custom/comments/README b/xsd-examples/cxx/tree/custom/comments/README
new file mode 100644
index 0000000..8fd69d0
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/README
@@ -0,0 +1,57 @@
+This example shows how to customize the anyType XML Schema built-in
+type to implement preservation of comments stored in XML documents.
+Because anyType is a base type for every generated type, you can use
+this technique to implement custom functionality that spans the
+entire type system. For more information on the C++/Tree mapping
+customization see the C++/Tree Mapping Customization Guide[2].
+
+[2] http://wiki.codesynthesis.com/Tree/Customization_guide
+
+The example consists of the following files:
+
+people.xsd
+ XML Schema definition for a simple person record vocabulary.
+
+people.xml
+ Sample XML instance document.
+
+xml-schema.hxx
+ C++ types for XML Schema built-in types. This header file is generated
+ by XSD using the --generate-xml-schema option. The --custom-type option
+ is also used to customize the xsd:anyType type.
+
+people.hxx
+people.ixx
+people.cxx
+ C++ types that represent the person record vocabulary, a set of
+ parsing functions that convert XML instance documents to a tree-like
+ in-memory object model, and a set of serialization functions that
+ convert the object model back to XML. These are generated by XSD
+ from people.xsd with the --extern-xml-schema option in order to
+ include xml-schema.hxx.
+
+xml-schema-custom.hxx
+ Header file which defines our own xml_schema::type class. It is
+ included at the end of xml-schema.hxx using the --hxx-epilogue
+ option.
+
+xml-schema-custom.cxx
+ Source file which contains the implementation of our xml_schema:type
+ class.
+
+dom-parse.hxx
+dom-parse.cxx
+ Definition and implementation of the parse() function that
+ parses an XML document to a DOM document while preserving
+ XML comments.
+
+driver.cxx
+ Driver for the example. It first calls the above parse() function
+ to parse the input file to a DOM document. It then parses the DOM
+ document to the object model and performs a number of modifications
+ on this object model. Finally, it serializes the modified object
+ model back to XML, including XML comments.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver people.xml
diff --git a/xsd-examples/cxx/tree/custom/comments/buildfile b/xsd-examples/cxx/tree/custom/comments/buildfile
new file mode 100644
index 0000000..093a6cc
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/buildfile
@@ -0,0 +1,48 @@
+# file : cxx/tree/custom/comments/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -people -xml-schema} \
+ {hxx ixx cxx}{people} \
+ {hxx }{xml-schema} \
+ $libs
+
+exe{driver}: xml{people}: test.input = true
+
+<{hxx ixx cxx}{people}>: xsd{people} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-serialization \
+ --extern-xml-schema xml-schema.xsd \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+hxx{xml-schema}: $xsd
+{{
+ diag xsd gen ($>[0])
+
+ # Note that the specified xml-schema.xsd doesn't exist and is only used to
+ # deduce the generated header name.
+ #
+ $xsd cxx-tree --std c++11 \
+ --generate-xml-schema \
+ --generate-serialization \
+ --custom-type anyType=/type_base \
+ --hxx-epilogue '#include "xml-schema-custom.hxx"' \
+ --output-dir $out_base \
+ xml-schema.xsd
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/custom/comments/dom-parse.cxx b/xsd-examples/cxx/tree/custom/comments/dom-parse.cxx
new file mode 100644
index 0000000..2fa6a70
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/dom-parse.cxx
@@ -0,0 +1,93 @@
+// file : cxx/tree/custom/comments/dom-parse.cxx
+// copyright : not copyrighted - public domain
+
+#include "dom-parse.hxx"
+
+#include <istream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_*
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+using namespace xercesc;
+namespace xml = xsd::cxx::xml;
+namespace tree = xsd::cxx::tree;
+
+xml::dom::unique_ptr<DOMDocument>
+parse (std::istream& is, const std::string& id, bool validate)
+{
+ const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+ xml::dom::unique_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Preserve comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, true);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable/Disable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, validate);
+ conf->setParameter (XMLUni::fgXercesSchema, validate);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support.
+ //
+#if _XERCES_VERSION >= 30100
+ conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+#endif
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ // Set error handler.
+ //
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+ // Prepare input stream.
+ //
+ xml::sax::std_input_source isrc (is, id);
+ Wrapper4InputSource wrap (&isrc, false);
+
+ xml::dom::unique_ptr<DOMDocument> doc (parser->parse (&wrap));
+
+ eh.throw_if_failed<tree::parsing<char> > ();
+
+ return doc;
+}
diff --git a/xsd-examples/cxx/tree/custom/comments/dom-parse.hxx b/xsd-examples/cxx/tree/custom/comments/dom-parse.hxx
new file mode 100644
index 0000000..83c3dd4
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/dom-parse.hxx
@@ -0,0 +1,23 @@
+// file : cxx/tree/custom/comments/dom-parse.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef DOM_PARSE
+#define DOM_PARSE
+
+#include <string>
+#include <iosfwd>
+
+#include <xercesc/dom/DOMDocument.hpp>
+
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+
+// Parse an XML document from the standard input stream with an
+// optional resource id. Resource id is used in diagnostics as
+// well as to locate schemas referenced from inside the document.
+//
+xsd::cxx::xml::dom::unique_ptr<xercesc::DOMDocument>
+parse (std::istream& is,
+ const std::string& id,
+ bool validate);
+
+#endif // DOM_PARSE
diff --git a/xsd-examples/cxx/tree/custom/comments/driver.cxx b/xsd-examples/cxx/tree/custom/comments/driver.cxx
new file mode 100644
index 0000000..5588273
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/driver.cxx
@@ -0,0 +1,90 @@
+// file : cxx/tree/custom/commens/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include "people.hxx"
+#include "dom-parse.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " people.xml" << endl;
+ return 1;
+ }
+
+ int r (0);
+
+ // We need to initialize the Xerces-C++ runtime because we
+ // are doing the XML-to-DOM parsing ourselves (see below).
+ //
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ using namespace people;
+ namespace xml = xsd::cxx::xml;
+
+ ifstream ifs;
+ ifs.exceptions (ifstream::badbit | ifstream::failbit);
+ ifs.open (argv[1]);
+
+ // For performance reasons the internal XML to DOM parsing code
+ // discards comments in the resulting DOM document. To overcome
+ // this we are going to use our own parse() function from
+ // dom-parse.hxx that preserves comments in the resulting DOM
+ // documents.
+ //
+ xml_schema::dom::unique_ptr<xercesc::DOMDocument> doc (
+ parse (ifs, argv[1], true));
+
+ // Parse the DOM document to the object model.
+ //
+ unique_ptr<catalog> c (catalog_ (*doc));
+
+ // Change the object model.
+ //
+ catalog::person_sequence& ps (c->person ());
+
+ for (catalog::person_iterator i (ps.begin ()); i != ps.end (); ++i)
+ {
+ i->age (i->age () + 1);
+ }
+
+ person john ("John Doe", 30);
+ john.comment ("Record for John Doe");
+
+ ps.push_back (john);
+
+ // Serialize.
+ //
+ xml_schema::namespace_infomap map;
+
+ map["ppl"].name = "http://www.codesynthesis.com/people";
+ map["ppl"].schema = "people.xsd";
+
+ catalog_ (std::cout, *c, map);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ r = 1;
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+ return r;
+}
diff --git a/xsd-examples/cxx/tree/custom/comments/people.xml b/xsd-examples/cxx/tree/custom/comments/people.xml
new file mode 100644
index 0000000..08d69e9
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/people.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/comments/people.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<ppl:catalog xmlns:ppl="http://www.codesynthesis.com/people"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/people people.xsd">
+
+ <person>
+ <!--Record for Joe Dirt-->
+ <name>Joe Dirt</name>
+ <age>28</age>
+ </person>
+
+</ppl:catalog>
diff --git a/xsd-examples/cxx/tree/custom/comments/people.xsd b/xsd-examples/cxx/tree/custom/comments/people.xsd
new file mode 100644
index 0000000..20f265f
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/people.xsd
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/comments/people.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:ppl="http://www.codesynthesis.com/people"
+ targetNamespace="http://www.codesynthesis.com/people">
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="age" type="xsd:unsignedShort"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="catalog">
+ <xsd:sequence>
+ <xsd:element name="person" type="ppl:person" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="catalog" type="ppl:catalog"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/tree/custom/comments/xml-schema-custom.cxx b/xsd-examples/cxx/tree/custom/comments/xml-schema-custom.cxx
new file mode 100644
index 0000000..265e0cb
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/xml-schema-custom.cxx
@@ -0,0 +1,117 @@
+// file : cxx/tree/custom/comments/xml-schema-custom.cxx
+// copyright : not copyrighted - public domain
+
+// Include xml-schema.hxx instead of xml-schema-custom.hxx here.
+//
+#include "xml-schema.hxx"
+
+#include <xercesc/dom/DOMComment.hpp>
+#include <xercesc/dom/DOMDocument.hpp>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode, xml::string
+
+namespace xml = xsd::cxx::xml;
+
+namespace xml_schema
+{
+ type::
+ type ()
+ : type_base ()
+ {
+ }
+
+ type::
+ type (const xercesc::DOMElement& e, flags f, container* c)
+ : type_base (e, f, c)
+ {
+ using namespace xercesc;
+
+ // Here we are only handling a comment that is the first
+ // node in the element's content.
+ //
+ const DOMNode* n (e.getFirstChild ());
+
+ if (n != 0 && n->getNodeType () == DOMNode::COMMENT_NODE)
+ {
+ const DOMComment* c (static_cast<const DOMComment*> (n));
+ comment_ = xml::transcode<char> (c->getData ());
+ }
+ }
+
+ type::
+ type (const xercesc::DOMAttr& a, flags f, container* c)
+ : type_base (a, f, c)
+ {
+ // No comments for attributes.
+ //
+ }
+
+ type::
+ type (const std::string& s, const xercesc::DOMElement* e,
+ flags f, container* c)
+ : type_base (s, e, f, c)
+ {
+ // No comments for list items.
+ //
+ }
+
+ type::
+ type (const type& x, flags f, container* c)
+ : type_base (x, f, c), comment_ (x.comment_)
+ {
+ }
+
+ type* type::
+ _clone (flags f, container* c) const
+ {
+ return new type (*this, f, c);
+ }
+
+ // Serialization operators.
+ //
+ void
+ operator<< (xercesc::DOMElement& e, const type& x)
+ {
+ // Call our base first.
+ //
+ const type_base& b (x);
+ e << b;
+
+ // Add the comment if any.
+ //
+ const std::string s (x.comment ());
+
+ if (!s.empty ())
+ {
+ using namespace xercesc;
+
+ DOMDocument* doc (e.getOwnerDocument ());
+ DOMComment* c (doc->createComment (xml::string (s).c_str ()));
+ e.appendChild (c);
+ }
+ }
+
+ void
+ operator<< (xercesc::DOMAttr& a, const type& x)
+ {
+ // Call our base first.
+ //
+ const type_base& b (x);
+ a << b;
+
+ // No comments for attributes.
+ //
+ }
+
+ void
+ operator<< (xml_schema::list_stream& ls, const type& x)
+ {
+ // Call our base first.
+ //
+ const type_base& b (x);
+ ls << b;
+
+ // No comments for list items.
+ //
+ }
+}
diff --git a/xsd-examples/cxx/tree/custom/comments/xml-schema-custom.hxx b/xsd-examples/cxx/tree/custom/comments/xml-schema-custom.hxx
new file mode 100644
index 0000000..01a4f9c
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/comments/xml-schema-custom.hxx
@@ -0,0 +1,60 @@
+// file : cxx/tree/custom/comments/xml-schema-custom.hxx
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use xml-schema.hxx instead. This
+// file is included into generated xml-schema.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <string>
+
+namespace xml_schema
+{
+ // When customizing anyType always inherit from the original type.
+ //
+ class type: public type_base
+ {
+ public:
+ type ();
+ type (const xercesc::DOMElement&, flags = 0, container* = 0);
+ type (const xercesc::DOMAttr&, flags = 0, container* = 0);
+ type (const std::string&, const xercesc::DOMElement*,
+ flags = 0, container* = 0);
+ type (const type&, flags = 0, container* = 0);
+
+ type&
+ operator= (const type&) = default;
+
+ virtual type*
+ _clone (flags = 0, container* = 0) const;
+
+ public:
+ // Comment manipulation API.
+ //
+ const std::string&
+ comment () const
+ {
+ return comment_;
+ }
+
+ void
+ comment (const std::string& c)
+ {
+ comment_ = c;
+ }
+
+ private:
+ std::string comment_;
+ };
+
+ // New serialization operators.
+ //
+ void
+ operator<< (xercesc::DOMElement&, const type&);
+
+ void
+ operator<< (xercesc::DOMAttr&, const type&);
+
+ void
+ operator<< (xml_schema::list_stream&, const type&);
+}
diff --git a/xsd-examples/cxx/tree/custom/contacts/.gitignore b/xsd-examples/cxx/tree/custom/contacts/.gitignore
new file mode 100644
index 0000000..43c214d
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/.gitignore
@@ -0,0 +1 @@
+contacts.?xx
diff --git a/xsd-examples/cxx/tree/custom/contacts/README b/xsd-examples/cxx/tree/custom/contacts/README
new file mode 100644
index 0000000..072ede3
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/README
@@ -0,0 +1,40 @@
+This example shows how to map a user-defined XML Schema type to a custom
+C++ class. It presents the simple case where the customized type is not
+used as a base in the same schema. For the complex case see the taxonomy
+example. For more information on the C++/Tree mapping customization see
+the C++/Tree Mapping Customization Guide[1].
+
+[1] http://wiki.codesynthesis.com/Tree/Customization_guide
+
+The example consists of the following files:
+
+contacts.xsd
+ XML Schema definition for a simple contacts database.
+
+contacts.xml
+ Sample XML instance document.
+
+contacts.hxx
+contacts.ixx
+contacts.cxx
+ C++ types that represent the given vocabulary and a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model. These are generated by XSD from contacts.xsd with the
+ --custom-type option in order to customize the contact type.
+
+contacts-custom.hxx
+ Header file which defines our own contact class by inheriting from the
+ generated contact_base. It is included at the end of contacts.hxx using
+ the --hxx-epilogue option.
+
+contacts-custom.cxx
+ Source file which contains the implementation of our contact class.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input file. It then prints
+ the contacts to STDERR.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver contacts.xml
diff --git a/xsd-examples/cxx/tree/custom/contacts/buildfile b/xsd-examples/cxx/tree/custom/contacts/buildfile
new file mode 100644
index 0000000..190306c
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/buildfile
@@ -0,0 +1,25 @@
+# file : cxx/tree/custom/contacts/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -contacts} {hxx ixx cxx}{contacts} $libs
+
+exe{driver}: xml{contacts}: test.input = true
+
+<{hxx ixx cxx}{contacts}>: xsd{contacts} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --custom-type contact=/contact_base \
+ --hxx-epilogue '#include "contacts-custom.hxx"' \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
diff --git a/xsd-examples/cxx/tree/custom/contacts/contacts-custom.cxx b/xsd-examples/cxx/tree/custom/contacts/contacts-custom.cxx
new file mode 100644
index 0000000..208b00f
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/contacts-custom.cxx
@@ -0,0 +1,50 @@
+// file : cxx/tree/custom/contacts/contacts-custom.cxx
+// copyright : not copyrighted - public domain
+
+#include <ostream>
+
+// Include contacts.hxx instead of contacts-custom.hxx here.
+//
+#include "contacts.hxx"
+
+namespace contacts
+{
+ // We implement the following constructs by simply forwarding
+ // to our base.
+ //
+ contact::
+ contact (const name_type& n,
+ const email_type& e,
+ const phone_type& p)
+ : contact_base (n, e, p)
+ {
+ }
+
+ contact::
+ contact (const xercesc::DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : contact_base (e, f, c)
+ {
+ }
+
+ contact::
+ contact (const contact& x,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : contact_base (x, f, c)
+ {
+ }
+
+ contact* contact::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new contact (*this, f, c);
+ }
+
+ void contact::
+ print (std::ostream& os) const
+ {
+ os << name () << " e| " << email () << " t| " << phone () << std::endl;
+ }
+}
diff --git a/xsd-examples/cxx/tree/custom/contacts/contacts-custom.hxx b/xsd-examples/cxx/tree/custom/contacts/contacts-custom.hxx
new file mode 100644
index 0000000..a5bc893
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/contacts-custom.hxx
@@ -0,0 +1,43 @@
+// file : cxx/tree/custom/contacts/contacts-custom.hxx
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use contacts.hxx instead. This
+// file is included into generated contacts.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <iosfwd> // std::ostream
+
+namespace contacts
+{
+ class contact: public contact_base
+ {
+ // The following constructor signatures are copied from
+ // contact_base except for the copy constructor and the
+ // _clone function where we had to change the type from
+ // contact_base to contact.
+ //
+ public:
+ contact (const name_type&,
+ const email_type&,
+ const phone_type&);
+
+ contact (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ contact (const contact&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ virtual contact*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ // Our customizations.
+ //
+ public:
+ void
+ print (std::ostream&) const;
+ };
+}
diff --git a/xsd-examples/cxx/tree/custom/contacts/contacts.xml b/xsd-examples/cxx/tree/custom/contacts/contacts.xml
new file mode 100644
index 0000000..884c25e
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/contacts.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/contacts/contacts.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<cts:catalog xmlns:cts="http://www.codesynthesis.com/contacts"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/contacts contacts.xsd">
+
+ <contact>
+ <name>Joe Dirt</name>
+ <email>joe@dirt.com</email>
+ <phone>555 DIRT</phone>
+ </contact>
+
+</cts:catalog>
diff --git a/xsd-examples/cxx/tree/custom/contacts/contacts.xsd b/xsd-examples/cxx/tree/custom/contacts/contacts.xsd
new file mode 100644
index 0000000..5348810
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/contacts.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/contacts/contacts.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:cts="http://www.codesynthesis.com/contacts"
+ targetNamespace="http://www.codesynthesis.com/contacts">
+
+ <xsd:complexType name="contact">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="email" type="xsd:string"/>
+ <xsd:element name="phone" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="catalog">
+ <xsd:sequence>
+ <xsd:element name="contact" type="cts:contact" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <xsd:element name="catalog" type="cts:catalog"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/tree/custom/contacts/driver.cxx b/xsd-examples/cxx/tree/custom/contacts/driver.cxx
new file mode 100644
index 0000000..a0c7510
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/contacts/driver.cxx
@@ -0,0 +1,38 @@
+// file : cxx/tree/custom/contacts/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <iostream>
+
+#include "contacts.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " contacts.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace contacts;
+
+ std::unique_ptr<catalog> c (catalog_ (argv[1]));
+
+ for (catalog::contact_const_iterator i (c->contact ().begin ());
+ i != c->contact ().end (); ++i)
+ {
+ i->print (cerr);
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/tree/custom/double/.gitignore b/xsd-examples/cxx/tree/custom/double/.gitignore
new file mode 100644
index 0000000..5cc7f75
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/double/.gitignore
@@ -0,0 +1,2 @@
+order.?xx
+xml-schema.hxx
diff --git a/xsd-examples/cxx/tree/custom/double/README b/xsd-examples/cxx/tree/custom/double/README
new file mode 100644
index 0000000..15348d2
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/double/README
@@ -0,0 +1,62 @@
+This example shows how to customize parsing and serialization code for the
+xsd:double XML Schema built-in type using the type customization mechanism
+provided by the C++/Tree Mapping. For more information on type customization
+see the C++/Tree Mapping Customization Guide, particularly sections 1 and 4:
+
+http://wiki.codesynthesis.com/Tree/Customization_guide
+
+In this example our schema uses xsd:double to represent a price. There are
+two potential problems with this choice of a price type. First, xsd:double
+can be serialized in the scientific notation which would be an unusual way
+of representing a price. Second, we would like to limit the number of
+fraction digits in our prices to 2. Furthermore, we would like to always
+have two fraction digits, even if one or both of them are zeros, for
+example: 12.99, 12.90, 12.00.
+
+In case we can modify the schema, a better approach would be to define the
+price type as a restriction of the xsd:decimal type (always fixed notation)
+and specify the fractionDigits facet to limit the number of fraction digits
+to 2. However, there is no way in XML Schema to specify that there should
+always be exactly 2 fraction digits. Therefore, it may still be desirable
+to customize this price type to get the required serialization behavior.
+
+Finally, it is worth noting that the behavior achieved in this example via
+type customization can also be achieved by compiling your code with the
+following macros defined:
+
+XSD_TREE_DOUBLE_FIXED
+XSD_TREE_DOUBLE_PRECISION 2
+
+However, the type customization approach while requiring more work is
+cleaner since it does not rely on global macro definitions.
+
+This example consists of the following files:
+
+order.xsd
+ XML Schema definition for a simple order vocabulary.
+
+double-custom.hxx
+double-custom.cxx
+ Custom parsing and serialization code for the xsd:double types. The
+ double-custom.hxx file is included at the end of the xml-schema.hxx
+ file described below.
+
+xml-schema.hxx
+ C++ types for XML Schema built-in types. This header file is generated
+ by the XSD compiler using the --generate-xml-schema option. The
+ --custom-type option is used to customize the xsd:double type. The
+ --hxx-epilogue option is used to include the double-custom.hxx file
+ at the end of this file.
+
+order.hxx
+order.cxx
+ C++ types generated from order.xsd. The --extern-xml-schema option
+ is used to include xml-schema.hxx into order.hxx.
+
+driver.cxx
+ Test driver for the example. It creates a sample order and then
+ writes it to XML to test the custom xsd:double serialization code.
+
+To run the example simply execute:
+
+$ ./driver
diff --git a/xsd-examples/cxx/tree/custom/double/buildfile b/xsd-examples/cxx/tree/custom/double/buildfile
new file mode 100644
index 0000000..258191a
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/double/buildfile
@@ -0,0 +1,46 @@
+# file : cxx/tree/custom/double/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -order -xml-schema} \
+ {hxx ixx cxx}{order} \
+ {hxx }{xml-schema} \
+ $libs
+
+<{hxx ixx cxx}{order}>: xsd{order} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-serialization \
+ --extern-xml-schema xml-schema.xsd \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+hxx{xml-schema}: $xsd
+{{
+ diag xsd gen ($>[0])
+
+ # Note that the specified xml-schema.xsd doesn't exist and is only used to
+ # deduce the generated header name.
+ #
+ $xsd cxx-tree --std c++11 \
+ --generate-xml-schema \
+ --generate-serialization \
+ --custom-type double=double \
+ --hxx-epilogue '#include "double-custom.hxx"' \
+ --output-dir $out_base \
+ xml-schema.xsd
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/custom/double/double-custom.cxx b/xsd-examples/cxx/tree/custom/double/double-custom.cxx
new file mode 100644
index 0000000..bfec6e0
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/double/double-custom.cxx
@@ -0,0 +1,96 @@
+// file : cxx/tree/custom/double/double-custom.cxx
+// copyright : not copyrighted - public domain
+
+// Include xml-schema.hxx instead of double-custom.hxx here.
+//
+#include "xml-schema.hxx"
+
+#include <limits>
+#include <locale>
+#include <sstream>
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+using namespace std;
+
+// Parsing.
+//
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ double traits<double, char, schema_type::double_>::
+ create (const std::string& s,
+ const xercesc::DOMElement*,
+ flags,
+ type*)
+ {
+ // This type cannot have whitespaces in its values. As result we
+ // don't need to waste time collapsing whitespaces. All we need to
+ // do is trim the string representation which can be done without
+ // copying.
+ //
+ ro_string<char> tmp (s);
+ trim (tmp);
+
+ zc_istream<char> is (tmp);
+ is.imbue (locale::classic ());
+
+ double t;
+ is >> t;
+
+ return t;
+ }
+ }
+ }
+}
+
+// Serialization.
+//
+namespace XERCES_CPP_NAMESPACE
+{
+ void
+ operator<< (xercesc::DOMElement& e, const xml_schema::as_double& d)
+ {
+ ostringstream os;
+ os.imbue (locale::classic ());
+
+ os.precision (2);
+ os << fixed << d.x;
+
+ e << os.str ();
+ }
+
+ void
+ operator<< (xercesc::DOMAttr& a, const xml_schema::as_double& d)
+ {
+ ostringstream os;
+ os.imbue (locale::classic ());
+
+ os.precision (2);
+ os << fixed << d.x;
+
+ a << os.str ();
+ }
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ void
+ operator<< (xml_schema::list_stream& ls,
+ const xml_schema::as_double& d)
+ {
+ ls.os_.imbue (locale::classic ());
+ ls.os_.precision (2);
+ ls.os_ << fixed << d.x;
+ }
+ }
+ }
+}
diff --git a/xsd-examples/cxx/tree/custom/double/double-custom.hxx b/xsd-examples/cxx/tree/custom/double/double-custom.hxx
new file mode 100644
index 0000000..cb74442
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/double/double-custom.hxx
@@ -0,0 +1,67 @@
+// file : cxx/tree/custom/double/double-custom.hxx
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use xml-schema.hxx instead. This
+// file is included into generated xml-schema.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+#include <xsd/cxx/tree/text.hxx> // text_content
+
+// Parsing.
+//
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template<>
+ struct traits<double, char, schema_type::double_>
+ {
+ static double
+ create (const xercesc::DOMElement& e, flags f, type* c)
+ {
+ return create (text_content<char> (e), 0, f, c);
+ }
+
+ static double
+ create (const xercesc::DOMAttr& a, flags f, type* c)
+ {
+ return create (xml::transcode<char> (a.getValue ()), 0, f, c);
+ }
+
+ static double
+ create (const std::string& s,
+ const xercesc::DOMElement*,
+ flags,
+ type*);
+ };
+ }
+ }
+}
+
+// Serialization.
+//
+namespace XERCES_CPP_NAMESPACE
+{
+ void
+ operator<< (xercesc::DOMElement& e, const xml_schema::as_double& d);
+
+ void
+ operator<< (xercesc::DOMAttr& a, const xml_schema::as_double& d);
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ void
+ operator<< (xml_schema::list_stream& ls,
+ const xml_schema::as_double& d);
+ }
+ }
+}
diff --git a/xsd-examples/cxx/tree/custom/double/driver.cxx b/xsd-examples/cxx/tree/custom/double/driver.cxx
new file mode 100644
index 0000000..e3f1800
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/double/driver.cxx
@@ -0,0 +1,31 @@
+// file : cxx/tree/custom/double/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <iostream>
+
+#include "order.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main ()
+{
+ try
+ {
+ // Order one Airbus A380.
+ //
+ order o;
+ o.item ().push_back (item ("Airbus A380", 317000000.90));
+
+
+ // Serialize.
+ //
+ order_ (std::cout, o);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/tree/custom/double/order.xsd b/xsd-examples/cxx/tree/custom/double/order.xsd
new file mode 100644
index 0000000..8066975
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/double/order.xsd
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/double/order.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="item">
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ <xsd:attribute name="price" type="xsd:double" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="order">
+ <xsd:sequence>
+ <xsd:element name="item" type="item" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="order" type="order"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/tree/custom/mixed/.gitignore b/xsd-examples/cxx/tree/custom/mixed/.gitignore
new file mode 100644
index 0000000..83d0a51
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/.gitignore
@@ -0,0 +1 @@
+people.?xx
diff --git a/xsd-examples/cxx/tree/custom/mixed/README b/xsd-examples/cxx/tree/custom/mixed/README
new file mode 100644
index 0000000..7b56812
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/README
@@ -0,0 +1,50 @@
+This example shows how to use type customization to parse and serialize
+mixed content. The example achieves this by customizing the type with
+the mixed content model to include a DOM document that stores the data
+as a raw XML representation. The customized type also provides its own
+parsing constructor and serialization operator where the mixed content
+is extracted from and inserted back to DOM, respectively. The use of
+DOM for mixed content storage is one of the options. You may find other
+data structures (e.g., a string) more suitable depending on your situation.
+
+For more information on the C++/Tree mapping customization see the C++/Tree
+Mapping Customization Guide[1].
+
+[1] http://wiki.codesynthesis.com/Tree/Customization_guide
+
+The example consists of the following files:
+
+people.xsd
+ XML Schema definition for a simple person record vocabulary. Each
+ record includes the bio element which represents arbitrary XHTML
+ fragments as mixed content.
+
+people.xml
+ Sample XML instance document.
+
+people.hxx
+people.ixx
+people.cxx
+ C++ types that represent the given vocabulary, a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model, and a set of serialization functions that convert the
+ object model back to XML. These are generated by XSD from people.xsd
+ with the --custom-type option in order to customize the bio type.
+
+people-custom.hxx
+ Header file which defines our own bio class by inheriting from the
+ generated bio_base. It is included at the end of people.hxx using
+ the --hxx-epilogue option.
+
+people-custom.cxx
+ Source file which contains the implementation of our bio class.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input file. It then prints
+ the data to STDERR, including the bio information converted to text.
+ Finally, the driver serializes the object model back to XML.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver people.xml
diff --git a/xsd-examples/cxx/tree/custom/mixed/buildfile b/xsd-examples/cxx/tree/custom/mixed/buildfile
new file mode 100644
index 0000000..9da936e
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/buildfile
@@ -0,0 +1,30 @@
+# file : cxx/tree/custom/mixed/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -people} {hxx ixx cxx}{people} $libs
+
+exe{driver}: xml{people}: test.input = true
+
+<{hxx ixx cxx}{people}>: xsd{people} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-serialization \
+ --custom-type bio=/bio_base \
+ --hxx-epilogue '#include "people-custom.hxx"' \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/custom/mixed/driver.cxx b/xsd-examples/cxx/tree/custom/mixed/driver.cxx
new file mode 100644
index 0000000..08c83e0
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/driver.cxx
@@ -0,0 +1,122 @@
+// file : cxx/tree/custom/mixed/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include "people.hxx"
+
+// The following transcode() utility function is handy when working with
+// Xerces. Include it after the generated header in order to get only char
+// or wchar_t version depending on how you compiled your schemas.
+//
+#include <xsd/cxx/xml/string.hxx>
+
+using std::cerr;
+using std::endl;
+using namespace xercesc;
+
+void
+xhtml2txt (const DOMElement*);
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " people.xml" << endl;
+ return 1;
+ }
+
+ int r (0);
+
+ // The Xerces-C++ DOM document that will be used to store the XHTML
+ // fragments "out-live" the call to the parsing function. Therefore
+ // we need to initialize the Xerces-C++ runtime ourselves.
+ //
+ XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ using namespace people;
+
+ // Parse.
+ //
+ std::unique_ptr<directory> d (
+ directory_ (argv[1], xml_schema::flags::dont_initialize));
+
+ // Print what we've got.
+ //
+ const directory::person_sequence& s (d->person ());
+
+ for (directory::person_const_iterator i (s.begin ()); i != s.end (); ++i)
+ {
+ cerr << "First : " << i->first_name () << endl
+ << "Last : " << i->last_name () << endl
+ << "Gender : " << i->gender () << endl
+ << "Age : " << i->age () << endl;
+
+ const bio& b (i->bio ());
+ const DOMElement* xhtml (b.xhtml ());
+
+ if (xhtml != 0)
+ {
+ cerr << "Bio : " << endl;
+ xhtml2txt (xhtml);
+ }
+
+ cerr << endl;
+ }
+
+ // Serialize.
+ //
+ xml_schema::namespace_infomap map;
+
+ map["ppl"].name = "http://www.codesynthesis.com/people";
+ map["ppl"].schema = "people.xsd";
+
+ directory_ (
+ std::cout, *d, map, "UTF-8", xml_schema::flags::dont_initialize);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+
+ XMLPlatformUtils::Terminate ();
+ return r;
+}
+
+// Primitive XHTML to text converter that just prints all the text
+// nodes and ignores everything else.
+//
+void
+xhtml2txt (const DOMElement* e)
+{
+ namespace xml = xsd::cxx::xml;
+
+ for (const DOMNode* n (e->getFirstChild ());
+ n != 0;
+ n = n->getNextSibling ())
+ {
+ switch (n->getNodeType ())
+ {
+ case DOMNode::TEXT_NODE:
+ {
+ cerr << xml::transcode<char> (n->getTextContent ());
+ break;
+ }
+ case DOMNode::ELEMENT_NODE:
+ {
+ xhtml2txt (static_cast<const DOMElement*> (n));
+ break;
+ }
+ default:
+ break; // Ignore all other nodes (e.g., comments, etc).
+ }
+ }
+}
diff --git a/xsd-examples/cxx/tree/custom/mixed/people-custom.cxx b/xsd-examples/cxx/tree/custom/mixed/people-custom.cxx
new file mode 100644
index 0000000..bd03fcc
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/people-custom.cxx
@@ -0,0 +1,89 @@
+// file : cxx/tree/custom/mixed/people-custom.cxx
+// copyright : not copyrighted - public domain
+
+#include <ostream>
+
+// Include people.hxx instead of people-custom.hxx here.
+//
+#include "people.hxx"
+
+namespace people
+{
+ using namespace xercesc;
+
+ const XMLCh ls[] = {chLatin_L, chLatin_S, chNull};
+
+ bio::
+ bio ()
+ : xhtml_ (0)
+ {
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls));
+
+ doc_.reset (impl->createDocument ());
+ }
+
+ bio::
+ bio (const DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : bio_base (e, f, c), xhtml_ (0)
+ {
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls));
+
+ doc_.reset (impl->createDocument ());
+
+ // Copy the xhtml element. Assume the first child element in
+ // e is always xhtml.
+ //
+ for (DOMNode* n (e.getFirstChild ()); n != 0; n = n->getNextSibling ())
+ {
+ if (n->getNodeType () == DOMNode::ELEMENT_NODE)
+ {
+ xhtml_ = static_cast<DOMElement*> (doc_->importNode (n, true));
+ break;
+ }
+ }
+ }
+
+ bio::
+ bio (const bio& d,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : bio_base (d, f, c), xhtml_ (0)
+ {
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls));
+
+ doc_.reset (impl->createDocument ());
+
+ xhtml_ = static_cast<DOMElement*> (
+ doc_->importNode (const_cast<DOMElement*> (d.xhtml_), true));
+ }
+
+ bio* bio::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new bio (*this, f, c);
+ }
+
+ void
+ operator<< (DOMElement& e, const bio& x)
+ {
+ // Allow our base to serialize first.
+ //
+ const bio_base& b (x);
+ e << b;
+
+ // Copy the XHTML fragment if we have one.
+ //
+ const DOMElement* xhtml (x.xhtml ());
+
+ if (xhtml != 0)
+ {
+ DOMDocument* doc (e.getOwnerDocument ());
+ e.appendChild (doc->importNode (const_cast<DOMElement*> (xhtml), true));
+ }
+ }
+}
diff --git a/xsd-examples/cxx/tree/custom/mixed/people-custom.hxx b/xsd-examples/cxx/tree/custom/mixed/people-custom.hxx
new file mode 100644
index 0000000..2ab949d
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/people-custom.hxx
@@ -0,0 +1,83 @@
+// file : cxx/tree/custom/mixed/people-custom.hxx
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use people.hxx instead. This
+// file is included into generated people.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <cassert>
+#include <xercesc/dom/DOM.hpp>
+
+namespace people
+{
+ class bio: public bio_base
+ {
+ // Standard constructors.
+ //
+ public:
+ bio ();
+
+ bio (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ bio (const bio&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ virtual bio*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ // XHTML bio as a DOM document.
+ //
+ public:
+ const xercesc::DOMElement*
+ xhtml () const
+ {
+ return xhtml_;
+ }
+
+ xercesc::DOMElement*
+ xhtml ()
+ {
+ return xhtml_;
+ }
+
+ // The element should belong to the DOMDocument returned by
+ // the dom_document() functions.
+ //
+ void
+ xhtml (xercesc::DOMElement* e)
+ {
+ assert (e->getOwnerDocument () == doc_.get ());
+
+ if (xhtml_ != 0)
+ xhtml_->release ();
+
+ xhtml_ = e;
+ }
+
+ const xercesc::DOMDocument&
+ dom_document () const
+ {
+ return *doc_;
+ }
+
+ xercesc::DOMDocument&
+ dom_document ()
+ {
+ return *doc_;
+ }
+
+ private:
+ xercesc::DOMElement* xhtml_;
+ xml_schema::dom::unique_ptr<xercesc::DOMDocument> doc_;
+ };
+
+ // Serialization operator.
+ //
+ void
+ operator<< (xercesc::DOMElement&, const bio&);
+}
diff --git a/xsd-examples/cxx/tree/custom/mixed/people.xml b/xsd-examples/cxx/tree/custom/mixed/people.xml
new file mode 100644
index 0000000..4033f95
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/people.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/mixed/people.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<ppl:directory xmlns:ppl="http://www.codesynthesis.com/people"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/people people.xsd">
+
+ <person>
+ <first-name>John</first-name>
+ <last-name>Doe</last-name>
+ <gender>male</gender>
+ <age>32</age>
+ <bio>
+ <xhtml xmlns="http://www.w3.org/1999/xhtml">
+ <p>Married to Jane Doe.</p>
+ </xhtml>
+ </bio>
+ </person>
+
+ <person>
+ <first-name>Jane</first-name>
+ <last-name>Doe</last-name>
+ <gender>female</gender>
+ <age>28</age>
+ <bio>
+ <xhtml xmlns="http://www.w3.org/1999/xhtml">
+ <p>Married to John Doe.</p>
+ </xhtml>
+ </bio>
+ </person>
+
+</ppl:directory>
diff --git a/xsd-examples/cxx/tree/custom/mixed/people.xsd b/xsd-examples/cxx/tree/custom/mixed/people.xsd
new file mode 100644
index 0000000..739861b
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/mixed/people.xsd
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/mixed/people.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:ppl="http://www.codesynthesis.com/people"
+ targetNamespace="http://www.codesynthesis.com/people">
+
+ <xsd:simpleType name="gender">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="male"/>
+ <xsd:enumeration value="female"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:complexType name="bio" mixed="true">
+ <xsd:sequence minOccurs="0" maxOccurs="unbounded">
+ <xsd:any namespace="http://www.w3.org/1999/xhtml" processContents="skip"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="first-name" type="xsd:string"/>
+ <xsd:element name="last-name" type="xsd:string"/>
+ <xsd:element name="gender" type="ppl:gender"/>
+ <xsd:element name="age" type="xsd:unsignedShort"/>
+ <xsd:element name="bio" type="ppl:bio"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="directory">
+ <xsd:sequence>
+ <xsd:element name="person" type="ppl:person" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="directory" type="ppl:directory"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/tree/custom/taxonomy/.gitignore b/xsd-examples/cxx/tree/custom/taxonomy/.gitignore
new file mode 100644
index 0000000..71428ab
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/.gitignore
@@ -0,0 +1,2 @@
+people.?xx
+people-fwd.hxx
diff --git a/xsd-examples/cxx/tree/custom/taxonomy/README b/xsd-examples/cxx/tree/custom/taxonomy/README
new file mode 100644
index 0000000..c2e425a
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/README
@@ -0,0 +1,53 @@
+This example shows how to map user-defined XML Schema types to custom C++
+classes. It presents the complex case where the customized types are
+inherited from in the same schema. For the simple case see the contacts
+example. For more information on the C++/Tree mapping customization see
+the C++/Tree Mapping Customization Guide[1].
+
+[1] http://wiki.codesynthesis.com/Tree/Customization_guide
+
+The example consists of the following files:
+
+people.xsd
+ XML Schema definition for a simple people database.
+
+people.xml
+ Sample XML instance document.
+
+people-fwd.hxx
+people.hxx
+people.ixx
+people.cxx
+ C++ types that represent the given vocabulary and a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model. These are generated by XSD from people.xsd with the
+ --custom-type option in order to customize the person, superman, and
+ batman types. Generation of the people-fwd.hxx forward declaration
+ file is requested with the --generate-forward option. Note also that
+ we use the --generate-polymorphic command line option as well as
+ --polymorphic-type to mark the type hierarchy starting with the
+ person type as polymorphic.
+
+people-custom-fwd.hxx
+ Header file which forward-declares our own person, superman, and batman
+ as class templates. It is included at the beginning of people-fwd.hxx
+ using the --fwd-prologue option.
+
+people-custom.hxx
+ Header file which defines our own person, superman, and batman class
+ templates by inheriting from the generated person_base, superman_base,
+ and batman_base. It is included at the beginning of people.hxx using
+ the --hxx-prologue option.
+
+people-custom.cxx
+ Source file which contains the implementations and instantiations of
+ our person, superman, and batman class templates.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input file. It then prints
+ the database to STDERR.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver people.xml
diff --git a/xsd-examples/cxx/tree/custom/taxonomy/buildfile b/xsd-examples/cxx/tree/custom/taxonomy/buildfile
new file mode 100644
index 0000000..9267c68
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/buildfile
@@ -0,0 +1,31 @@
+# file : cxx/tree/custom/taxonomy/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -people} {hxx ixx cxx}{people} hxx{people-fwd} $libs
+
+exe{driver}: xml{people}: test.input = true
+
+<{hxx ixx cxx}{people} hxx{people-fwd}>: xsd{people} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-forward \
+ --generate-polymorphic \
+ --polymorphic-type person \
+ --custom-type "person=person_impl<person_base>/person_base" \
+ --custom-type "superman=superman_impl<superman_base>/superman_base" \
+ --custom-type "batman=batman_impl<batman_base>/batman_base" \
+ --fwd-prologue '#include "people-custom-fwd.hxx"' \
+ --hxx-prologue '#include "people-custom.hxx"' \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
diff --git a/xsd-examples/cxx/tree/custom/taxonomy/driver.cxx b/xsd-examples/cxx/tree/custom/taxonomy/driver.cxx
new file mode 100644
index 0000000..f719bbb
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/driver.cxx
@@ -0,0 +1,38 @@
+// file : cxx/tree/custom/taxonomy/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <iostream>
+
+#include "people.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " people.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace people;
+
+ std::unique_ptr<catalog> c (catalog_ (argv[1]));
+
+ for (catalog::person_const_iterator i (c->person ().begin ());
+ i != c->person ().end (); ++i)
+ {
+ i->print (cerr);
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx b/xsd-examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx
new file mode 100644
index 0000000..1b59a54
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx
@@ -0,0 +1,19 @@
+// file : cxx/tree/custom/taxonomy/people-custom-fwd.hxx
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use people-fwd.hxx instead. This
+// file is included into generated people-fwd.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+namespace people
+{
+ template <typename base>
+ class person_impl;
+
+ template <typename base>
+ class superman_impl;
+
+ template <typename base>
+ class batman_impl;
+}
diff --git a/xsd-examples/cxx/tree/custom/taxonomy/people-custom.cxx b/xsd-examples/cxx/tree/custom/taxonomy/people-custom.cxx
new file mode 100644
index 0000000..decc847
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/people-custom.cxx
@@ -0,0 +1,156 @@
+// file : cxx/tree/custom/taxonomy/people-custom.cxx
+// copyright : not copyrighted - public domain
+
+#include <ostream>
+
+// Include people.hxx instead of people-custom.hxx here.
+//
+#include "people.hxx"
+
+namespace people
+{
+ // person_impl
+ //
+ template <typename base>
+ person_impl<base>::
+ person_impl (const xml_schema::string& name)
+ : base (name)
+ {
+ }
+
+ template <typename base>
+ person_impl<base>::
+ person_impl (const xercesc::DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : base (e, f, c)
+ {
+ }
+
+ template <typename base>
+ person_impl<base>::
+ person_impl (const person_impl& p,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : base (p, f, c)
+ {
+ }
+
+ template <typename base>
+ person_impl<base>* person_impl<base>::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new person_impl (*this, f, c);
+ }
+
+ template <typename base>
+ void person_impl<base>::
+ print (std::ostream& os) const
+ {
+ os << this->name () << std::endl;
+ }
+
+ // Explicitly instantiate person_impl class template for person_base.
+ //
+ template class person_impl<person_base>;
+
+
+ // superman_impl
+ //
+ template <typename base>
+ superman_impl<base>::
+ superman_impl (const xml_schema::string& name, bool can_fly)
+ : base (name, can_fly)
+ {
+ }
+
+ template <typename base>
+ superman_impl<base>::
+ superman_impl (const xercesc::DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : base (e, f, c)
+ {
+ }
+
+ template <typename base>
+ superman_impl<base>::
+ superman_impl (const superman_impl& s,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : base (s, f, c)
+ {
+ }
+
+ template <typename base>
+ superman_impl<base>* superman_impl<base>::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new superman_impl (*this, f, c);
+ }
+
+ template <typename base>
+ void superman_impl<base>::
+ print (std::ostream& os) const
+ {
+ if (this->can_fly ())
+ os << "Flying superman ";
+ else
+ os << "Superman ";
+
+ os << this->name () << std::endl;
+ }
+
+ // Explicitly instantiate superman_impl class template for superman_base.
+ //
+ template class superman_impl<superman_base>;
+
+
+ // batman_impl
+ //
+ template <typename base>
+ batman_impl<base>::
+ batman_impl (const xml_schema::string& name,
+ bool can_fly,
+ unsigned int wing_span)
+ : base (name, can_fly, wing_span)
+ {
+ }
+
+ template <typename base>
+ batman_impl<base>::
+ batman_impl (const xercesc::DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : base (e, f, c)
+ {
+ }
+
+ template <typename base>
+ batman_impl<base>::
+ batman_impl (const batman_impl& s,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : base (s, f, c)
+ {
+ }
+
+ template <typename base>
+ batman_impl<base>* batman_impl<base>::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new batman_impl (*this, f, c);
+ }
+
+ template <typename base>
+ void batman_impl<base>::
+ print (std::ostream& os) const
+ {
+ os << "Batman " << this->name () << " with " <<
+ this->wing_span () << "m wing span" << std::endl;
+ }
+
+ // Explicitly instantiate batman_impl class template for batman_base.
+ //
+ template class batman_impl<batman_base>;
+}
diff --git a/xsd-examples/cxx/tree/custom/taxonomy/people-custom.hxx b/xsd-examples/cxx/tree/custom/taxonomy/people-custom.hxx
new file mode 100644
index 0000000..58c94c4
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/people-custom.hxx
@@ -0,0 +1,105 @@
+// file : cxx/tree/custom/taxonomy/people-custom.hxx
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use people.hxx instead. This
+// file is included into generated people.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <iosfwd> // std::ostream
+
+// Include people-fwd.hxx here so that we can refer to the generated
+// types.
+//
+#include "people-fwd.hxx"
+
+namespace people
+{
+ //
+ //
+ template <typename base>
+ class person_impl: public base
+ {
+ public:
+ person_impl (const xml_schema::string& name);
+
+ person_impl (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ person_impl (const person_impl&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ person_impl&
+ operator= (const person_impl&) = default;
+
+ virtual person_impl*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ public:
+ virtual void
+ print (std::ostream&) const;
+ };
+
+
+ //
+ //
+ template <typename base>
+ class superman_impl: public base
+ {
+ public:
+ superman_impl (const xml_schema::string& name, bool can_fly);
+
+ superman_impl (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ superman_impl (const superman_impl&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ virtual superman_impl*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ superman_impl&
+ operator= (const superman_impl&) = default;
+
+ public:
+ virtual void
+ print (std::ostream&) const;
+ };
+
+
+ //
+ //
+ template <typename base>
+ class batman_impl: public base
+ {
+ public:
+ batman_impl (const xml_schema::string& name,
+ bool can_fly,
+ unsigned int wing_span);
+
+ batman_impl (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ batman_impl (const batman_impl&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ batman_impl&
+ operator= (const batman_impl&) = default;
+
+ virtual batman_impl*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ public:
+ virtual void
+ print (std::ostream&) const;
+ };
+}
diff --git a/xsd-examples/cxx/tree/custom/taxonomy/people.xml b/xsd-examples/cxx/tree/custom/taxonomy/people.xml
new file mode 100644
index 0000000..831c547
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/people.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/taxonomy/people.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<ppl:catalog xmlns:ppl="http://www.codesynthesis.com/people"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/people people.xsd">
+
+ <person>
+ <name>Joe Dirt</name>
+ </person>
+
+ <person xsi:type="ppl:superman" can-fly="false">
+ <name>James "007" Bond</name>
+ </person>
+
+ <person xsi:type="ppl:batman" can-fly="true" wing-span="10">
+ <name>Bruce Wayne</name>
+ </person>
+
+</ppl:catalog>
diff --git a/xsd-examples/cxx/tree/custom/taxonomy/people.xsd b/xsd-examples/cxx/tree/custom/taxonomy/people.xsd
new file mode 100644
index 0000000..b07f338
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/taxonomy/people.xsd
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/taxonomy/people.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:ppl="http://www.codesynthesis.com/people"
+ targetNamespace="http://www.codesynthesis.com/people">
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="superman">
+ <xsd:complexContent>
+ <xsd:extension base="ppl:person">
+ <xsd:attribute name="can-fly" type="xsd:boolean" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="batman">
+ <xsd:complexContent>
+ <xsd:extension base="ppl:superman">
+ <xsd:attribute name="wing-span" type="xsd:unsignedInt" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="catalog">
+ <xsd:sequence>
+ <xsd:element name="person" type="ppl:person" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="catalog" type="ppl:catalog"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/tree/custom/wildcard/.gitignore b/xsd-examples/cxx/tree/custom/wildcard/.gitignore
new file mode 100644
index 0000000..f32cbe8
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/.gitignore
@@ -0,0 +1 @@
+wildcard.?xx
diff --git a/xsd-examples/cxx/tree/custom/wildcard/README b/xsd-examples/cxx/tree/custom/wildcard/README
new file mode 100644
index 0000000..70eaea4
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/README
@@ -0,0 +1,45 @@
+This example shows how to use type customization to parse and serialize
+a specific attribute that is matched by a wildcard (anyAttribute). The
+example achieves this by customizing the type to include the data
+members and accessors/modifiers that represent the attribute as well as
+the parsing constructor and serialization operator where the attribute
+value is extracted from and inserted back to DOM, respectively. For
+more information on the C++/Tree mapping customization see the C++/Tree
+Mapping Customization Guide[1].
+
+[1] http://wiki.codesynthesis.com/Tree/Customization_guide
+
+The example consists of the following files:
+
+wildcard.xsd
+ XML Schema definition for simple data type and element.
+
+wildcard.xml
+ Sample XML instance document.
+
+wildcard.hxx
+wildcard.ixx
+wildcard.cxx
+ C++ types that represent the given vocabulary, a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model, and a set of serialization functions that convert the
+ object model back to XML. These are generated by XSD from wildcard.xsd
+ with the --custom-type option in order to customize the data type.
+
+wildcard-custom.hxx
+ Header file which defines our own data class by inheriting from the
+ generated data_base. It is included at the end of wildcard.hxx using
+ the --hxx-epilogue option.
+
+wildcard-custom.cxx
+ Source file which contains the implementation of our data class.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input file. It then prints
+ the data to STDERR, including the extra attribute. Finally, the driver
+ serializes the object model back to XML.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver wildcard.xml
diff --git a/xsd-examples/cxx/tree/custom/wildcard/buildfile b/xsd-examples/cxx/tree/custom/wildcard/buildfile
new file mode 100644
index 0000000..e386709
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/buildfile
@@ -0,0 +1,27 @@
+# file : cxx/tree/custom/wildcard/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -wildcard} {hxx ixx cxx}{wildcard} $libs
+
+exe{driver}: xml{wildcard}: test.input = true
+
+<{hxx ixx cxx}{wildcard}>: xsd{wildcard} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-serialization \
+ --generate-ostream \
+ --custom-type data=/data_base \
+ --hxx-epilogue '#include "wildcard-custom.hxx"' \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
diff --git a/xsd-examples/cxx/tree/custom/wildcard/driver.cxx b/xsd-examples/cxx/tree/custom/wildcard/driver.cxx
new file mode 100644
index 0000000..43fae82
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/driver.cxx
@@ -0,0 +1,47 @@
+// file : cxx/tree/custom/wildcard/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <iostream>
+
+#include "wildcard.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " wildcard.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace wildcard;
+
+ // Parse.
+ //
+ std::unique_ptr<data> d (data_ (argv[1]));
+
+ // Print.
+ //
+ cerr << *d << endl;
+
+ // Serialize.
+ //
+ xml_schema::namespace_infomap map;
+
+ map["wc"].name = "http://www.codesynthesis.com/wildcard";
+ map["wc"].schema = "wildcard.xsd";
+
+ data_ (std::cout, *d, map);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/tree/custom/wildcard/wildcard-custom.cxx b/xsd-examples/cxx/tree/custom/wildcard/wildcard-custom.cxx
new file mode 100644
index 0000000..16798d2
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/wildcard-custom.cxx
@@ -0,0 +1,84 @@
+// file : cxx/tree/custom/wildcard/wildcard-custom.cxx
+// copyright : not copyrighted - public domain
+
+#include <ostream>
+
+// Include wildcard.hxx instead of wildcard-custom.hxx here.
+//
+#include "wildcard.hxx"
+
+namespace wildcard
+{
+ data::
+ data (const xml_schema::string& d)
+ : data_base (d), scope_present_ (false)
+ {
+ }
+
+ data::
+ data (const xercesc::DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : data_base (e, f, c), scope_present_ (false)
+ {
+ // Check if we've got the scope attribute.
+ //
+ namespace xml = xsd::cxx::xml;
+ xml::string name ("scope");
+
+ if (e.hasAttribute (name.c_str ()))
+ {
+ scope (xml::transcode<char> (e.getAttribute (name.c_str ())));
+ }
+ }
+
+ data::
+ data (const data& d,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : data_base (d, f, c),
+ scope_present_ (d.scope_present_),
+ scope_ (d.scope_)
+ {
+ }
+
+ data* data::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new data (*this, f, c);
+ }
+
+ void
+ operator<< (xercesc::DOMElement& e, const data& x)
+ {
+ // Use our base to serialize data and id.
+ //
+ const data_base& b (x);
+ e << b;
+
+ // Add the scope attribute if present.
+ //
+ if (x.scope_present ())
+ {
+ namespace xml = xsd::cxx::xml;
+ xml::string name ("scope");
+ xml::string value (x.scope ());
+
+ e.setAttribute (name.c_str (), value.c_str ());
+ }
+ }
+
+ std::ostream&
+ operator<< (std::ostream& os, const data& x)
+ {
+ // Use our base to print date and id.
+ //
+ const data_base& b (x);
+ os << b;
+
+ if (x.scope_present ())
+ os << std::endl << "scope: " << x.scope ();
+
+ return os;
+ }
+}
diff --git a/xsd-examples/cxx/tree/custom/wildcard/wildcard-custom.hxx b/xsd-examples/cxx/tree/custom/wildcard/wildcard-custom.hxx
new file mode 100644
index 0000000..e789a86
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/wildcard-custom.hxx
@@ -0,0 +1,66 @@
+// file : cxx/tree/custom/wildcard/wildcard-custom.hxx
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use wildcard.hxx instead. This
+// file is included into generated wildcard.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+namespace wildcard
+{
+ class data: public data_base
+ {
+ // Standard constructors.
+ //
+ public:
+ data (const xml_schema::string&);
+
+ data (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ data (const data&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ virtual data*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ // Our customizations.
+ //
+ public:
+ bool
+ scope_present () const
+ {
+ return scope_present_;
+ }
+
+ const xml_schema::string&
+ scope () const
+ {
+ return scope_;
+ }
+
+ void
+ scope (const xml_schema::string& s)
+ {
+ scope_present_ = true;
+ scope_ = s;
+ }
+
+ private:
+ bool scope_present_;
+ xml_schema::string scope_;
+ };
+
+ // Serialization operator.
+ //
+ void
+ operator<< (xercesc::DOMElement&, const data&);
+
+ // std::ostream insertion operator.
+ //
+ std::ostream&
+ operator<< (std::ostream&, const data&);
+}
diff --git a/xsd-examples/cxx/tree/custom/wildcard/wildcard.xml b/xsd-examples/cxx/tree/custom/wildcard/wildcard.xml
new file mode 100644
index 0000000..8f6ba65
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/wildcard.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/wildcard/wildcard.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<wc:data xmlns:wc="http://www.codesynthesis.com/wildcard"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/wildcard wildcard.xsd"
+ id="1"
+ scope="global">abc123</wc:data>
diff --git a/xsd-examples/cxx/tree/custom/wildcard/wildcard.xsd b/xsd-examples/cxx/tree/custom/wildcard/wildcard.xsd
new file mode 100644
index 0000000..a19be3f
--- /dev/null
+++ b/xsd-examples/cxx/tree/custom/wildcard/wildcard.xsd
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/custom/wildcard/wildcard.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wc="http://www.codesynthesis.com/wildcard"
+ targetNamespace="http://www.codesynthesis.com/wildcard">
+
+ <xsd:complexType name="data">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="id" type="xsd:unsignedInt"/>
+ <xsd:anyAttribute namespace="##any" processContents="skip"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:element name="data" type="wc:data"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/tree/embedded/.gitignore b/xsd-examples/cxx/tree/embedded/.gitignore
new file mode 100644
index 0000000..9023e82
--- /dev/null
+++ b/xsd-examples/cxx/tree/embedded/.gitignore
@@ -0,0 +1,3 @@
+xsdbin
+library.?xx
+library-schema.?xx
diff --git a/xsd-examples/cxx/tree/embedded/README b/xsd-examples/cxx/tree/embedded/README
new file mode 100644
index 0000000..266a8ff
--- /dev/null
+++ b/xsd-examples/cxx/tree/embedded/README
@@ -0,0 +1,48 @@
+This example shows how to embed the binary representation of the schema
+grammar into an application and then use it with the C++/Tree mapping to
+parse and validate XML documents. This example is similar to the 'caching'
+example except that it loads the binary representation of the schemas
+embedded into the application instead of pre-parsing external schema files.
+
+The example consists of the following files:
+
+xsdbin.cxx
+ Tool for converting one or more XML Schema files to the compressed binary
+ representation. The output is written as a pair of C++ source files
+ containing the array with the binary data. Use the --help option to see
+ the tool's usage information.
+
+library.xsd
+ XML Schema which describes a library of books.
+
+library.xml
+ Sample XML instance document.
+
+library.hxx
+library.cxx
+ C++ types that represent the given vocabulary and a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model. These are generated by the XSD compiler from library.xsd.
+
+library-schema.hxx
+library-schema.cxx
+ Binary representation of the library.xsd schema. These files are generated
+ by the xsdbin tool.
+
+grammar-input-stream.hxx
+grammar-input-stream.cxx
+ Input stream implementation with the special-purpose schema grammar
+ decompression algorithm. It is used to load the binary schema representation
+ produced by the xsdbin tool.
+
+driver.cxx
+ Driver for the example. It first sets up the Xerces-C++ DOM parser and
+ loads the embedded binary schema grammar for validation. It then performs
+ ten iterations that parse the input file to a DOM document using the DOM
+ parser and call one of the parsing functions that constructs the object
+ model from this DOM document. On each iteration the driver prints a number
+ of books in the 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/tree/embedded/buildfile b/xsd-examples/cxx/tree/embedded/buildfile
new file mode 100644
index 0000000..c8e7808
--- /dev/null
+++ b/xsd-examples/cxx/tree/embedded/buildfile
@@ -0,0 +1,46 @@
+# file : cxx/tree/embedded/buildfile
+# license : not copyrighted - public domain
+
+import libxsd = libxsd%lib{xsd}
+import libxerces = libxerces-c%lib{xerces-c}
+
+./: exe{driver} exe{xsdbin} doc{README}
+
+# exe{driver}
+#
+exe{driver}: {hxx cxx}{* -xsdbin -library -library-schema} \
+ {hxx ixx cxx}{library} \
+ {hxx cxx}{library-schema} \
+ $libxsd $libxerces
+
+exe{driver}: xml{library}: test.input = true
+
+<{hxx ixx cxx}{library}>: xsd{library} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+<{hxx cxx}{library-schema}>: xsd{library} exe{xsdbin}
+{{
+ diag xsdbin ($<[0]) # @@ TMP
+
+ ($<[1]) --output-dir $out_base $path($<[0])
+}}
+
+# exe{xsdbin}
+#
+exe{xsdbin}: cxx{xsdbin} $libxerces
+exe{xsdbin}: test = false
+
+# Build options.
+#
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/embedded/driver.cxx b/xsd-examples/cxx/tree/embedded/driver.cxx
new file mode 100644
index 0000000..445d046
--- /dev/null
+++ b/xsd-examples/cxx/tree/embedded/driver.cxx
@@ -0,0 +1,183 @@
+// file : cxx/tree/embedded/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_*
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/validators/common/Grammar.hpp> // xercesc::Grammar
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
+
+#include <xsd/cxx/xml/string.hxx>
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+
+#include <xsd/cxx/tree/error-handler.hxx>
+
+#include "library.hxx"
+#include "library-schema.hxx"
+#include "grammar-input-stream.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " library.xml" << endl;
+ return 1;
+ }
+
+ int r (0);
+
+ // We need to initialize the Xerces-C++ runtime because we
+ // are doing the XML-to-DOM parsing ourselves.
+ //
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ using namespace xercesc;
+ namespace xml = xsd::cxx::xml;
+ namespace tree = xsd::cxx::tree;
+
+ // Create and load the grammar pool.
+ //
+ MemoryManager* mm (XMLPlatformUtils::fgMemoryManager);
+
+ unique_ptr<XMLGrammarPool> gp (new XMLGrammarPoolImpl (mm));
+
+ try
+ {
+ grammar_input_stream is (library_schema, sizeof (library_schema));
+ gp->deserializeGrammars(&is);
+ }
+ catch(const XSerializationException& e)
+ {
+ cerr << "unable to load schema: " <<
+ xml::transcode<char> (e.getMessage ()) << endl;
+ return 1;
+ }
+
+ // Lock the grammar pool. This is necessary if we plan to use the
+ // same grammar pool in multiple threads (this way we can reuse the
+ // same grammar in multiple parsers). Locking the pool disallows any
+ // modifications to the pool, such as an attempt by one of the threads
+ // to cache additional schemas.
+ //
+ gp->lockPool ();
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+ xml::dom::unique_ptr<DOMLSParser> parser (
+ impl->createLSParser (
+ DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp.get ()));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, true);
+ conf->setParameter (XMLUni::fgXercesSchema, true);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support.
+ //
+#if _XERCES_VERSION >= 30100
+ conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+#endif
+
+ // Use the loaded grammar during parsing.
+ //
+ conf->setParameter (XMLUni::fgXercesUseCachedGrammarInParse, true);
+
+ // Disable loading schemas via other means (e.g., schemaLocation).
+ //
+ conf->setParameter (XMLUni::fgXercesLoadSchema, false);
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ // Set error handler.
+ //
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+ // Parse XML documents.
+ //
+ for (unsigned long i (0); i < 10; ++i)
+ {
+ ifstream ifs;
+ ifs.exceptions (ifstream::badbit | ifstream::failbit);
+ ifs.open (argv[1]);
+
+ // Wrap the standard input stream.
+ //
+ xml::sax::std_input_source isrc (ifs, argv[1]);
+ Wrapper4InputSource wrap (&isrc, false);
+
+ // Parse XML to DOM.
+ //
+ xml_schema::dom::unique_ptr<DOMDocument> doc (parser->parse (&wrap));
+
+ eh.throw_if_failed<xml_schema::parsing> ();
+
+ // Parse DOM to the object model.
+ //
+ unique_ptr<library::catalog> c (library::catalog_ (*doc));
+
+ cerr << "catalog with " << c->book ().size () << " books" << endl;
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ r = 1;
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+ return r;
+}
diff --git a/xsd-examples/cxx/tree/embedded/grammar-input-stream.cxx b/xsd-examples/cxx/tree/embedded/grammar-input-stream.cxx
new file mode 100644
index 0000000..118ecb0
--- /dev/null
+++ b/xsd-examples/cxx/tree/embedded/grammar-input-stream.cxx
@@ -0,0 +1,95 @@
+// file : cxx/tree/embedded/grammar-input-stream.cxx
+// copyright : not copyrighted - public domain
+
+#include <cassert>
+#include "grammar-input-stream.hxx"
+
+grammar_input_stream::
+grammar_input_stream (const XMLByte* data, std::size_t size)
+ : data_ (data),
+ size_ (size),
+ pos_ (0),
+ vpos_ (0),
+ cseq_ (0),
+ add_zero_ (false)
+{
+}
+
+XMLFilePos grammar_input_stream::
+curPos () const
+{
+ return static_cast<XMLFilePos> (vpos_);
+}
+
+XMLSize_t grammar_input_stream::
+readBytes (XMLByte* const buf, const XMLSize_t size)
+{
+ std::size_t i (0);
+
+ // Add a zero from the alternating sequence if it didn't
+ // fit on the previous read.
+ //
+ if (add_zero_)
+ {
+ buf[i++] = 0;
+ add_zero_ = false;
+ }
+
+ // If have an unfinished sequential sequence, output it now.
+ //
+ if (cseq_ != 0 && !alt_)
+ {
+ for (; cseq_ != 0 && i < size; --cseq_)
+ buf[i++] = 0;
+ }
+
+ for (; i < size && pos_ < size_;)
+ {
+ XMLByte b = buf[i++] = data_[pos_++];
+
+ // See if we are in a compression sequence.
+ //
+ if (cseq_ != 0)
+ {
+ if (i < size)
+ buf[i++] = 0;
+ else
+ add_zero_ = true; // Add it on the next read.
+
+ cseq_--;
+ continue;
+ }
+
+ // If we are not in a compression sequence and this byte is
+ // not zero then we are done.
+ //
+ if (b != 0)
+ continue;
+
+ // We have a zero.
+ //
+ assert (pos_ < size_); // There has to be another byte.
+ unsigned char v (static_cast<unsigned char> (data_[pos_++]));
+ alt_ = (v & 128) != 0;
+ cseq_ = v & 127;
+
+ // If it is a sequential sequence, output as many zeros as
+ // we can.
+ //
+ if (!alt_)
+ {
+ for (; cseq_ != 0 && i < size; --cseq_)
+ buf[i++] = 0;
+ }
+ }
+
+ vpos_ += i;
+
+ return static_cast<XMLSize_t> (i);
+}
+
+const XMLCh* grammar_input_stream::
+getContentType () const
+{
+ return 0;
+}
diff --git a/xsd-examples/cxx/tree/embedded/grammar-input-stream.hxx b/xsd-examples/cxx/tree/embedded/grammar-input-stream.hxx
new file mode 100644
index 0000000..701be31
--- /dev/null
+++ b/xsd-examples/cxx/tree/embedded/grammar-input-stream.hxx
@@ -0,0 +1,40 @@
+// file : cxx/tree/embedded/grammar-input-stream.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef GRAMMAR_INPUT_STREAM_HXX
+#define GRAMMAR_INPUT_STREAM_HXX
+
+#include <cstddef>
+#include <xercesc/util/BinInputStream.hpp>
+
+// Memory buffer input stream with the special-purpose schema
+// grammar decompression.
+//
+class grammar_input_stream: public xercesc::BinInputStream
+{
+public :
+ grammar_input_stream (const XMLByte* data, std::size_t size);
+
+ virtual XMLFilePos
+ curPos () const;
+
+ virtual XMLSize_t
+ readBytes (XMLByte* const buf, const XMLSize_t size);
+
+ virtual const XMLCh*
+ getContentType () const;
+
+private :
+ const XMLByte* data_;
+ std::size_t size_;
+ std::size_t pos_;
+ std::size_t vpos_;
+
+ // Compression data.
+ //
+ size_t cseq_; // Number of bytes left in a compression sequence.
+ bool alt_; // Alternating or sequential sequence.
+ bool add_zero_; // Add a zero on the next read.
+};
+
+#endif // GRAMMAR_INPUT_STREAM_HXX
diff --git a/xsd-examples/cxx/tree/embedded/library.xml b/xsd-examples/cxx/tree/embedded/library.xml
new file mode 100644
index 0000000..f2816e7
--- /dev/null
+++ b/xsd-examples/cxx/tree/embedded/library.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/embedded/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">
+ <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/tree/embedded/library.xsd b/xsd-examples/cxx/tree/embedded/library.xsd
new file mode 100644
index 0000000..0ffee32
--- /dev/null
+++ b/xsd-examples/cxx/tree/embedded/library.xsd
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/embedded/library.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension"
+ 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:language"/>
+ </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:date"/>
+ <xsd:element name="died" type="xsd:date" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="author">
+ <xsd:complexContent>
+ <xsd:extension base="lib:person">
+ <xsd:attribute name="recommends" type="xsd:IDREF" xse:refType="lib: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" default="true"/>
+ <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/tree/embedded/xsdbin.cxx b/xsd-examples/cxx/tree/embedded/xsdbin.cxx
new file mode 100644
index 0000000..3539c52
--- /dev/null
+++ b/xsd-examples/cxx/tree/embedded/xsdbin.cxx
@@ -0,0 +1,494 @@
+// file : cxx/tree/embedded/xsdbin.cxx
+// copyright : not copyrighted - public domain
+
+// This program loads the XML Schema file(s) and converts them to
+// the Xerces-C++ binary schema format which can then be embedded
+// into C++ programs and used to validate XML documents. The output
+// is written as a C++ source file containing the array with the
+// binary data.
+//
+
+#include <string>
+#include <memory> // std::unique_ptr
+#include <cstddef> // std::size_t
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/util/XMLUni.hpp>
+#include <xercesc/util/XMLString.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/util/XercesVersion.hpp>
+
+#include <xercesc/internal/BinMemOutputStream.hpp>
+#include <xercesc/validators/common/Grammar.hpp>
+
+#include <xercesc/sax/ErrorHandler.hpp>
+#include <xercesc/sax/SAXParseException.hpp>
+#include <xercesc/sax2/SAX2XMLReader.hpp>
+#include <xercesc/sax2/XMLReaderFactory.hpp>
+
+#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
+
+using namespace std;
+using namespace xercesc;
+
+class error_handler: public ErrorHandler
+{
+public:
+ error_handler ()
+ : failed_ (false)
+ {
+ }
+
+ bool
+ failed () const
+ {
+ return failed_;
+ }
+
+ enum severity {s_warning, s_error, s_fatal};
+
+ virtual void
+ warning (const SAXParseException&);
+
+ virtual void
+ error (const SAXParseException&);
+
+ virtual void
+ fatalError (const SAXParseException&);
+
+ virtual void
+ resetErrors ()
+ {
+ failed_ = false;
+ }
+
+ void
+ handle (const SAXParseException&, severity);
+
+private:
+ bool failed_;
+};
+
+void
+cxx_escape (string&);
+
+int
+main (int argc, char* argv[])
+{
+ const char* hxx_suffix = "-schema.hxx";
+ const char* cxx_suffix = "-schema.cxx";
+
+ string name;
+ string base;
+ string outdir;
+
+ struct usage
+ {
+ usage (bool e = true): error (e) {}
+ bool error;
+ };
+
+ int argi (1);
+ bool multi_import (true);
+ bool verbose (false);
+
+ try
+ {
+ for (; argi < argc; ++argi)
+ {
+ string a (argv[argi]);
+
+ if (a == "--help")
+ throw usage (false);
+ else if (a == "--verbose")
+ {
+ verbose = true;
+ }
+ else if (a == "--hxx-suffix")
+ {
+ if (++argi >= argc)
+ throw usage ();
+
+ hxx_suffix = argv[argi];
+ }
+ else if (a == "--cxx-suffix")
+ {
+ if (++argi >= argc)
+ throw usage ();
+
+ cxx_suffix = argv[argi];
+ }
+ else if (a == "--output-dir")
+ {
+ if (++argi >= argc)
+ throw usage ();
+
+ outdir = argv[argi];
+ }
+ else if (a == "--array-name")
+ {
+ if (++argi >= argc)
+ throw usage ();
+
+ name = argv[argi];
+ }
+ else if (a == "--disable-multi-import")
+ {
+ multi_import = false;
+ }
+ else
+ break;
+ }
+
+ if (argi >= argc)
+ {
+ cerr << "no input file specified" << endl;
+ throw usage ();
+ }
+
+ base = argv[argi];
+ }
+ catch (usage const& e)
+ {
+ ostream& o (e.error ? cerr : cout);
+
+ o << "Usage: " << argv[0] << " [options] <files>" << endl
+ << "Options:" << endl
+ << " --help Print usage information and exit." << endl
+ << " --verbose Print progress information." << endl
+ << " --output-dir <dir> Write generated files to <dir>." << endl
+ << " --hxx-suffix <sfx> Header file suffix instead of '-schema.hxx'." << endl
+ << " --cxx-suffix <sfx> Source file suffix instead of '-schema.cxx'." << endl
+ << " --array-name <name> Binary data array name." << endl
+ << " --disable-multi-import Disable multiple import support." << endl
+ << endl;
+
+ return e.error ? 0 : 1;
+ }
+
+ XMLPlatformUtils::Initialize ();
+
+ {
+ MemoryManager* mm (XMLPlatformUtils::fgMemoryManager);
+
+ unique_ptr<XMLGrammarPool> gp (new XMLGrammarPoolImpl (mm));
+
+ // Load the schemas into grammar pool.
+ //
+ {
+ unique_ptr<SAX2XMLReader> parser (
+ XMLReaderFactory::createXMLReader (mm, gp.get ()));
+
+ parser->setFeature (XMLUni::fgSAX2CoreNameSpaces, true);
+ parser->setFeature (XMLUni::fgSAX2CoreNameSpacePrefixes, true);
+ parser->setFeature (XMLUni::fgSAX2CoreValidation, true);
+ parser->setFeature (XMLUni::fgXercesSchema, true);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, true);
+ parser->setFeature (XMLUni::fgXercesValidationErrorAsFatal, true);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support.
+ //
+#if _XERCES_VERSION >= 30100
+ parser->setFeature (XMLUni::fgXercesHandleMultipleImports, multi_import);
+#endif
+
+ error_handler eh;
+ parser->setErrorHandler (&eh);
+
+ for (; argi < argc; ++argi)
+ {
+ if (verbose)
+ cerr << "loading " << argv[argi] << endl;
+
+ if (!parser->loadGrammar (argv[argi], Grammar::SchemaGrammarType, true))
+ {
+ cerr << argv[argi] << ": error: unable to load" << endl;
+ return 1;
+ }
+
+ if (eh.failed ())
+ return 1;
+ }
+ }
+
+ // Get the binary representation.
+ //
+ BinMemOutputStream data;
+
+ try
+ {
+ gp->serializeGrammars (&data);
+ }
+ catch (const XSerializationException& e)
+ {
+ char* msg (XMLString::transcode (e.getMessage ()));
+ cerr << "error: " << msg << endl;
+ XMLString::release (&msg);
+ return 1;
+ }
+
+ size_t n (static_cast<size_t> (data.curPos ()));
+ const unsigned char* buf (
+ static_cast<const unsigned char*> (data.getRawBuffer ()));
+
+ if (verbose)
+ cerr << "uncomressed data size " << n << " bytes" << endl;
+
+ // Compress zeros.
+ //
+ size_t cn (0);
+ unsigned char* cbuf = new unsigned char[n];
+
+ size_t cseq (0); // Number of bytes left in a compression sequence.
+ bool alt (false); // Alternating or sequential sequence.
+
+ for (size_t i (0); i < n;)
+ {
+ unsigned char v (buf[i++]);
+
+ // See if we are in a compression sequence.
+ //
+ if (cseq != 0)
+ {
+ // See if this byte needs to be copied.
+ //
+ if (alt && cseq % 2 == 0)
+ cbuf[cn++] = v;
+
+ cseq--;
+ continue;
+ }
+
+ // If we are not in a compression sequence and this byte is
+ // not zero then simply copy it.
+ //
+ if (v != 0)
+ {
+ cbuf[cn++] = v;
+ continue;
+ }
+
+ // We have a zero.
+ //
+ cbuf[cn++] = 0;
+
+ // See if we can start a new compression sequence.
+ //
+ if (i < n)
+ {
+ if (buf[i] == 0)
+ {
+ // Sequential sequence. See how far it runs.
+ //
+ alt = false;
+
+ for (cseq = 1; cseq < 127 && cseq + i < n; cseq++)
+ if (buf[cseq + i] != 0)
+ break;
+ }
+ else if (i + 1 < n && buf[i + 1] == 0)
+ {
+ // Alternating sequence. See how far it runs.
+ //
+ alt = true;
+
+ for (cseq = 1; cseq < 127 && cseq * 2 + i + 1 < n; cseq++)
+ {
+ if (buf[cseq * 2 + i + 1] != 0)
+ break;
+
+ // For longer sequences prefer sequential to alternating.
+ //
+ if (cseq > 2 &&
+ buf[cseq * 2 + i] == 0 &&
+ buf[(cseq - 1) * 2 + i] == 0 &&
+ buf[(cseq - 2) * 2 + i] == 0)
+ {
+ cseq -= 2;
+ break;
+ }
+ }
+
+ cseq *= 2;
+ }
+ }
+
+ if (cseq != 0)
+ {
+ cbuf[cn++] = static_cast<unsigned char> (
+ alt ? (128 | cseq / 2) : cseq);
+ }
+ else
+ cbuf[cn++] = 0;
+ }
+
+ if (verbose)
+ cerr << "comressed data size " << cn << " bytes" << endl;
+
+ buf = cbuf;
+ n = cn;
+
+ // Figure out the file names.
+ //
+ string::size_type p (base.rfind ('/')), p1 (base.rfind ('\\'));
+
+ if (p1 != string::npos && (p == string::npos || p1 > p))
+ p = p1;
+
+ if (p != string::npos)
+ base = string (base, p + 1);
+
+ p = base.rfind ('.');
+
+ if (p != string::npos)
+ base.resize (p);
+
+ string hxx (base + hxx_suffix);
+ string cxx (base + cxx_suffix);
+
+ if (!outdir.empty ())
+ {
+#if defined (WIN32) || defined (__WIN32__)
+ hxx = outdir + '\\' + hxx;
+ cxx = outdir + '\\' + cxx;
+#else
+ hxx = outdir + '/' + hxx;
+ cxx = outdir + '/' + cxx;
+#endif
+ }
+
+ if (name.empty ())
+ {
+ name = base + "_schema";
+ cxx_escape (name);
+ }
+
+ // Write header.
+ //
+ {
+ ofstream os (hxx.c_str ());
+
+ if (!os.is_open ())
+ {
+ cerr << hxx << ": error: unable to open" << endl;
+ return 1;
+ }
+
+ os << "// Automatically generated. Do not edit." << endl
+ << "//" << endl
+ << endl
+ << "#include <xercesc/util/XercesDefs.hpp>" << endl
+ << endl
+ << "extern const XMLByte " << name << "[" << n << "UL];" << endl;
+ }
+
+ {
+ ofstream os (cxx.c_str ());
+
+ if (!os.is_open ())
+ {
+ cerr << cxx << ": error: unable to open" << endl;
+ return 1;
+ }
+
+ os << "// Automatically generated. Do not edit." << endl
+ << "//" << endl
+ << endl
+ << "#include <xercesc/util/XercesDefs.hpp>" << endl
+ << "#include <xercesc/util/XercesVersion.hpp>" << endl
+ << endl
+ << "#if XERCES_GRAMMAR_SERIALIZATION_LEVEL != " <<
+ XERCES_GRAMMAR_SERIALIZATION_LEVEL << endl
+ << "# error incompatible Xerces-C++ version detected" << endl
+ << "#endif" << endl
+ << endl
+ << "extern const XMLByte " << name << "[" << n << "UL] =" << endl
+ << "{";
+
+ for (size_t i (0); i < n; ++i)
+ {
+ if (i != 0)
+ os << ',';
+
+ os << (i % 12 == 0 ? "\n " : " ") << "0x";
+ os.width (2);
+ os.fill ('0');
+ os << hex << static_cast<unsigned short> (buf[i]);
+ }
+
+ os << endl
+ << "};" << endl
+ << endl;
+ }
+
+ delete[] cbuf;
+ }
+
+ XMLPlatformUtils::Terminate ();
+}
+
+void
+cxx_escape (string& s)
+{
+ for (string::size_type i (0); i < s.size (); ++i)
+ {
+ char& c (s[i]);
+
+ if (i == 0)
+ {
+ if (!((c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ c == '_'))
+ c = '_';
+ }
+ else
+ {
+ if (!((c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= '0' && c <= '9') ||
+ c == '_'))
+ c = '_';
+ }
+ }
+}
+
+void error_handler::
+warning (const SAXParseException& e)
+{
+ handle (e, s_warning);
+}
+
+void error_handler::
+error (const SAXParseException& e)
+{
+ failed_ = true;
+ handle (e, s_error);
+}
+
+void error_handler::
+fatalError (const SAXParseException& e)
+{
+ failed_ = true;
+ handle (e, s_fatal);
+}
+
+void error_handler::
+handle (const SAXParseException& e, severity s)
+{
+ const XMLCh* xid (e.getPublicId ());
+
+ if (xid == 0)
+ xid = e.getSystemId ();
+
+ char* id (XMLString::transcode (xid));
+ char* msg (XMLString::transcode (e.getMessage ()));
+
+ cerr << id << ":"
+ << e.getLineNumber () << ":" << e.getColumnNumber () << " "
+ << (s == s_warning ? "warning: " : "error: ") << msg << endl;
+
+ XMLString::release (&id);
+ XMLString::release (&msg);
+}
diff --git a/xsd-examples/cxx/tree/hello/.gitignore b/xsd-examples/cxx/tree/hello/.gitignore
new file mode 100644
index 0000000..d73130a
--- /dev/null
+++ b/xsd-examples/cxx/tree/hello/.gitignore
@@ -0,0 +1 @@
+hello.?xx
diff --git a/xsd-examples/cxx/tree/hello/README b/xsd-examples/cxx/tree/hello/README
new file mode 100644
index 0000000..bb98584
--- /dev/null
+++ b/xsd-examples/cxx/tree/hello/README
@@ -0,0 +1,26 @@
+This is a "Hello, world!" example that shows how to use the C++/Tree
+mapping to access XML instance documents described by XML Schema
+definitions.
+
+The example consists of the following files:
+
+hello.xsd
+ XML Schema which describes "hello" instance documents.
+
+hello.xml
+ Sample XML instance document.
+
+hello.hxx
+hello.cxx
+ C++ types that represent the given vocabulary and a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model. These are generated by XSD from hello.xsd.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input file. It then prints
+ the content of the object model to STDERR.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver hello.xml
diff --git a/xsd-examples/cxx/tree/hello/buildfile b/xsd-examples/cxx/tree/hello/buildfile
new file mode 100644
index 0000000..241d6f1
--- /dev/null
+++ b/xsd-examples/cxx/tree/hello/buildfile
@@ -0,0 +1,23 @@
+# file : cxx/tree/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} {hxx ixx cxx}{hello} $libs
+
+exe{driver}: xml{hello}: test.input = true
+
+<{hxx ixx cxx}{hello}>: xsd{hello} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
diff --git a/xsd-examples/cxx/tree/hello/driver.cxx b/xsd-examples/cxx/tree/hello/driver.cxx
new file mode 100644
index 0000000..7c8cec0
--- /dev/null
+++ b/xsd-examples/cxx/tree/hello/driver.cxx
@@ -0,0 +1,36 @@
+// file : cxx/tree/hello/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <iostream>
+
+#include "hello.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " hello.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ unique_ptr<hello_t> h (hello (argv[1]));
+
+ for (hello_t::name_const_iterator i (h->name ().begin ());
+ i != h->name ().end ();
+ ++i)
+ {
+ cout << h->greeting () << ", " << *i << "!" << endl;
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/tree/hello/hello.xml b/xsd-examples/cxx/tree/hello/hello.xml
new file mode 100644
index 0000000..b534d21
--- /dev/null
+++ b/xsd-examples/cxx/tree/hello/hello.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/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/tree/hello/hello.xsd b/xsd-examples/cxx/tree/hello/hello.xsd
new file mode 100644
index 0000000..a945ecf
--- /dev/null
+++ b/xsd-examples/cxx/tree/hello/hello.xsd
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/hello/hello.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="hello_t">
+
+ <xsd:annotation>
+ <xsd:documentation>
+ The hello_t type consists of a greeting phrase and a
+ collection of names to which this greeting applies.
+ </xsd:documentation>
+ </xsd:annotation>
+
+ <xsd:sequence>
+
+ <xsd:element name="greeting" type="xsd:string">
+ <xsd:annotation>
+ <xsd:documentation>
+ The greeting element contains the greeting phrase
+ for this hello object.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+
+ <xsd:element name="name" type="xsd:string" maxOccurs="unbounded">
+ <xsd:annotation>
+ <xsd:documentation>
+ The name elements contains names to be greeted.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="hello" type="hello_t">
+ <xsd:annotation>
+ <xsd:documentation>
+ The hello element is a root of the Hello XML vocabulary.
+ Every conforming document should start with this element.
+ </xsd:documentation>
+ </xsd:annotation>
+ </xsd:element>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/tree/library/.gitignore b/xsd-examples/cxx/tree/library/.gitignore
new file mode 100644
index 0000000..c116ec1
--- /dev/null
+++ b/xsd-examples/cxx/tree/library/.gitignore
@@ -0,0 +1 @@
+library.?xx
diff --git a/xsd-examples/cxx/tree/library/README b/xsd-examples/cxx/tree/library/README
new file mode 100644
index 0000000..0b8638c
--- /dev/null
+++ b/xsd-examples/cxx/tree/library/README
@@ -0,0 +1,32 @@
+This example shows how to use the C++/Tree mapping to parse XML documents
+into a tree-like in-memory object model, modify this object model, and
+finally serialize it back to XML.
+
+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
+library.ixx
+library.cxx
+ C++ types that represent the given vocabulary, a set of parsing
+ functions that convert XML documents to a tree-like in-memory object
+ model, and a set of serialization functions that convert the object
+ model back to XML. These are generated by XSD from library.xsd.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input file. It then prints
+ the content of the object model to STDERR. Finally, the driver modifies
+ the object model and serializes it back to XML.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver library.xml
+
+This example also shows how to use the ID/IDREF cross-referencing
+mechanism and the xsd:enumeration to C++ enum mapping.
diff --git a/xsd-examples/cxx/tree/library/buildfile b/xsd-examples/cxx/tree/library/buildfile
new file mode 100644
index 0000000..4ab023b
--- /dev/null
+++ b/xsd-examples/cxx/tree/library/buildfile
@@ -0,0 +1,25 @@
+# file : cxx/tree/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} {hxx ixx cxx}{library} $libs
+
+exe{driver}: xml{library}: test.input = true
+
+<{hxx ixx cxx}{library}>: xsd{library} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-ostream \
+ --generate-serialization \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
diff --git a/xsd-examples/cxx/tree/library/driver.cxx b/xsd-examples/cxx/tree/library/driver.cxx
new file mode 100644
index 0000000..9086891
--- /dev/null
+++ b/xsd-examples/cxx/tree/library/driver.cxx
@@ -0,0 +1,130 @@
+// file : cxx/tree/library/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <iostream>
+
+#include "library.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;
+
+ // Read in the XML file and obtain its object model.
+ //
+ std::unique_ptr<catalog> c (catalog_ (argv[1]));
+
+
+ // Let's print what we've got.
+ //
+ for (catalog::book_const_iterator bi (c->book ().begin ());
+ bi != c->book ().end ();
+ ++bi)
+ {
+ cerr << endl
+ << "ID : " << bi->id () << endl
+ << "ISBN : " << bi->isbn () << endl
+ << "Title : " << bi->title () << endl
+ << "Genre : " << bi->genre () << endl;
+
+ for (book::author_const_iterator ai (bi->author ().begin ());
+ ai != bi->author ().end ();
+ ++ai)
+ {
+ cerr << "Author : " << ai->name () << endl;
+ cerr << " Born : " << ai->born () << endl;
+
+ if (ai->died ())
+ cerr << " Died : " << *ai->died () << endl;
+
+ if (ai->recommends ())
+ cerr << " Recommends : " << (*ai->recommends ())->title () << endl;
+ }
+
+ cerr << "Available : " << std::boolalpha << bi->available () << endl;
+ }
+
+
+ // Now we are going to modify the object model and serialize it
+ // back to XML.
+ //
+
+ catalog::book_sequence& books (c->book ());
+
+
+ // Get rid of all unavailable books.
+ //
+ for (catalog::book_iterator bi (books.begin ()); bi != books.end ();)
+ {
+ if (!bi->available ())
+ bi = books.erase (bi);
+ else
+ ++bi;
+ }
+
+
+ // Insert a new book.
+ //
+ book b (679776443, // ISBN
+ "Dead Souls", // Title
+ genre::philosophy, // Genre
+ "DS"); // ID
+
+ b.author ().push_back (author ("Nikolai Gogol",
+ xml_schema::date (1809, 3, 31)));
+
+ books.insert (books.begin (), b);
+
+
+ // Because we removed all unavailable books, some IDREFs might be
+ // broken. Let's fix this.
+ //
+ for (catalog::book_iterator bi (books.begin ()); bi != books.end (); ++bi)
+ {
+ for (book::author_iterator ai (bi->author ().begin ());
+ ai != bi->author ().end ();
+ ++ai)
+ {
+ author::recommends_optional& c (ai->recommends ());
+
+ if (c.present ())
+ {
+ author::recommends_type& ref (c.get ());
+
+ if (!ref)
+ c.reset ();
+ }
+ }
+ }
+
+
+ // Prepare namespace mapping and schema location information.
+ //
+ xml_schema::namespace_infomap map;
+
+ map["lib"].name = "http://www.codesynthesis.com/library";
+ map["lib"].schema = "library.xsd";
+
+
+ // Write it out.
+ //
+ catalog_ (std::cout, *c, map);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/tree/library/library.xml b/xsd-examples/cxx/tree/library/library.xml
new file mode 100644
index 0000000..d048aa4
--- /dev/null
+++ b/xsd-examples/cxx/tree/library/library.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/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">
+ <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/tree/library/library.xsd b/xsd-examples/cxx/tree/library/library.xsd
new file mode 100644
index 0000000..4db07ef
--- /dev/null
+++ b/xsd-examples/cxx/tree/library/library.xsd
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/library/library.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension"
+ 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:language"/>
+ </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:date"/>
+ <xsd:element name="died" type="xsd:date" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="author">
+ <xsd:complexContent>
+ <xsd:extension base="lib:person">
+ <xsd:attribute name="recommends" type="xsd:IDREF" xse:refType="lib: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" default="true"/>
+ <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/tree/messaging/.gitignore b/xsd-examples/cxx/tree/messaging/.gitignore
new file mode 100644
index 0000000..f493b6c
--- /dev/null
+++ b/xsd-examples/cxx/tree/messaging/.gitignore
@@ -0,0 +1 @@
+protocol.?xx
diff --git a/xsd-examples/cxx/tree/messaging/README b/xsd-examples/cxx/tree/messaging/README
new file mode 100644
index 0000000..435a4cf
--- /dev/null
+++ b/xsd-examples/cxx/tree/messaging/README
@@ -0,0 +1,58 @@
+This example shows how to handle XML vocabularies with multiple
+root elements using the element type and element map features
+of the C++/Tree mapping. The main purpose of element types is
+to distinguish object models with the same root type but with
+different root elements. The element map allows uniform parsing
+and serialization of multiple root elements.
+
+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. Note that some request
+ and response elements are of the same type.
+
+balance.xml
+withdraw.xml
+deposit.xml
+ Sample XML instances for the protocol requests.
+
+protocol.hxx
+protocol.cxx
+ C++ types that represent the given vocabulary. These are
+ generated by the XSD compiler from protocol.xsd. Generation of
+ element types instead of parsing and serialization functions is
+ requested with the --generate-element-type option. Generation of
+ the element map is requested with the --generate-element-map
+ option.
+
+dom-parse.hxx
+dom-parse.cxx
+ Definition and implementation of the parse() function that
+ parses an XML document to a DOM document.
+
+dom-serialize.hxx
+dom-serialize.cxx
+ Definition and implementation of the serialize() function that
+ serializes a DOM document to XML.
+
+driver.cxx
+ Driver for the example. It first calls the above-mentioned parse()
+ function to parse the input file to a DOM document. It then calls
+ the parse() function on the element map to parse the root document
+ element to the object model. The object model is returned as a
+ pointer to xml_schema::element_type which is a common base type for
+ all element types. The driver then determines which request it has
+ received either using RTTI or by comparing the root element names.
+ Once the request type is determined, information about it is printed
+ to STDERR and the corresponding response is created. Finally, the
+ driver serializes the opaque response object to a DOM document
+ using the element map and then serializes this DOM document to
+ STDOUT using the above-mentioned serialize() function.
+
+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/tree/messaging/balance.xml b/xsd-examples/cxx/tree/messaging/balance.xml
new file mode 100644
index 0000000..27c1509
--- /dev/null
+++ b/xsd-examples/cxx/tree/messaging/balance.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/messaging/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/tree/messaging/buildfile b/xsd-examples/cxx/tree/messaging/buildfile
new file mode 100644
index 0000000..62fadda
--- /dev/null
+++ b/xsd-examples/cxx/tree/messaging/buildfile
@@ -0,0 +1,29 @@
+# file : cxx/tree/messaging/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} xml{balance deposit withdraw} doc{README}
+
+exe{driver}: {hxx cxx}{* -protocol} {hxx ixx cxx}{protocol} $libs testscript
+
+<{hxx ixx cxx}{protocol}>: xsd{protocol} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --root-element-all \
+ --generate-element-type \
+ --generate-element-map \
+ --generate-serialization \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/messaging/deposit.xml b/xsd-examples/cxx/tree/messaging/deposit.xml
new file mode 100644
index 0000000..5be2a0a
--- /dev/null
+++ b/xsd-examples/cxx/tree/messaging/deposit.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/messaging/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/tree/messaging/dom-parse.cxx b/xsd-examples/cxx/tree/messaging/dom-parse.cxx
new file mode 100644
index 0000000..3ae5787
--- /dev/null
+++ b/xsd-examples/cxx/tree/messaging/dom-parse.cxx
@@ -0,0 +1,93 @@
+// file : cxx/tree/messaging/dom-parse.cxx
+// copyright : not copyrighted - public domain
+
+#include "dom-parse.hxx"
+
+#include <istream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_*
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+using namespace xercesc;
+namespace xml = xsd::cxx::xml;
+namespace tree = xsd::cxx::tree;
+
+xml::dom::unique_ptr<DOMDocument>
+parse (std::istream& is, const std::string& id, bool validate)
+{
+ const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+ xml::dom::unique_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable/Disable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, validate);
+ conf->setParameter (XMLUni::fgXercesSchema, validate);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support.
+ //
+#if _XERCES_VERSION >= 30100
+ conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+#endif
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ // Set error handler.
+ //
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+ // Prepare input stream.
+ //
+ xml::sax::std_input_source isrc (is, id);
+ Wrapper4InputSource wrap (&isrc, false);
+
+ xml::dom::unique_ptr<DOMDocument> doc (parser->parse (&wrap));
+
+ eh.throw_if_failed<tree::parsing<char> > ();
+
+ return doc;
+}
diff --git a/xsd-examples/cxx/tree/messaging/dom-parse.hxx b/xsd-examples/cxx/tree/messaging/dom-parse.hxx
new file mode 100644
index 0000000..b73c52d
--- /dev/null
+++ b/xsd-examples/cxx/tree/messaging/dom-parse.hxx
@@ -0,0 +1,22 @@
+// file : cxx/tree/messaging/dom-parse.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef DOM_PARSE
+#define DOM_PARSE
+
+#include <string>
+#include <iosfwd>
+
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+
+// Parse an XML document from the standard input stream with an
+// optional resource id. Resource id is used in diagnostics as
+// well as to locate schemas referenced from inside the document.
+//
+xsd::cxx::xml::dom::unique_ptr<xercesc::DOMDocument>
+parse (std::istream& is,
+ const std::string& id,
+ bool validate);
+
+#endif // DOM_PARSE
diff --git a/xsd-examples/cxx/tree/messaging/dom-serialize.cxx b/xsd-examples/cxx/tree/messaging/dom-serialize.cxx
new file mode 100644
index 0000000..b32c5a2
--- /dev/null
+++ b/xsd-examples/cxx/tree/messaging/dom-serialize.cxx
@@ -0,0 +1,64 @@
+// file : cxx/tree/messaging/dom-serialize.cxx
+// copyright : not copyrighted - public domain
+
+#include "dom-serialize.hxx"
+
+#include <ostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp>
+
+#include <xsd/cxx/xml/string.hxx>
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+#include <xsd/cxx/xml/dom/serialization-source.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+using namespace xercesc;
+namespace xml = xsd::cxx::xml;
+namespace tree = xsd::cxx::tree;
+
+void
+serialize (std::ostream& os,
+ const xercesc::DOMDocument& doc,
+ const std::string& encoding)
+{
+ const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+
+ xml::dom::ostream_format_target oft (os);
+
+ // Create a DOMSerializer.
+ //
+ xml::dom::unique_ptr<DOMLSSerializer> writer (
+ impl->createLSSerializer ());
+
+ DOMConfiguration* conf (writer->getDomConfig ());
+
+ // Set error handler.
+ //
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+ // Set some generally nice features.
+ //
+ conf->setParameter (XMLUni::fgDOMWRTDiscardDefaultContent, true);
+ conf->setParameter (XMLUni::fgDOMWRTFormatPrettyPrint, true);
+ conf->setParameter (XMLUni::fgDOMWRTXercesPrettyPrint, false);
+
+ xml::dom::unique_ptr<DOMLSOutput> out (impl->createLSOutput ());
+ out->setEncoding (xml::string (encoding).c_str ());
+ out->setByteStream (&oft);
+
+ writer->write (&doc, out.get ());
+
+ eh.throw_if_failed<tree::serialization<char> > ();
+}
diff --git a/xsd-examples/cxx/tree/messaging/dom-serialize.hxx b/xsd-examples/cxx/tree/messaging/dom-serialize.hxx
new file mode 100644
index 0000000..bf1e290
--- /dev/null
+++ b/xsd-examples/cxx/tree/messaging/dom-serialize.hxx
@@ -0,0 +1,20 @@
+// file : cxx/tree/messaging/dom-serialize.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef DOM_SERIALIZE
+#define DOM_SERIALIZE
+
+#include <string>
+#include <iosfwd>
+
+#include <xercesc/dom/DOMDocument.hpp>
+
+// Serialize a DOM document to XML which is written to the standard
+// output stream.
+//
+void
+serialize (std::ostream& os,
+ const xercesc::DOMDocument& doc,
+ const std::string& encoding = "UTF-8");
+
+#endif // DOM_SERIALIZE
diff --git a/xsd-examples/cxx/tree/messaging/driver.cxx b/xsd-examples/cxx/tree/messaging/driver.cxx
new file mode 100644
index 0000000..a358014
--- /dev/null
+++ b/xsd-examples/cxx/tree/messaging/driver.cxx
@@ -0,0 +1,146 @@
+// file : cxx/tree/messaging/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <string>
+#include <fstream>
+#include <typeinfo>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include <xsd/cxx/xml/string.hxx>
+
+#include "dom-parse.hxx"
+#include "dom-serialize.hxx"
+
+#include "protocol.hxx"
+
+using namespace std;
+using namespace protocol;
+using namespace xercesc;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " request.xml" << endl;
+ return 1;
+ }
+
+ int r (0);
+
+ // We need to initialize the Xerces-C++ runtime because we
+ // are doing the XML-to-DOM parsing ourselves.
+ //
+ XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ ifstream ifs;
+ ifs.exceptions (ifstream::badbit | ifstream::failbit);
+ ifs.open (argv[1]);
+
+ unique_ptr<xml_schema::element_type> req, res;
+
+ // Parse the XML request to a DOM document using the parse()
+ // function from dom-parse.hxx.
+ //
+ {
+ xml_schema::dom::unique_ptr<DOMDocument> doc (
+ parse (ifs, argv[1], true));
+
+ DOMElement& root (*doc->getDocumentElement ());
+
+ req = xml_schema::element_map::parse (root);
+ }
+
+ // We can test which request we've got either using RTTI or by
+ // comparing the element names, as shown below.
+ //
+ if (balance* b = dynamic_cast<balance*> (req.get ()))
+ {
+ account_t& a (b->value ());
+
+ cerr << "balance request for acc# " << a.account () << endl;
+
+ res.reset (new success (balance_t (a.account (), 1000)));
+ }
+ else if (req->_name () == withdraw::name ())
+ {
+ withdraw& w (static_cast<withdraw&> (*req));
+ change_t& c (w.value ());
+
+ wcerr << "withdrawal request for acc# " << c.account () << ", "
+ << "amount: " << c.amount () << endl;
+
+ if (c.amount () > 1000)
+ res.reset (new insufficient_funds (balance_t (c.account (), 1000)));
+ else
+ res.reset (new success (balance_t (c.account (), 1000 - c.amount ())));
+
+ }
+ else if (req->_name () == deposit::name ())
+ {
+ deposit& d (static_cast<deposit&> (*req));
+ change_t& c (d.value ());
+
+ wcerr << "deposit request for acc# " << c.account () << ", "
+ << "amount: " << c.amount () << endl;
+
+ res.reset (new success (balance_t (c.account (), 1000 + c.amount ())));
+ }
+
+ // Serialize the response to a DOM document.
+ //
+ namespace xml = xsd::cxx::xml;
+
+ const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+ const string& name (res->_name ());
+ const string& ns (res->_namespace ());
+
+ xml_schema::dom::unique_ptr<DOMDocument> doc (
+ impl->createDocument (
+ xml::string (ns).c_str (),
+ xml::string ("p:" + name).c_str (),
+ 0));
+
+ xml_schema::element_map::serialize (*doc->getDocumentElement (), *res);
+
+ // Serialize the DOM document to XML using the serialize() function
+ // from dom-serialize.hxx.
+ //
+ cout << "response:" << endl
+ << endl;
+
+ serialize (cout, *doc);
+ }
+ catch (const xml_schema::no_element_info& e)
+ {
+ // This exception indicates that we tried to parse or serialize
+ // an unknown element.
+ //
+ cerr << "unknown request: " << e.element_namespace () << "#" <<
+ e.element_name () << endl;
+ r = 1;
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ r = 1;
+ }
+
+ XMLPlatformUtils::Terminate ();
+ return r;
+}
diff --git a/xsd-examples/cxx/tree/messaging/protocol.xsd b/xsd-examples/cxx/tree/messaging/protocol.xsd
new file mode 100644
index 0000000..4a28ac3
--- /dev/null
+++ b/xsd-examples/cxx/tree/messaging/protocol.xsd
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/messaging/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">
+
+ <!-- types -->
+
+ <xsd:complexType name="account_t">
+ <xsd:sequence>
+ <xsd:element name="account" type="xsd:unsignedInt"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="change_t">
+ <xsd:complexContent>
+ <xsd:extension base="p:account_t">
+ <xsd:sequence>
+ <xsd:element name="amount" type="xsd:unsignedInt"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="balance_t">
+ <xsd:complexContent>
+ <xsd:extension base="p:account_t">
+ <xsd:sequence>
+ <xsd:element name="balance" type="xsd:unsignedInt"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <!-- request elements -->
+
+ <xsd:element name="balance" type="p:account_t"/>
+ <xsd:element name="withdraw" type="p:change_t"/>
+ <xsd:element name="deposit" type="p:change_t"/>
+
+ <!-- response elements -->
+
+ <xsd:element name="success" type="p:balance_t"/>
+ <xsd:element name="insufficient-funds" type="p:balance_t"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/tree/messaging/testscript b/xsd-examples/cxx/tree/messaging/testscript
new file mode 100644
index 0000000..c9df49f
--- /dev/null
+++ b/xsd-examples/cxx/tree/messaging/testscript
@@ -0,0 +1,6 @@
+# file : cxx/tree/messaging/testscript
+# license : not copyrighted - public domain
+
+$* $src_base/balance.xml >| 2>| : balance
+$* $src_base/withdraw.xml >| 2>| : withdraw
+$* $src_base/deposit.xml >| 2>| : deposit
diff --git a/xsd-examples/cxx/tree/messaging/withdraw.xml b/xsd-examples/cxx/tree/messaging/withdraw.xml
new file mode 100644
index 0000000..e9ef526
--- /dev/null
+++ b/xsd-examples/cxx/tree/messaging/withdraw.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/messaging/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/tree/mixed/.gitignore b/xsd-examples/cxx/tree/mixed/.gitignore
new file mode 100644
index 0000000..cbeac00
--- /dev/null
+++ b/xsd-examples/cxx/tree/mixed/.gitignore
@@ -0,0 +1 @@
+text.?xx
diff --git a/xsd-examples/cxx/tree/mixed/README b/xsd-examples/cxx/tree/mixed/README
new file mode 100644
index 0000000..fc23faa
--- /dev/null
+++ b/xsd-examples/cxx/tree/mixed/README
@@ -0,0 +1,45 @@
+This example shows how to access the underlying DOM nodes in the
+C++/Tree mapping in order to handle raw, "type-less content" such
+as mixed content models, anyType/anySimpleType, and any/anyAttribute.
+
+For an alternative (and recommended) approach that employs ordered
+types see the order/mixed example.
+
+For an alternative approach that employes type customization see
+examples in the custom/ directory, in particular, custom/mixed and
+custom/wildcard.
+
+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.
+
+text.hxx
+text.cxx
+ C++ types that represent the given vocabulary and a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model. These are generated by XSD from text.xsd.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input file. It then uses
+ both the underlying DOM and statically-typed mapping to perform the
+ transformation.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver text.xml
diff --git a/xsd-examples/cxx/tree/mixed/buildfile b/xsd-examples/cxx/tree/mixed/buildfile
new file mode 100644
index 0000000..4c1be8e
--- /dev/null
+++ b/xsd-examples/cxx/tree/mixed/buildfile
@@ -0,0 +1,27 @@
+# file : cxx/tree/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} {hxx ixx cxx}{text} $libs
+
+exe{driver}: xml{text}: test.input = true
+
+<{hxx ixx cxx}{text}>: xsd{text} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/mixed/driver.cxx b/xsd-examples/cxx/tree/mixed/driver.cxx
new file mode 100644
index 0000000..cf64e7f
--- /dev/null
+++ b/xsd-examples/cxx/tree/mixed/driver.cxx
@@ -0,0 +1,122 @@
+// file : cxx/tree/mixed/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+
+#include "text.hxx"
+
+// The following transcode() utility function is handy when working with
+// Xerces. Include it after the generated header in order to get only char
+// or wchar_t version depending on how you compiled your schemas.
+//
+#include <xsd/cxx/xml/string.hxx>
+
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::unique_ptr;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " text.xml" << endl;
+ return 1;
+ }
+
+ using namespace xercesc;
+
+ int r (0);
+
+ // The Xerces-C++ DOM objects that will be associated with the
+ // document tree "out-live" the call to the parsing function.
+ // Therefore we need to initialize the Xerces-C++ runtime
+ // ourselves.
+ //
+ XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ unique_ptr<text> t (
+ text_ (argv[1],
+ xml_schema::flags::keep_dom |
+ xml_schema::flags::dont_initialize));
+
+ // The DOM association can be recreated in a copy (the underlying
+ // DOM document is cloned) if explicitly requested with the keep_dom
+ // flag and only if this copy is "complete", i.e., made from the root
+ // of the tree.
+ //
+ text copy (*t, xml_schema::flags::keep_dom);
+
+ // Print text.
+ //
+ {
+ namespace xml = xsd::cxx::xml;
+
+ unsigned long ref (0);
+ DOMNode* root (copy._node ());
+
+ for (DOMNode* n (root->getFirstChild ());
+ n != 0;
+ n = n->getNextSibling ())
+ {
+ switch (n->getNodeType ())
+ {
+ case DOMNode::TEXT_NODE:
+ {
+ cout << xml::transcode<char> (n->getTextContent ());
+ break;
+ }
+ case DOMNode::ELEMENT_NODE:
+ {
+ // Let's get back to a tree node from this DOM node.
+ //
+ xml_schema::type& t (
+ *reinterpret_cast<xml_schema::type*> (
+ n->getUserData (xml_schema::dom::tree_node_key)));
+
+ anchor& a (dynamic_cast<anchor&> (t));
+
+ cout << a << "[" << ref << "]";
+
+ // Or we could continue using DOM interface:
+ //
+ //cout << xml::transcode<char> (n->getTextContent ())
+ // << "[" << ref << "]";
+
+ ++ref;
+ break;
+ }
+ default:
+ break; // Ignore all other nodes (e.g., comments, etc).
+ }
+ }
+ }
+
+ // Print references.
+ //
+ {
+ unsigned long r (0);
+
+ for (text::a_const_iterator i (copy.a ().begin ());
+ i != copy.a ().end ();
+ ++i, ++r)
+ {
+ cout << "[" << r << "] " << i->href () << endl;
+ }
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+
+ XMLPlatformUtils::Terminate ();
+ return r;
+}
diff --git a/xsd-examples/cxx/tree/mixed/text.xml b/xsd-examples/cxx/tree/mixed/text.xml
new file mode 100644
index 0000000..dfe730e
--- /dev/null
+++ b/xsd-examples/cxx/tree/mixed/text.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/mixed/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/tree/mixed/text.xsd b/xsd-examples/cxx/tree/mixed/text.xsd
new file mode 100644
index 0000000..f3c023d
--- /dev/null
+++ b/xsd-examples/cxx/tree/mixed/text.xsd
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/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:anyURI" 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/tree/multiroot/.gitignore b/xsd-examples/cxx/tree/multiroot/.gitignore
new file mode 100644
index 0000000..f493b6c
--- /dev/null
+++ b/xsd-examples/cxx/tree/multiroot/.gitignore
@@ -0,0 +1 @@
+protocol.?xx
diff --git a/xsd-examples/cxx/tree/multiroot/README b/xsd-examples/cxx/tree/multiroot/README
new file mode 100644
index 0000000..b742422
--- /dev/null
+++ b/xsd-examples/cxx/tree/multiroot/README
@@ -0,0 +1,45 @@
+This example shows how to handle XML vocabularies with multiple
+root elements using the C++/Tree mapping.
+
+See also the messaging example for an alternative approach that
+uses the element type and element map features of the C++/Tree
+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
+protocol.cxx
+ C++ types that represent the given vocabulary and a set of
+ parsing functions that convert XML documents to a tree-like
+ in-memory object model. These are generated by XSD from
+ protocol.xsd.
+
+dom-parse.hxx
+dom-parse.cxx
+ Definition and implementation of the parse() function that
+ parses an XML document to a DOM document.
+
+driver.cxx
+ Driver for the example. It first calls the above parse() function
+ to parse the input file to a DOM document. It then determines the
+ type of request being handled and calls the corresponding parsing
+ function that constructs the object model from this DOM document.
+ Finally, it prints the content of this object model to STDERR.
+ This example intentionally does not support the deposit request
+ to show how to handle unknown documents.
+
+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/tree/multiroot/balance.xml b/xsd-examples/cxx/tree/multiroot/balance.xml
new file mode 100644
index 0000000..5f4a441
--- /dev/null
+++ b/xsd-examples/cxx/tree/multiroot/balance.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/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/tree/multiroot/buildfile b/xsd-examples/cxx/tree/multiroot/buildfile
new file mode 100644
index 0000000..dc10588
--- /dev/null
+++ b/xsd-examples/cxx/tree/multiroot/buildfile
@@ -0,0 +1,26 @@
+# file : cxx/tree/multiroot/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} xml{balance deposit withdraw} doc{README}
+
+exe{driver}: {hxx cxx}{* -protocol} {hxx ixx cxx}{protocol} $libs testscript
+
+<{hxx ixx cxx}{protocol}>: xsd{protocol} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --root-element-all \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/multiroot/deposit.xml b/xsd-examples/cxx/tree/multiroot/deposit.xml
new file mode 100644
index 0000000..9db2a2a
--- /dev/null
+++ b/xsd-examples/cxx/tree/multiroot/deposit.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/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/tree/multiroot/dom-parse.cxx b/xsd-examples/cxx/tree/multiroot/dom-parse.cxx
new file mode 100644
index 0000000..e67c187
--- /dev/null
+++ b/xsd-examples/cxx/tree/multiroot/dom-parse.cxx
@@ -0,0 +1,93 @@
+// file : cxx/tree/multiroot/dom-parse.cxx
+// copyright : not copyrighted - public domain
+
+#include "dom-parse.hxx"
+
+#include <istream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_*
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+using namespace xercesc;
+namespace xml = xsd::cxx::xml;
+namespace tree = xsd::cxx::tree;
+
+xml::dom::unique_ptr<DOMDocument>
+parse (std::istream& is, const std::string& id, bool validate)
+{
+ const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+ xml::dom::unique_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable/Disable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, validate);
+ conf->setParameter (XMLUni::fgXercesSchema, validate);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support.
+ //
+#if _XERCES_VERSION >= 30100
+ conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+#endif
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ // Set error handler.
+ //
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+ // Prepare input stream.
+ //
+ xml::sax::std_input_source isrc (is, id);
+ Wrapper4InputSource wrap (&isrc, false);
+
+ xml::dom::unique_ptr<DOMDocument> doc (parser->parse (&wrap));
+
+ eh.throw_if_failed<tree::parsing<char> > ();
+
+ return doc;
+}
diff --git a/xsd-examples/cxx/tree/multiroot/dom-parse.hxx b/xsd-examples/cxx/tree/multiroot/dom-parse.hxx
new file mode 100644
index 0000000..3699a77
--- /dev/null
+++ b/xsd-examples/cxx/tree/multiroot/dom-parse.hxx
@@ -0,0 +1,22 @@
+// file : cxx/tree/multiroot/dom-parse.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef DOM_PARSE
+#define DOM_PARSE
+
+#include <string>
+#include <iosfwd>
+
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+
+// Parse an XML document from the standard input stream with an
+// optional resource id. Resource id is used in diagnostics as
+// well as to locate schemas referenced from inside the document.
+//
+xsd::cxx::xml::dom::unique_ptr<xercesc::DOMDocument>
+parse (std::istream& is,
+ const std::string& id,
+ bool validate);
+
+#endif // DOM_PARSE
diff --git a/xsd-examples/cxx/tree/multiroot/driver.cxx b/xsd-examples/cxx/tree/multiroot/driver.cxx
new file mode 100644
index 0000000..d22c25e
--- /dev/null
+++ b/xsd-examples/cxx/tree/multiroot/driver.cxx
@@ -0,0 +1,124 @@
+// file : cxx/tree/multiroot/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <string>
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include "dom-parse.hxx"
+
+#include "protocol.hxx"
+
+using namespace std;
+using namespace protocol;
+
+// Parse an XML document and return a pointer to request_t which can
+// then be tested with dynamic_cast. If your vocabulary does not have
+// a common base type for all root element types then you can use
+// xml_schema::type which is a base for all generated types.
+//
+unique_ptr<request_t>
+parse (istream& is, const string& id)
+{
+ using namespace xercesc;
+ namespace xml = xsd::cxx::xml;
+
+ // Parse an XML instance to a DOM document using the parse()
+ // function from dom-parse.hxx.
+ //
+ xml_schema::dom::unique_ptr<DOMDocument> doc (parse (is, id, true));
+
+ DOMElement* root (doc->getDocumentElement ());
+
+ string ns (xml::transcode<char> (root->getNamespaceURI ()));
+ string name (xml::transcode<char> (root->getLocalName ()));
+
+ unique_ptr<request_t> r;
+
+ // We could have handled the result directly in this function
+ // instead of returning it as an opaque pointer and using
+ // dynamic_cast later to figure out which request we are dealing
+ // with.
+ //
+ if (ns == "http://www.codesynthesis.com/protocol")
+ {
+ if (name == "balance")
+ {
+ // Use the balance parsing function.
+ //
+ r.reset (balance (*doc).release ());
+ }
+ else if (name == "withdraw")
+ {
+ // Use the withdraw parsing function.
+ //
+ r.reset (withdraw (*doc).release ());
+ }
+ }
+
+ if (r.get () == 0)
+ cerr << "ignoring unknown request: " << ns << "#" << name << endl;
+
+ return r;
+}
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " request.xml" << endl;
+ return 1;
+ }
+
+ int r (0);
+
+ // We need to initialize the Xerces-C++ runtime because we
+ // are doing the XML-to-DOM parsing ourselves.
+ //
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ ifstream ifs;
+ ifs.exceptions (ifstream::badbit | ifstream::failbit);
+ ifs.open (argv[1]);
+
+ unique_ptr<request_t> r (parse (ifs, argv[1]));
+
+ // Let's print what we've got.
+ //
+ if (balance_t* b = dynamic_cast<balance_t*> (r.get ()))
+ {
+ cerr << "balance request for acc# " << b->account () << endl;
+ }
+ else if (withdraw_t* w = dynamic_cast<withdraw_t*> (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;
+ r = 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ r = 1;
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+ return r;
+}
diff --git a/xsd-examples/cxx/tree/multiroot/protocol.xsd b/xsd-examples/cxx/tree/multiroot/protocol.xsd
new file mode 100644
index 0000000..2fe9456
--- /dev/null
+++ b/xsd-examples/cxx/tree/multiroot/protocol.xsd
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/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_t">
+ <xsd:sequence>
+ <xsd:element name="account" type="xsd:unsignedInt"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="balance_t">
+ <xsd:complexContent>
+ <xsd:extension base="p:request_t"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="withdraw_t">
+ <xsd:complexContent>
+ <xsd:extension base="p:request_t">
+ <xsd:sequence>
+ <xsd:element name="amount" type="xsd:unsignedInt"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="deposit_t">
+ <xsd:complexContent>
+ <xsd:extension base="p:request_t">
+ <xsd:sequence>
+ <xsd:element name="amount" type="xsd:unsignedInt"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:element name="balance" type="p:balance_t"/>
+ <xsd:element name="withdraw" type="p:withdraw_t"/>
+ <xsd:element name="deposit" type="p:deposit_t"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/tree/multiroot/testscript b/xsd-examples/cxx/tree/multiroot/testscript
new file mode 100644
index 0000000..383bed4
--- /dev/null
+++ b/xsd-examples/cxx/tree/multiroot/testscript
@@ -0,0 +1,6 @@
+# file : cxx/tree/multiroot/testscript
+# license : not copyrighted - public domain
+
+$* $src_base/balance.xml 2>| : balance
+$* $src_base/withdraw.xml 2>| : withdraw
+$* $src_base/deposit.xml 2>| : deposit
diff --git a/xsd-examples/cxx/tree/multiroot/withdraw.xml b/xsd-examples/cxx/tree/multiroot/withdraw.xml
new file mode 100644
index 0000000..f98ad16
--- /dev/null
+++ b/xsd-examples/cxx/tree/multiroot/withdraw.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/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/tree/order/README b/xsd-examples/cxx/tree/order/README
new file mode 100644
index 0000000..7125a2d
--- /dev/null
+++ b/xsd-examples/cxx/tree/order/README
@@ -0,0 +1,11 @@
+This directory contains a number of examples that show how to use ordered
+types to capture and maintain content order. The following list gives an
+overview of each example:
+
+element
+ Shows how to use ordered types to capture and maintain element order,
+ including element wildcards.
+
+mixed
+ Shows how to use ordered types to capture mixed content text and to
+ maintain order information between elements and text.
diff --git a/xsd-examples/cxx/tree/order/element/.gitignore b/xsd-examples/cxx/tree/order/element/.gitignore
new file mode 100644
index 0000000..2fff792
--- /dev/null
+++ b/xsd-examples/cxx/tree/order/element/.gitignore
@@ -0,0 +1 @@
+transactions.?xx
diff --git a/xsd-examples/cxx/tree/order/element/README b/xsd-examples/cxx/tree/order/element/README
new file mode 100644
index 0000000..19f2381
--- /dev/null
+++ b/xsd-examples/cxx/tree/order/element/README
@@ -0,0 +1,35 @@
+This example shows how to use ordered types to capture and maintain
+element order, including element wildcards.
+
+The example consists of the following files:
+
+transactions.xsd
+ XML Schema which describes various bank transactions. A batch of
+ transactions can contain any number of different transactions in
+ any order but the order of transaction in the batch is significant.
+
+library.xml
+ Sample XML instance document.
+
+transactions.hxx
+transactions.cxx
+ C++ types that represent the given vocabulary as well as a set of
+ parsing and serialization functions. These are generated by XSD
+ from transactions.xsd. Note that the --ordered-type option is
+ used to indicate to the XSD compiler that the batch type is
+ ordered. We also use the --generate-wildcard option to enable
+ wildcard support. An element wildcard is used in the batch to
+ allow transaction extensions.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input XML file. It then
+ iterates over transactions in the batch using the content order
+ sequence. The driver then performs various modifications of the
+ object model while showing how to maintain the content order.
+ Finally, it saves the modified transaction batch back to XML to
+ verify that the content order is preserved in the output document.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver transactions.xml
diff --git a/xsd-examples/cxx/tree/order/element/buildfile b/xsd-examples/cxx/tree/order/element/buildfile
new file mode 100644
index 0000000..eb3834e
--- /dev/null
+++ b/xsd-examples/cxx/tree/order/element/buildfile
@@ -0,0 +1,30 @@
+# file : cxx/tree/order/element/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}{* -transactions} {hxx ixx cxx}{transactions} $libs
+
+exe{driver}: xml{transactions}: test.input = true
+
+<{hxx ixx cxx}{transactions}>: xsd{transactions} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-serialization \
+ --generate-wildcard \
+ --ordered-type batch \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/order/element/driver.cxx b/xsd-examples/cxx/tree/order/element/driver.cxx
new file mode 100644
index 0000000..2f62700
--- /dev/null
+++ b/xsd-examples/cxx/tree/order/element/driver.cxx
@@ -0,0 +1,147 @@
+// file : cxx/tree/order/element/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <cassert>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include "transactions.hxx"
+
+// The following string class keeps us sane when working with Xerces.
+// Include it after the generated header in order to get only char or
+// wchar_t version depending on how you compiled your schemas.
+//
+#include <xsd/cxx/xml/string.hxx>
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " transactions.xml" << endl;
+ return 1;
+ }
+
+ using namespace xercesc;
+
+ int r (0);
+
+ // The Xerces-C++ DOM objects that will be used to store the
+ // content matched by the wildcard "out-lives" the call to the
+ // parsing function. Therefore we need to initialize the
+ // Xerces-C++ runtime ourselves.
+ //
+ XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ using namespace transactions;
+
+ // Parse the batch.
+ //
+ std::unique_ptr<batch> b (
+ batch_ (argv[1], xml_schema::flags::dont_initialize));
+
+ // Print what we've got in content order.
+ //
+ for (batch::content_order_const_iterator i (b->content_order ().begin ());
+ i != b->content_order ().end ();
+ ++i)
+ {
+ switch (i->id)
+ {
+ case batch::balance_id:
+ {
+ const balance& t (b->balance ()[i->index]);
+ cerr << t.account () << " balance" << endl;
+ break;
+ }
+ case batch::withdraw_id:
+ {
+ const withdraw& t (b->withdraw ()[i->index]);
+ cerr << t.account () << " withdraw " << t.amount () << endl;
+ break;
+ }
+ case batch::deposit_id:
+ {
+ const deposit& t (b->deposit ()[i->index]);
+ cerr << t.account () << " deposit " << t.amount () << endl;
+ break;
+ }
+ case batch::any_id:
+ {
+ namespace xml = xsd::cxx::xml;
+
+ const DOMElement& e (b->any ()[i->index]);
+ cerr << xml::transcode<char> (e.getLocalName ()) << endl;
+ break;
+ }
+ default:
+ {
+ assert (false); // Unknown content id.
+ }
+ }
+ }
+
+ cerr << endl;
+
+ // Modify the transaction batch. First remove the last transaction.
+ // Note that we have to update both the content itself and content
+ // order sequences.
+ //
+ batch::content_order_sequence& co (b->content_order ());
+
+ co.pop_back ();
+ b->withdraw ().pop_back ();
+
+ // Now add a few more transactions. Again we have to add both the
+ // content and its ordering. The order information consists of the
+ // content id and, in case of a sequence, the index.
+ //
+ b->deposit ().push_back (deposit (123456789, 100000));
+ co.push_back (
+ batch::content_order_type (
+ batch::deposit_id, b->deposit ().size () - 1));
+
+ // The next transaction we add at the beginning of the batch.
+ //
+ b->balance ().push_back (balance (123456789));
+ co.insert (co.begin (),
+ batch::content_order_type (
+ batch::balance_id, b->balance ().size () - 1));
+
+ // Note also that when we merely modify the content of one
+ // of the elements in place, we don't need to update its
+ // order. For example:
+ //
+ b->deposit ()[0].amount (2000000);
+
+ // Serialize the modified transaction batch back to XML.
+ //
+ xml_schema::namespace_infomap map;
+
+ map[""].name = "http://www.codesynthesis.com/transactions";
+ map[""].schema = "transactions.xsd";
+ map["te"].name = "http://www.codesynthesis.com/transactions-extras";
+
+ batch_ (std::cout,
+ *b,
+ map,
+ "UTF-8",
+ xml_schema::flags::dont_initialize);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+
+ XMLPlatformUtils::Terminate ();
+ return r;
+}
diff --git a/xsd-examples/cxx/tree/order/element/transactions.xml b/xsd-examples/cxx/tree/order/element/transactions.xml
new file mode 100644
index 0000000..7af9ab1
--- /dev/null
+++ b/xsd-examples/cxx/tree/order/element/transactions.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/order/element/transactions.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<batch xmlns="http://www.codesynthesis.com/transactions"
+ xmlns:te="http://www.codesynthesis.com/transactions-extras"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/transactions transactions.xsd">
+ <deposit>
+ <account>123456789</account>
+ <amount>1000000</amount>
+ </deposit>
+
+ <balance>
+ <account>123456789</account>
+ </balance>
+
+ <te:block>
+ <account>123456789</account>
+ <amount>500000</amount>
+ </te:block>
+
+ <withdraw>
+ <account>123456789</account>
+ <amount>500000</amount>
+ </withdraw>
+</batch>
diff --git a/xsd-examples/cxx/tree/order/element/transactions.xsd b/xsd-examples/cxx/tree/order/element/transactions.xsd
new file mode 100644
index 0000000..7a63c9f
--- /dev/null
+++ b/xsd-examples/cxx/tree/order/element/transactions.xsd
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/order/element/transactions.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:t="http://www.codesynthesis.com/transactions"
+ targetNamespace="http://www.codesynthesis.com/transactions"
+ elementFormDefault="qualified">
+
+ <xsd:complexType name="transaction">
+ <xsd:sequence>
+ <xsd:element name="account" type="xsd:unsignedInt"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="balance">
+ <xsd:complexContent>
+ <xsd:extension base="t:transaction"/>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="withdraw">
+ <xsd:complexContent>
+ <xsd:extension base="t:transaction">
+ <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="t:transaction">
+ <xsd:sequence>
+ <xsd:element name="amount" type="xsd:unsignedInt"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="batch">
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element name="balance" type="t:balance"/>
+ <xsd:element name="withdraw" type="t:withdraw"/>
+ <xsd:element name="deposit" type="t:deposit"/>
+ <xsd:any namespace="##other" processContents="lax"/>
+ </xsd:choice>
+ </xsd:complexType>
+
+ <xsd:element name="batch" type="t:batch"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/tree/order/mixed/.gitignore b/xsd-examples/cxx/tree/order/mixed/.gitignore
new file mode 100644
index 0000000..cbeac00
--- /dev/null
+++ b/xsd-examples/cxx/tree/order/mixed/.gitignore
@@ -0,0 +1 @@
+text.?xx
diff --git a/xsd-examples/cxx/tree/order/mixed/README b/xsd-examples/cxx/tree/order/mixed/README
new file mode 100644
index 0000000..e66c1ad
--- /dev/null
+++ b/xsd-examples/cxx/tree/order/mixed/README
@@ -0,0 +1,45 @@
+This example shows how to use ordered types to capture mixed content
+text and to maintain order information between elements and text.
+
+In this example we use mixed content model to describe text with
+embedded links in the form:
+
+ This paragraph talks about <a href="uri">time</a>.
+
+The example transforms such text into plain text with references in
+the form:
+
+ This paragraph talks about time[uri].
+
+It also saves the modified text back to XML in order to verify the
+element and text order.
+
+The example consists of the following files:
+
+text.xsd
+ XML Schema which describes "text with links" instance documents.
+
+text.xml
+ Sample XML instance document.
+
+text.hxx
+text.cxx
+ C++ types that represent the given vocabulary as well as a set of
+ parsing and serialization functions. These are generated by XSD
+ from text.xsd. Note that the --ordered-type-mixed option is used
+ to indicate to the XSD compiler that all types with mixed content
+ should be automatically treated as ordered.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input XML file. It then
+ iterates over the text and elements in the content order to convert
+ the document to its plain text representation. The driver then adds
+ another paragraph of text and a link to the object model while showing
+ how to maintain the content order. Finally, it saves the modified
+ text back to XML to verify that the content order is preserved in
+ the output document.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver text.xml
diff --git a/xsd-examples/cxx/tree/order/mixed/buildfile b/xsd-examples/cxx/tree/order/mixed/buildfile
new file mode 100644
index 0000000..149bca0
--- /dev/null
+++ b/xsd-examples/cxx/tree/order/mixed/buildfile
@@ -0,0 +1,25 @@
+# file : cxx/tree/order/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} {hxx ixx cxx}{text} $libs
+
+exe{driver}: xml{text}: test.input = true
+
+<{hxx ixx cxx}{text}>: xsd{text} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-serialization \
+ --ordered-type-mixed \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
diff --git a/xsd-examples/cxx/tree/order/mixed/driver.cxx b/xsd-examples/cxx/tree/order/mixed/driver.cxx
new file mode 100644
index 0000000..a18f4ad
--- /dev/null
+++ b/xsd-examples/cxx/tree/order/mixed/driver.cxx
@@ -0,0 +1,89 @@
+// file : cxx/tree/order/mixed/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <cassert>
+#include <iostream>
+
+#include "text.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " text.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ std::unique_ptr<text> t (text_ (argv[1]));
+
+ // Print what we've got in content order.
+ //
+ for (text::content_order_const_iterator i (t->content_order ().begin ());
+ i != t->content_order ().end ();
+ ++i)
+ {
+ switch (i->id)
+ {
+ case text::a_id:
+ {
+ const anchor& a (t->a ()[i->index]);
+ cerr << a << "[" << a.href () << "]";
+ break;
+ }
+ case text::text_content_id:
+ {
+ const xml_schema::string& s (t->text_content ()[i->index]);
+ cerr << s;
+ break;
+ }
+ default:
+ {
+ assert (false); // Unknown content id.
+ }
+ }
+ }
+
+ cerr << endl;
+
+ // Modify the document. Note that we have to update both the content
+ // itself and content order sequences.
+ //
+ typedef text::content_order_type order_type;
+
+ text::content_order_sequence& co (t->content_order ());
+ text::text_content_sequence& tc (t->text_content ());
+
+ tc.push_back ("The last paragraph doesn't talk about ");
+ co.push_back (order_type (text::text_content_id, tc.size () - 1));
+
+ t->a ().push_back (anchor ("anything", "http://en.wikipedia.org"));
+ co.push_back (order_type (text::a_id, t->a ().size () - 1));
+
+ tc.push_back (" in particular.\n\n");
+ co.push_back (order_type (text::text_content_id, tc.size () - 1));
+
+ // Serialize the modified document back to XML.
+ //
+ xml_schema::namespace_infomap map;
+
+ map[""].schema = "text.xsd";
+
+ text_ (std::cout,
+ *t,
+ map,
+ "UTF-8",
+ xml_schema::flags::dont_pretty_print);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/tree/order/mixed/text.xml b/xsd-examples/cxx/tree/order/mixed/text.xml
new file mode 100644
index 0000000..3d7476d
--- /dev/null
+++ b/xsd-examples/cxx/tree/order/mixed/text.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/order/mixed/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/tree/order/mixed/text.xsd b/xsd-examples/cxx/tree/order/mixed/text.xsd
new file mode 100644
index 0000000..b55d214
--- /dev/null
+++ b/xsd-examples/cxx/tree/order/mixed/text.xsd
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/order/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:anyURI" 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/tree/performance/.gitignore b/xsd-examples/cxx/tree/performance/.gitignore
new file mode 100644
index 0000000..b143f97
--- /dev/null
+++ b/xsd-examples/cxx/tree/performance/.gitignore
@@ -0,0 +1,5 @@
+gen
+
+# Testscript output directory (can be symlink).
+#
+test-gen
diff --git a/xsd-examples/cxx/tree/performance/README b/xsd-examples/cxx/tree/performance/README
new file mode 100644
index 0000000..0206387
--- /dev/null
+++ b/xsd-examples/cxx/tree/performance/README
@@ -0,0 +1,62 @@
+This example measures the performance of parsing and serialization in
+the C++/Tree mapping. It also shows how to structure your code to
+achieve the maximum performance for these two operations.
+
+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.hxx
+test.ixx
+test.cxx
+ C++ types that represent the given vocabulary, a set of parsing
+ functions that convert XML documents to a tree-like in-memory object
+ model, and a set of serialization functions that convert the object
+ model back to XML. These are generated by the XSD compiler from
+ test.xsd.
+
+parsing.cxx
+ Parsing performance test. It first reads the entire document into
+ a memory buffer. It then creates a DOM parser and pre-parses and
+ caches the schema if validation is enabled. Finally, it runs the
+ performance measurement loop which on each iteration parses the
+ XML document from the in-memory buffer into DOM and then DOM to
+ the object model.
+
+serialization.cxx
+ Serialization performance test. It first parses the XML document
+ into the object model. It then creates a memory buffer into which
+ the document is serialized and a DOM serializer. Finally, it runs
+ the performance measurement loop which on each iteration serializes
+ the object model to DOM and DOM to XML.
+
+driver.cxx
+ Driver for the example. It first parses the command line arguments.
+ It then initializes the Xerces-C++ runtime and calls the parsing
+ and serialization tests described above.
+
+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 (off by default). The -i option can be used to specify the
+number of parsing and serialization 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/tree/performance/buildfile b/xsd-examples/cxx/tree/performance/buildfile
new file mode 100644
index 0000000..e9faeef
--- /dev/null
+++ b/xsd-examples/cxx/tree/performance/buildfile
@@ -0,0 +1,36 @@
+# file : cxx/tree/performance/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: doc{README}
+
+# exe{driver}
+#
+./: exe{driver}: {hxx cxx}{* -gen -test} {hxx ixx cxx}{test} $libs
+
+exe{driver}: xml{test-50k}: test.input = true
+
+<{hxx ixx cxx}{test}>: xsd{test} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-serialization \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+# exe{gen}
+#
+./: exe{gen}: cxx{gen} testscript{gen}
+
+# Build options.
+#
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/performance/driver.cxx b/xsd-examples/cxx/tree/performance/driver.cxx
new file mode 100644
index 0000000..b156f84
--- /dev/null
+++ b/xsd-examples/cxx/tree/performance/driver.cxx
@@ -0,0 +1,90 @@
+// file : cxx/tree/performance/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <string>
+#include <sstream>
+#include <iostream>
+
+#include <xercesc/util/PlatformUtils.hpp>
+
+using namespace std;
+
+// See parsing.cxx
+//
+bool
+parsing (const char* file, unsigned long iter, bool validate);
+
+// See serialization.cxx
+//
+bool
+serialization (const char* file, unsigned long iter);
+
+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)
+ {
+ std::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;
+ }
+
+ int r (0);
+
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ // Call parsing and serialization tests.
+ //
+ if (!parsing (file, iter, validate) || !serialization (file, iter))
+ r = 1;
+
+ xercesc::XMLPlatformUtils::Terminate ();
+
+ return r;
+}
diff --git a/xsd-examples/cxx/tree/performance/gen.cxx b/xsd-examples/cxx/tree/performance/gen.cxx
new file mode 100644
index 0000000..b6392c0
--- /dev/null
+++ b/xsd-examples/cxx/tree/performance/gen.cxx
@@ -0,0 +1,76 @@
+#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/tree/performance/gen.testscript b/xsd-examples/cxx/tree/performance/gen.testscript
new file mode 100644
index 0000000..deefc05
--- /dev/null
+++ b/xsd-examples/cxx/tree/performance/gen.testscript
@@ -0,0 +1,9 @@
+# file : cxx/tree/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/tree/performance/parsing.cxx b/xsd-examples/cxx/tree/performance/parsing.cxx
new file mode 100644
index 0000000..c41b57d
--- /dev/null
+++ b/xsd-examples/cxx/tree/performance/parsing.cxx
@@ -0,0 +1,172 @@
+// file : cxx/tree/performance/parsing.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <cstddef> // std::size_t
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/dom/DOMLSParser.hpp>
+#include <xercesc/dom/DOMImplementation.hpp>
+#include <xercesc/dom/DOMImplementationRegistry.hpp>
+
+#include <xercesc/validators/common/Grammar.hpp>
+
+#include <xercesc/framework/MemBufInputSource.hpp>
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xercesc/util/XMLUniDefs.hpp>
+
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+#include "time.hxx"
+#include "test.hxx"
+
+using namespace std;
+
+bool
+parsing (const char* file, unsigned long iter, bool validate)
+{
+ try
+ {
+ cerr << "parsing:" << endl;
+
+ 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;
+
+ // Create XML parser that we are going to use in all iterations.
+ //
+ using namespace xercesc;
+
+ const XMLCh ls_id[] =
+ {xercesc::chLatin_L, xercesc::chLatin_S, xercesc::chNull};
+
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+ // Use the error handler implementation provided by the XSD runtime.
+ //
+ xsd::cxx::tree::error_handler<char> eh;
+ xsd::cxx::xml::dom::bits::error_handler_proxy<char> ehp (eh);
+
+ xml_schema::dom::unique_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ conf->setParameter (XMLUni::fgDOMComments, false);
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Set error handler.
+ //
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+ if (validate)
+ {
+ conf->setParameter (XMLUni::fgDOMValidate, true);
+ conf->setParameter (XMLUni::fgXercesSchema, true);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support.
+ //
+#if _XERCES_VERSION >= 30100
+ conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+#endif
+
+ // If we are validating, pre-load and cache the schema.
+ //
+ 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,
+ xsd::cxx::tree::error_handler<char>::severity::fatal,
+ "unable to load schema");
+ }
+
+ eh.throw_if_failed<xml_schema::parsing> ();
+ conf->setParameter (XMLUni::fgXercesUseCachedGrammarInParse, true);
+ conf->setParameter (XMLUni::fgXercesLoadSchema, false);
+ }
+ else
+ {
+ conf->setParameter (XMLUni::fgDOMValidate, false);
+ conf->setParameter (XMLUni::fgXercesSchema, false);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ // Create memory buffer input source.
+ //
+ MemBufInputSource is (
+ reinterpret_cast<XMLByte*> (buf), size, file, false);
+ is.setCopyBufToStream (false);
+ Wrapper4InputSource wis (&is, false);
+
+ // Parsing loop.
+ //
+ os::time start;
+
+ for (unsigned long i (0); i < iter; ++i)
+ {
+ // First parse XML to DOM reusing the parser we created above.
+ //
+ xml_schema::dom::unique_ptr<DOMDocument> doc (parser->parse (&wis));
+ eh.throw_if_failed<xml_schema::parsing> ();
+
+ // Then parse DOM to the object model.
+ //
+ unique_ptr<test::root> r (test::root_ (*doc));
+ }
+
+ os::time end;
+ os::time time (end - start);
+
+ 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 false;
+ }
+ catch (std::ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return false;
+ }
+
+ return true;
+}
diff --git a/xsd-examples/cxx/tree/performance/serialization.cxx b/xsd-examples/cxx/tree/performance/serialization.cxx
new file mode 100644
index 0000000..e81fcbd
--- /dev/null
+++ b/xsd-examples/cxx/tree/performance/serialization.cxx
@@ -0,0 +1,132 @@
+// file : cxx/tree/performance/serialization.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <cstddef> // std::size_t
+#include <sstream>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/dom/DOMLSOutput.hpp>
+#include <xercesc/dom/DOMLSSerializer.hpp>
+#include <xercesc/dom/DOMImplementation.hpp>
+#include <xercesc/dom/DOMImplementationRegistry.hpp>
+
+#include <xercesc/framework/MemBufFormatTarget.hpp>
+
+#include <xercesc/util/XMLUniDefs.hpp>
+
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+#include "time.hxx"
+#include "test.hxx"
+
+using namespace std;
+
+bool
+serialization (const char* file, unsigned long iter)
+{
+ try
+ {
+ using namespace xercesc;
+
+ cerr << "serialization:" << endl;
+
+ // Get the object model using the standard parsing function.
+ //
+ unique_ptr<test::root> r (
+ test::root_ (file,
+ xml_schema::flags::dont_initialize |
+ xml_schema::flags::dont_validate));
+
+ // Serialize it to the in-memory buffer. This makes sure the buffer
+ // pre-allocates enough memory.
+ //
+ xml_schema::namespace_infomap map;
+ map["t"].name = "test";
+ map["t"].schema = "test.xsd";
+
+ MemBufFormatTarget ft (10240);
+ test::root_ (ft, *r, map, "UTF-8",
+ xml_schema::flags::dont_initialize |
+ xml_schema::flags::dont_pretty_print |
+ xml_schema::flags::no_xml_declaration);
+
+ size_t size (ft.getLen ());
+ cerr << " document size: " << size << " bytes" << endl
+ << " iterations: " << iter << endl;
+
+ // Create XML serializer that we are going to use in all iterations.
+ //
+ const XMLCh ls_id[] =
+ {xercesc::chLatin_L, xercesc::chLatin_S, xercesc::chNull};
+
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+ // Use the error handler implementation provided by the XSD runtime.
+ //
+ xsd::cxx::tree::error_handler<char> eh;
+ xsd::cxx::xml::dom::bits::error_handler_proxy<char> ehp (eh);
+
+ xml_schema::dom::unique_ptr<DOMLSSerializer> writer (
+ impl->createLSSerializer ());
+
+ DOMConfiguration* conf (writer->getDomConfig ());
+
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+ conf->setParameter (XMLUni::fgDOMXMLDeclaration, false);
+
+ xml_schema::dom::unique_ptr<DOMLSOutput> out (impl->createLSOutput ());
+
+ out->setByteStream (&ft);
+
+ // Serialization loop.
+ //
+ os::time start;
+
+ for (unsigned long i (0); i < iter; ++i)
+ {
+ // First serialize the object model to DOM.
+ //
+ xml_schema::dom::unique_ptr<DOMDocument> doc (test::root_ (*r, map));
+
+ ft.reset ();
+
+ // Then serialize DOM to XML reusing the serializer we created above.
+ //
+ writer->write (doc.get (), out.get ());
+ eh.throw_if_failed<xml_schema::serialization> ();
+ }
+
+ os::time end;
+ os::time time (end - start);
+
+ 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 false;
+ }
+ catch (std::ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return false;
+ }
+
+ return true;
+}
diff --git a/xsd-examples/cxx/tree/performance/test-50k.xml b/xsd-examples/cxx/tree/performance/test-50k.xml
new file mode 100644
index 0000000..42e22f3
--- /dev/null
+++ b/xsd-examples/cxx/tree/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/tree/performance/test.xsd b/xsd-examples/cxx/tree/performance/test.xsd
new file mode 100644
index 0000000..98ee921
--- /dev/null
+++ b/xsd-examples/cxx/tree/performance/test.xsd
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/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/tree/performance/time.cxx b/xsd-examples/cxx/tree/performance/time.cxx
new file mode 100644
index 0000000..48385a1
--- /dev/null
+++ b/xsd-examples/cxx/tree/performance/time.cxx
@@ -0,0 +1,46 @@
+// file : cxx/tree/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/tree/performance/time.hxx b/xsd-examples/cxx/tree/performance/time.hxx
new file mode 100644
index 0000000..b05414b
--- /dev/null
+++ b/xsd-examples/cxx/tree/performance/time.hxx
@@ -0,0 +1,110 @@
+// file : cxx/tree/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/tree/polymorphism/.gitignore b/xsd-examples/cxx/tree/polymorphism/.gitignore
new file mode 100644
index 0000000..f2e9b04
--- /dev/null
+++ b/xsd-examples/cxx/tree/polymorphism/.gitignore
@@ -0,0 +1 @@
+supermen.?xx
diff --git a/xsd-examples/cxx/tree/polymorphism/README b/xsd-examples/cxx/tree/polymorphism/README
new file mode 100644
index 0000000..6e54e49
--- /dev/null
+++ b/xsd-examples/cxx/tree/polymorphism/README
@@ -0,0 +1,32 @@
+This example shows how to use XML Schema polymorphism features such as
+xsi:type attributes and substitution groups in the C++/Tree mapping.
+
+The example consists of the following files:
+
+supermen.xsd
+ XML Schema which describes the "supermen" instance documents.
+
+supermen.xml
+ Sample XML instance document.
+
+supermen.hxx
+supermen.cxx
+ C++ types that represent the given vocabulary, a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model, and a set of serialization functions that convert the
+ object model back to XML. These are generated by XSD from supermen.xsd.
+ Note also that we use the --generate-polymorphic command line option
+ and that we don't need to use --polymorphic-type to explicitly mark
+ types as polymorphic because this is automatically deduced by the
+ XSD compiler from the substitution groups used in the supermen.xsd
+ schema.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input file. It then prints
+ the content of the object model to STDERR. Finally, the driver serializes
+ the object model back to XML.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver instance.xml
diff --git a/xsd-examples/cxx/tree/polymorphism/buildfile b/xsd-examples/cxx/tree/polymorphism/buildfile
new file mode 100644
index 0000000..754c6c2
--- /dev/null
+++ b/xsd-examples/cxx/tree/polymorphism/buildfile
@@ -0,0 +1,26 @@
+# file : cxx/tree/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} {hxx ixx cxx}{supermen} $libs
+
+exe{driver}: xml{supermen}: test.input = true
+
+<{hxx ixx cxx}{supermen}>: xsd{supermen} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-polymorphic \
+ --generate-serialization \
+ --root-element-last \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
diff --git a/xsd-examples/cxx/tree/polymorphism/driver.cxx b/xsd-examples/cxx/tree/polymorphism/driver.cxx
new file mode 100644
index 0000000..6458170
--- /dev/null
+++ b/xsd-examples/cxx/tree/polymorphism/driver.cxx
@@ -0,0 +1,59 @@
+// file : cxx/tree/polymorphism/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <iostream>
+
+#include "supermen.hxx"
+
+using std::cerr;
+using std::endl;
+using std::unique_ptr;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " supermen.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ unique_ptr<supermen> sm (supermen_ (argv[1]));
+
+ supermen copy (*sm); // Dynamic types are preserved in copies.
+
+ // Print what we've got.
+ //
+ for (supermen::person_const_iterator i (copy.person ().begin ());
+ i != copy.person ().end ();
+ ++i)
+ {
+ cerr << i->name ();
+
+ if (const superman* s = dynamic_cast<const superman*> (&*i))
+ {
+ if (s->can_fly ())
+ cerr << ", flying superman";
+ else
+ cerr << ", superman";
+ }
+
+ cerr << endl;
+ }
+
+ // Serialize back to XML.
+ //
+ xml_schema::namespace_infomap map;
+ map[""].schema = "supermen.xsd";
+
+ supermen_ (std::cout, copy, map);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/xsd-examples/cxx/tree/polymorphism/supermen.xml b/xsd-examples/cxx/tree/polymorphism/supermen.xml
new file mode 100644
index 0000000..08430fa
--- /dev/null
+++ b/xsd-examples/cxx/tree/polymorphism/supermen.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/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/tree/polymorphism/supermen.xsd b/xsd-examples/cxx/tree/polymorphism/supermen.xsd
new file mode 100644
index 0000000..cf5ff0c
--- /dev/null
+++ b/xsd-examples/cxx/tree/polymorphism/supermen.xsd
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/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/tree/secure/.gitignore b/xsd-examples/cxx/tree/secure/.gitignore
new file mode 100644
index 0000000..c116ec1
--- /dev/null
+++ b/xsd-examples/cxx/tree/secure/.gitignore
@@ -0,0 +1 @@
+library.?xx
diff --git a/xsd-examples/cxx/tree/secure/README b/xsd-examples/cxx/tree/secure/README
new file mode 100644
index 0000000..649f0a3
--- /dev/null
+++ b/xsd-examples/cxx/tree/secure/README
@@ -0,0 +1,41 @@
+This example shows how to perform more secure XML parsing by disabling
+the XML External Entity (XXE) Processing. If XML Schema validation is
+used, then it would also make sense to pre-load the known schemas and
+to disable loading of any external schemas, for example, via the
+schemaLocation attribute found in the XML documents. See the comment
+in driver.cxx for more information on how to achieve this.
+
+The example consists of the following files:
+
+library.xsd
+ XML Schema which describes a library of books.
+
+library.xml
+ Sample XML instance document. It includes (commented out) DOCTYPE
+ declarations with internal and external subsets that the parser
+ will refuse to process.
+
+library.hxx
+library.cxx
+ C++ types that represent the given vocabulary and a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model. These are generated by the XSD compiler from library.xsd.
+
+secure-dom-parser.hxx
+secure-dom-parser.cxx
+ A secure Xerces-C++ DOM parser implementation that disables processing
+ of internal/external DTD subsets.
+
+driver.cxx
+ Driver for the example. It first sets up the secure DOM parser. It then
+ parses the input file to a DOM document using the secure DOM parser and
+ calls one of the parsing functions that constructs the object model from
+ this DOM document. Finally, the driver prints a number of books in the
+ object model to STDERR.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver library.xml
+
+To verify that DTD processing is disabled, uncomment a different DOCTYPE
+version in the sample document.
diff --git a/xsd-examples/cxx/tree/secure/buildfile b/xsd-examples/cxx/tree/secure/buildfile
new file mode 100644
index 0000000..b1ca71f
--- /dev/null
+++ b/xsd-examples/cxx/tree/secure/buildfile
@@ -0,0 +1,27 @@
+# file : cxx/tree/secure/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} {hxx ixx cxx}{library} $libs
+
+exe{driver}: xml{library}: test.input = true
+
+<{hxx ixx cxx}{library}>: xsd{library} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/secure/driver.cxx b/xsd-examples/cxx/tree/secure/driver.cxx
new file mode 100644
index 0000000..7b6886f
--- /dev/null
+++ b/xsd-examples/cxx/tree/secure/driver.cxx
@@ -0,0 +1,141 @@
+// file : cxx/tree/secure/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xsd/cxx/xml/string.hxx>
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+
+#include <xsd/cxx/tree/error-handler.hxx>
+
+#include "library.hxx"
+#include "secure-dom-parser.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " library.xml" << endl;
+ return 1;
+ }
+
+ int r (0);
+
+ // We need to initialize the Xerces-C++ runtime because we
+ // are doing the XML-to-DOM parsing ourselves.
+ //
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ using namespace xercesc;
+ namespace xml = xsd::cxx::xml;
+ namespace tree = xsd::cxx::tree;
+
+ xml::dom::unique_ptr<DOMLSParser> parser (new SecureDOMParser ());
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, true);
+ conf->setParameter (XMLUni::fgXercesSchema, true);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support.
+ //
+#if _XERCES_VERSION >= 30100
+ conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+#endif
+
+ // Disable loading schemas via other means (e.g., schemaLocation).
+ //
+ // Note: this might be a good idea though if you need validation,
+ // you will need to pre-load the schema via other means. See the
+ // 'caching' and 'embedded' examples for different approaches.
+ // Both of them can be used with SecureDOMParser.
+ //
+ // conf->setParameter (XMLUni::fgXercesLoadSchema, false);
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ // Set error handler.
+ //
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+ // Parse the XML document.
+ //
+ ifstream ifs;
+ ifs.exceptions (ifstream::badbit | ifstream::failbit);
+ ifs.open (argv[1]);
+
+ // Wrap the standard input stream.
+ //
+ xml::sax::std_input_source isrc (ifs, argv[1]);
+ Wrapper4InputSource wrap (&isrc, false);
+
+ // Parse XML to DOM.
+ //
+ xml_schema::dom::unique_ptr<DOMDocument> doc (parser->parse (&wrap));
+
+ eh.throw_if_failed<xml_schema::parsing> ();
+
+ // Parse DOM to the object model.
+ //
+ unique_ptr<library::catalog> c (library::catalog_ (*doc));
+
+ cerr << "catalog with " << c->book ().size () << " books" << endl;
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ r = 1;
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+ return r;
+}
diff --git a/xsd-examples/cxx/tree/secure/library.xml b/xsd-examples/cxx/tree/secure/library.xml
new file mode 100644
index 0000000..fa5f044
--- /dev/null
+++ b/xsd-examples/cxx/tree/secure/library.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0"?>
+<!DOCTYPE lib:catalog>
+<!--
+<!DOCTYPE lib:catalog [<!ENTITY xxe SYSTEM "file:///dev/random" >]>
+-->
+<!--
+<!DOCTYPE lib:catalog PUBLIC "public id" "http://example.org">
+-->
+
+<!--
+
+file : cxx/tree/secure/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">
+ <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/tree/secure/library.xsd b/xsd-examples/cxx/tree/secure/library.xsd
new file mode 100644
index 0000000..f80da3c
--- /dev/null
+++ b/xsd-examples/cxx/tree/secure/library.xsd
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/secure/library.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension"
+ 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:language"/>
+ </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:date"/>
+ <xsd:element name="died" type="xsd:date" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="author">
+ <xsd:complexContent>
+ <xsd:extension base="lib:person">
+ <xsd:attribute name="recommends" type="xsd:IDREF" xse:refType="lib: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" default="true"/>
+ <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/tree/secure/secure-dom-parser.cxx b/xsd-examples/cxx/tree/secure/secure-dom-parser.cxx
new file mode 100644
index 0000000..8eb7a28
--- /dev/null
+++ b/xsd-examples/cxx/tree/secure/secure-dom-parser.cxx
@@ -0,0 +1,24 @@
+// file : cxx/tree/secure/secure-dom-parser.cxx
+// copyright : not copyrighted - public domain
+
+#include "secure-dom-parser.hxx"
+
+#include <xercesc/util/XMLException.hpp>
+#include <xercesc/util/XMLExceptMsgs.hpp>
+
+using namespace xercesc;
+
+void SecureDOMParser::
+doctypeDecl (const DTDElementDecl& e,
+ const XMLCh* const pub_id,
+ const XMLCh* const sys_id,
+ const bool hasi,
+ const bool hase)
+{
+ if (hasi || hase)
+ ThrowXMLwithMemMgr(RuntimeException,
+ XMLExcepts::Gen_NoDTDValidator,
+ fMemoryManager);
+
+ DOMLSParserImpl::doctypeDecl (e, pub_id, sys_id, hasi, hase);
+}
diff --git a/xsd-examples/cxx/tree/secure/secure-dom-parser.hxx b/xsd-examples/cxx/tree/secure/secure-dom-parser.hxx
new file mode 100644
index 0000000..d70dff0
--- /dev/null
+++ b/xsd-examples/cxx/tree/secure/secure-dom-parser.hxx
@@ -0,0 +1,25 @@
+// file : cxx/tree/secure/secure-dom-parser.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef SECURE_DOM_PARSER_HXX
+#define SECURE_DOM_PARSER_HXX
+
+#include <xercesc/parsers/DOMLSParserImpl.hpp>
+
+class SecureDOMParser: public xercesc::DOMLSParserImpl
+{
+public:
+ SecureDOMParser (xercesc::MemoryManager* mm =
+ xercesc::XMLPlatformUtils::fgMemoryManager,
+ xercesc::XMLGrammarPool* gp = 0)
+ : DOMLSParserImpl (0, mm, gp) {}
+
+ virtual void
+ doctypeDecl (const xercesc::DTDElementDecl& root,
+ const XMLCh* const public_id,
+ const XMLCh* const system_id,
+ const bool has_internal,
+ const bool has_external);
+};
+
+#endif // SECURE_DOM_PARSER_HXX
diff --git a/xsd-examples/cxx/tree/streaming/.gitignore b/xsd-examples/cxx/tree/streaming/.gitignore
new file mode 100644
index 0000000..db4a6e9
--- /dev/null
+++ b/xsd-examples/cxx/tree/streaming/.gitignore
@@ -0,0 +1 @@
+position.?xx
diff --git a/xsd-examples/cxx/tree/streaming/README b/xsd-examples/cxx/tree/streaming/README
new file mode 100644
index 0000000..5a467e0
--- /dev/null
+++ b/xsd-examples/cxx/tree/streaming/README
@@ -0,0 +1,51 @@
+This example shows how to perform stream-oriented, partially in-memory
+XML processing using the C++/Tree mapping. With the partially in-memory
+parsing and serialization only a part of the object model is in memory at
+any given time. With this approach we can process parts of the document
+as they become available as well as handle documents that are too large
+to fit into memory.
+
+The example consists of the following files:
+
+position.xsd
+ XML Schema which describes a simple object position vocabulary. The
+ position is represented as a potentially large series of latitude and
+ longitude measurements.
+
+position.xml
+ Sample object position document.
+
+position.hxx
+position.cxx
+ C++ types that represent the position vocabulary as well as parsing
+ and serialization functions. These are generated by XSD from
+ position.xsd.
+
+parser.hxx
+parser.cxx
+ Stream-oriented DOM parser implementation that is built on top of the
+ Xerces-C++ SAX2 parser in the progressive parsing mode. This parser
+ allows us to parse an XML document as a series of DOM fragments.
+
+serializer.hxx
+serializer.cxx
+ Stream-oriented DOM serializer implementation that allows us to
+ serialize an XML Document as a series of object model fragments.
+
+grammar-input-stream.hxx
+grammar-input-stream.cxx
+ Input stream implementation with the special-purpose schema grammar
+ decompression algorithm. It is used internally by the streaming parser.
+
+driver.cxx
+ Driver for the example. It parses the input file into a series of DOM
+ fragments which are then parsed into the object model fragments. The
+ driver prints the information from the document as it becomes available.
+ It also serializes the object model fragments into a new XML document
+ (out.xml).
+
+To run the example simply execute:
+
+$ ./driver position.xml
+
+The serialization results are written to the out.xml file.
diff --git a/xsd-examples/cxx/tree/streaming/buildfile b/xsd-examples/cxx/tree/streaming/buildfile
new file mode 100644
index 0000000..8c34b17
--- /dev/null
+++ b/xsd-examples/cxx/tree/streaming/buildfile
@@ -0,0 +1,26 @@
+# file : cxx/tree/streaming/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+
+./: exe{driver} xml{position} doc{README}
+
+exe{driver}: {hxx cxx}{* -position} {hxx ixx cxx}{position} $libs testscript
+
+<{hxx ixx cxx}{position}>: xsd{position} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-serialization \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/streaming/driver.cxx b/xsd-examples/cxx/tree/streaming/driver.cxx
new file mode 100644
index 0000000..8a70f58
--- /dev/null
+++ b/xsd-examples/cxx/tree/streaming/driver.cxx
@@ -0,0 +1,139 @@
+// file : cxx/tree/streaming/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <iostream>
+#include <fstream>
+
+#include <xercesc/dom/DOM.hpp>
+
+#include <xsd/cxx/xml/string.hxx> // xml::string
+
+#include "parser.hxx"
+#include "serializer.hxx"
+#include "position.hxx"
+
+using namespace std;
+using namespace xercesc;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " position.xml" << endl;
+ return 1;
+ }
+
+ int r (0);
+
+ // We need to initialize the Xerces-C++ runtime because we are doing
+ // the XML-to-DOM parsing ourselves.
+ //
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ using namespace op;
+ namespace xml = xsd::cxx::xml;
+
+ // Parse and serialize at the same time, in the streaming mode.
+ //
+
+ ifstream ifs;
+ ifs.exceptions (ifstream::badbit | ifstream::failbit);
+ ifs.open (argv[1]);
+
+ ofstream ofs;
+ ofs.exceptions (ios_base::badbit | ios_base::failbit);
+ ofs.open ("out.xml");
+
+ xml_schema::namespace_infomap ns_map;
+ ns_map["op"].name = "http://www.codesynthesis.com/op";
+ ns_map["op"].schema = "position.xsd";
+
+ parser p;
+ serializer s;
+
+ p.start (ifs, argv[1], true);
+ s.start (ofs);
+
+ typedef xml_schema::dom::unique_ptr<DOMDocument> document_ptr;
+
+ // Peek at the root element. This way we only get the "carcase"
+ // of the document, that is, the root element with its name, all
+ // the attributes, and namespace declarations but without any of
+ // the nested elements.
+ //
+ document_ptr docr (p.peek ());
+ bool parsed (false);
+
+ // Parse first-level elements.
+ //
+ for (document_ptr doc1 (p.peek ()); doc1.get () != 0; doc1 = p.peek ())
+ {
+ // Check whether it is an element that we should stream (position) or
+ // just add to the root (header).
+ //
+ string n1 (xml::transcode<char> (
+ doc1->getDocumentElement ()->getLocalName ()));
+
+ // If we see the first streaming element, then parse the root carcase.
+ //
+ if (!parsed && n1 == "position")
+ {
+ object o (*docr->getDocumentElement ());
+
+ cerr << "id: " << o.id () << endl
+ << "name: " << o.header ().name () << endl
+ << "type: " << o.header ().type () << endl;
+
+ // Start serializing the document by writing out the root carcase.
+ // Note that we leave it open so that we can serialize more elements.
+ //
+ s.next_open (ns_map["op"].name, "op:object", ns_map, o);
+ parsed = true;
+ }
+
+ // Handle elements that need streaming.
+ //
+ if (n1 == "position")
+ {
+ // Position has no nested elements that we need to stream so we
+ // finish parsing it in one go.
+ //
+ doc1 = p.next (move (doc1));
+ position pos (*doc1->getDocumentElement ());
+
+ cerr << "lat: " << pos.lat () << " lon: " << pos.lon () << endl;
+
+ // Serialize it (append) to the root element.
+ //
+ s.next ("position", pos);
+ }
+ else
+ {
+ // Element that doesn't require streaming (header in our case). Add
+ // to the root element and finish parsing.
+ //
+ docr = p.next (move (doc1), move (docr));
+ }
+ }
+
+ // Close the root element in serializer.
+ //
+ s.next_close ("op:object");
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+ catch (const ios_base::failure&)
+ {
+ cerr << "io failure" << endl;
+ r = 1;
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+ return r;
+}
diff --git a/xsd-examples/cxx/tree/streaming/grammar-input-stream.cxx b/xsd-examples/cxx/tree/streaming/grammar-input-stream.cxx
new file mode 100644
index 0000000..6f17f33
--- /dev/null
+++ b/xsd-examples/cxx/tree/streaming/grammar-input-stream.cxx
@@ -0,0 +1,96 @@
+// file : cxx/tree/streaming/grammar-input-stream.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <cassert>
+#include "grammar-input-stream.hxx"
+
+grammar_input_stream::
+grammar_input_stream (const XMLByte* data, std::size_t size)
+ : data_ (data),
+ size_ (size),
+ pos_ (0),
+ vpos_ (0),
+ cseq_ (0),
+ add_zero_ (false)
+{
+}
+
+XMLFilePos grammar_input_stream::
+curPos () const
+{
+ return static_cast<XMLFilePos> (vpos_);
+}
+
+XMLSize_t grammar_input_stream::
+readBytes (XMLByte* const buf, const XMLSize_t size)
+{
+ std::size_t i (0);
+
+ // Add a zero from the alternating sequence if it didn't
+ // fit on the previous read.
+ //
+ if (add_zero_)
+ {
+ buf[i++] = 0;
+ add_zero_ = false;
+ }
+
+ // If have an unfinished sequential sequence, output it now.
+ //
+ if (cseq_ != 0 && !alt_)
+ {
+ for (; cseq_ != 0 && i < size; --cseq_)
+ buf[i++] = 0;
+ }
+
+ for (; i < size && pos_ < size_;)
+ {
+ XMLByte b = buf[i++] = data_[pos_++];
+
+ // See if we are in a compression sequence.
+ //
+ if (cseq_ != 0)
+ {
+ if (i < size)
+ buf[i++] = 0;
+ else
+ add_zero_ = true; // Add it on the next read.
+
+ cseq_--;
+ continue;
+ }
+
+ // If we are not in a compression sequence and this byte is
+ // not zero then we are done.
+ //
+ if (b != 0)
+ continue;
+
+ // We have a zero.
+ //
+ assert (pos_ < size_); // There has to be another byte.
+ unsigned char v (static_cast<unsigned char> (data_[pos_++]));
+ alt_ = (v & 128) != 0;
+ cseq_ = v & 127;
+
+ // If it is a sequential sequence, output as many zeros as
+ // we can.
+ //
+ if (!alt_)
+ {
+ for (; cseq_ != 0 && i < size; --cseq_)
+ buf[i++] = 0;
+ }
+ }
+
+ vpos_ += i;
+
+ return static_cast<XMLSize_t> (i);
+}
+
+const XMLCh* grammar_input_stream::
+getContentType () const
+{
+ return 0;
+}
diff --git a/xsd-examples/cxx/tree/streaming/grammar-input-stream.hxx b/xsd-examples/cxx/tree/streaming/grammar-input-stream.hxx
new file mode 100644
index 0000000..17e6913
--- /dev/null
+++ b/xsd-examples/cxx/tree/streaming/grammar-input-stream.hxx
@@ -0,0 +1,41 @@
+// file : cxx/tree/streaming/grammar-input-stream.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef GRAMMAR_INPUT_STREAM_HXX
+#define GRAMMAR_INPUT_STREAM_HXX
+
+#include <cstddef>
+#include <xercesc/util/BinInputStream.hpp>
+
+// Memory buffer input stream with the special-purpose schema
+// grammar decompression.
+//
+class grammar_input_stream: public xercesc::BinInputStream
+{
+public :
+ grammar_input_stream (const XMLByte* data, std::size_t size);
+
+ virtual XMLFilePos
+ curPos () const;
+
+ virtual XMLSize_t
+ readBytes (XMLByte* const buf, const XMLSize_t size);
+
+ virtual const XMLCh*
+ getContentType () const;
+
+private :
+ const XMLByte* data_;
+ std::size_t size_;
+ std::size_t pos_;
+ std::size_t vpos_;
+
+ // Compression data.
+ //
+ size_t cseq_; // Number of bytes left in a compression sequence.
+ bool alt_; // Alternating or sequential sequence.
+ bool add_zero_; // Add a zero on the next read.
+};
+
+#endif // GRAMMAR_INPUT_STREAM_HXX
diff --git a/xsd-examples/cxx/tree/streaming/parser.cxx b/xsd-examples/cxx/tree/streaming/parser.cxx
new file mode 100644
index 0000000..064dc77
--- /dev/null
+++ b/xsd-examples/cxx/tree/streaming/parser.cxx
@@ -0,0 +1,371 @@
+#include <cassert>
+#include <utility> // std::move()
+
+#include <xercesc/util/XMLUni.hpp>
+#include <xercesc/util/XMLString.hpp>
+
+#include <xercesc/sax2/Attributes.hpp>
+#include <xercesc/sax2/DefaultHandler.hpp>
+#include <xercesc/sax2/SAX2XMLReader.hpp>
+#include <xercesc/sax2/XMLReaderFactory.hpp>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/dom/impl/DOMTextImpl.hpp>
+
+#include <xercesc/validators/common/Grammar.hpp> // xercesc::Grammar
+#include <xercesc/framework/XMLGrammarPoolImpl.hpp>
+
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+#include <xsd/cxx/xml/sax/bits/error-handler-proxy.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+#include "parser.hxx"
+#include "grammar-input-stream.hxx"
+
+using namespace std;
+using namespace xercesc;
+
+namespace xml = xsd::cxx::xml;
+namespace tree = xsd::cxx::tree;
+
+typedef parser::document_ptr document_ptr;
+
+class parser_impl: public DefaultHandler
+{
+public:
+ parser_impl (const XMLByte* grammar, size_t grammar_size);
+
+ void
+ start (istream& is, const string& id, bool validate);
+
+ document_ptr
+ peek ();
+
+ document_ptr
+ next (document_ptr doc = document_ptr (),
+ document_ptr outer_doc = document_ptr ());
+
+ // SAX event handlers.
+ //
+private:
+ virtual void
+ startElement (const XMLCh* const uri,
+ const XMLCh* const lname,
+ const XMLCh* const qname,
+ const Attributes& attributes);
+
+ virtual void
+ endElement (const XMLCh* const uri,
+ const XMLCh* const lname,
+ const XMLCh* const qname);
+
+ virtual void
+ characters (const XMLCh* const s,
+ const XMLSize_t length);
+
+private:
+ // SAX parser.
+ //
+ bool clean_;
+ unique_ptr<XMLGrammarPool> grammar_pool_;
+ unique_ptr<SAX2XMLReader> parser_;
+ XMLPScanToken token_;
+ tree::error_handler<char> error_handler_;
+ xml::sax::bits::error_handler_proxy<char> error_proxy_;
+ unique_ptr<xml::sax::std_input_source> isrc_;
+
+ size_t depth_;
+ size_t whitespace_depth_; // Depth at which to ignore whitespaces.
+
+ bool peek_;
+ size_t next_depth_; // Depth at which next() should work.
+
+ // DOM document being built.
+ //
+ DOMImplementation& dom_impl_;
+ document_ptr doc_;
+ DOMElement* cur_;
+};
+
+const XMLCh ls[] = {chLatin_L, chLatin_S, chNull};
+
+parser_impl::
+parser_impl (const XMLByte* grammar, size_t grammar_size)
+ : clean_ (true),
+ error_proxy_ (error_handler_),
+ dom_impl_ (*DOMImplementationRegistry::getDOMImplementation (ls))
+{
+ MemoryManager* mm (XMLPlatformUtils::fgMemoryManager);
+
+ if (grammar != 0)
+ {
+ assert (grammar_size != 0);
+ grammar_pool_.reset (new XMLGrammarPoolImpl (mm));
+
+ grammar_input_stream is (grammar, grammar_size);
+ grammar_pool_->deserializeGrammars(&is);
+ grammar_pool_->lockPool ();
+ }
+
+ parser_.reset (XMLReaderFactory::createXMLReader (mm, grammar_pool_.get ()));
+
+ parser_->setFeature (XMLUni::fgSAX2CoreNameSpaces, true);
+ parser_->setFeature (XMLUni::fgSAX2CoreNameSpacePrefixes, true);
+ parser_->setFeature (XMLUni::fgXercesValidationErrorAsFatal, true);
+ parser_->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support. It also allows us to disable buffering in the parser
+ // so that the data is parsed and returned as soon as it is
+ // available.
+ //
+#if _XERCES_VERSION >= 30100
+ parser_->setFeature (XMLUni::fgXercesHandleMultipleImports, true);
+
+ XMLSize_t lwm = 0;
+ parser_->setProperty (XMLUni::fgXercesLowWaterMark, &lwm);
+#endif
+
+ parser_->setErrorHandler (&error_proxy_);
+ parser_->setContentHandler (this);
+}
+
+void parser_impl::
+start (istream& is, const string& id, bool val)
+{
+ // Reset our state.
+ //
+ depth_ = 0;
+ peek_ = false;
+ doc_.reset ();
+ error_handler_.reset ();
+
+ if (!clean_)
+ parser_->parseReset (token_);
+ else
+ clean_ = false;
+
+ isrc_.reset (new xml::sax::std_input_source (is, id));
+
+ parser_->setFeature (XMLUni::fgSAX2CoreValidation, val);
+ parser_->setFeature (XMLUni::fgXercesSchema, val);
+
+ if (val && grammar_pool_.get () != 0)
+ {
+ // Use the loaded grammar during parsing.
+ //
+ parser_->setFeature (XMLUni::fgXercesUseCachedGrammarInParse, true);
+
+ // Disable loading schemas via other means (e.g., schemaLocation).
+ //
+ parser_->setFeature (XMLUni::fgXercesLoadSchema, false);
+ }
+
+ parser_->parseFirst (*isrc_, token_);
+ error_handler_.throw_if_failed<tree::parsing<char> > ();
+}
+
+document_ptr parser_impl::
+peek ()
+{
+ bool r (true);
+
+ size_t d (depth_);
+ whitespace_depth_ = d;
+
+ peek_ = true;
+
+ // Parse (skip whitespace content) until the depth increases or we get
+ // a document. The latter test covers <element/> cases where both start
+ // and end events will trigger and therefore leave the depth unchanged.
+ //
+ while (r && depth_ == d && doc_.get () == 0)
+ {
+ r = parser_->parseNext (token_);
+ error_handler_.throw_if_failed<tree::parsing<char> > ();
+ }
+
+ if (!r)
+ return document_ptr ();
+
+ return move (doc_);
+}
+
+document_ptr parser_impl::
+next (document_ptr doc, document_ptr outer_doc)
+{
+ assert (peek_ == (doc.get () != 0));
+
+ // Install doc/outer_doc as the document we are parsing.
+ //
+ if (doc.get () != 0)
+ {
+ if (outer_doc.get () != 0)
+ {
+ // Move doc to outer_doc.
+ //
+ doc_ = move (outer_doc);
+ cur_ = static_cast<DOMElement*> (
+ doc_->importNode (doc->getDocumentElement (), true));
+ doc_->getDocumentElement ()->appendChild (cur_);
+ }
+ else
+ {
+ doc_ = move (doc);
+ cur_ = doc_->getDocumentElement ();
+ }
+
+ // This handles the <element/> case where we get both start and
+ // end events in peek(). In this case the element is fully parsed
+ // and next() has nothing to do.
+ //
+ if (depth_ != next_depth_)
+ {
+ peek_ = false;
+ return move (doc_);
+ }
+ }
+
+ bool r (true);
+
+ // If we peeked, then we have already seen the start tag and our
+ // return depth is one above the current depth.
+ //
+ size_t d (peek_ ? depth_ - 1 : depth_);
+ whitespace_depth_ = d;
+
+ peek_ = false;
+
+ // Keep calling parseNext() until we either move to a greater depth or
+ // get a document. This way we skip the text (presumably whitespaces)
+ // that may be preceding this chunk.
+ //
+ while (r && depth_ == d && doc_.get () == 0)
+ {
+ parser_->parseNext (token_);
+ error_handler_.throw_if_failed<tree::parsing<char> > ();
+ }
+
+ if (!r)
+ return document_ptr ();
+
+ // If we are not at our start depth, keep calling parseNext() until we
+ // get there again.
+ //
+ while (r && depth_ != d)
+ {
+ r = parser_->parseNext (token_);
+ error_handler_.throw_if_failed<tree::parsing<char> > ();
+ }
+
+ if (!r)
+ return document_ptr ();
+
+ return move (doc_);
+}
+
+// DOM builder.
+//
+
+void parser_impl::
+startElement (const XMLCh* const uri,
+ const XMLCh* const /*lname*/,
+ const XMLCh* const qname,
+ const Attributes& attr)
+{
+ if (doc_.get () == 0)
+ {
+ doc_.reset (dom_impl_.createDocument (uri, qname, 0));
+ cur_ = doc_->getDocumentElement ();
+ }
+ else
+ {
+ DOMElement* e = doc_->createElementNS (uri, qname);
+ cur_->appendChild (e);
+ cur_ = e;
+ }
+
+ // Set attributes.
+ //
+ for (XMLSize_t i (0), end (attr.getLength()); i < end; ++i)
+ {
+ const XMLCh* qn (attr.getQName (i));
+ const XMLCh* ns (attr.getURI (i));
+
+ // When SAX2 reports the xmlns attribute, it does not include
+ // the proper attribute namespace. So we have to detect and
+ // handle this case.
+ //
+ if (XMLString::equals (qn, XMLUni::fgXMLNSString))
+ ns = XMLUni::fgXMLNSURIName;
+
+ cur_->setAttributeNS (ns, qn, attr.getValue (i));
+ }
+
+ depth_++;
+
+ if (peek_)
+ next_depth_ = depth_;
+}
+
+void parser_impl::
+endElement (const XMLCh* const /*uri*/,
+ const XMLCh* const /*lname*/,
+ const XMLCh* const /*qname*/)
+{
+ // We have an element parent only on depth 2 or greater.
+ //
+ if (--depth_ > 1)
+ cur_ = static_cast<DOMElement*> (cur_->getParentNode ());
+}
+
+void parser_impl::
+characters (const XMLCh* const s, const XMLSize_t length)
+{
+ const XMLCh empty[] = {chNull};
+
+ // Ignore text content (presumably whitespaces) while looking for
+ // the next element.
+ //
+ if (depth_ > whitespace_depth_)
+ {
+ DOMText* t = doc_->createTextNode (empty);
+ static_cast<DOMTextImpl*> (t)->appendData (s, length);
+ cur_->appendChild (t);
+ }
+}
+
+//
+// parser
+//
+
+parser::
+~parser ()
+{
+}
+
+parser::
+parser (const XMLByte* grammar, size_t grammar_size)
+ : impl_ (new parser_impl (grammar, grammar_size))
+{
+}
+
+void parser::
+start (istream& is, const string& id, bool val)
+{
+ return impl_->start (is, id, val);
+}
+
+document_ptr parser::
+peek ()
+{
+ return impl_->peek ();
+}
+
+document_ptr parser::
+next (document_ptr doc, document_ptr outer_doc)
+{
+ return impl_->next (move (doc), move (outer_doc));
+}
diff --git a/xsd-examples/cxx/tree/streaming/parser.hxx b/xsd-examples/cxx/tree/streaming/parser.hxx
new file mode 100644
index 0000000..605d236
--- /dev/null
+++ b/xsd-examples/cxx/tree/streaming/parser.hxx
@@ -0,0 +1,67 @@
+#ifndef PARSER_HXX
+#define PARSER_HXX
+
+#include <string>
+#include <iosfwd>
+#include <cstddef> // std::size_t
+#include <memory> // std::unique_ptr
+
+#include <xercesc/dom/DOMDocument.hpp>
+
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+
+class parser_impl;
+
+class parser
+{
+public:
+ // We can specify embedded XML Schema grammar to be used by the parser
+ // that was created by the xsdbin utility from the 'embedded' example.
+ //
+ parser (const XMLByte* grammar = 0, std::size_t grammar_size = 0);
+ ~parser ();
+
+ // The start function prepares everything for parsing a new document.
+ //
+ void
+ start (std::istream& is, const std::string& id, bool validate);
+
+ typedef xsd::cxx::xml::dom::unique_ptr<xercesc::DOMDocument> document_ptr;
+
+ // The peek function parses just the next element (ignoring any
+ // preceding content assuming it is whitespace) without parsing
+ // any of its nested content (but it includes the element's
+ // attributes). It returns NULL if there are no more elements
+ // at this level (there could still be on outer levels in case
+ // of nested streaming).
+ //
+ document_ptr
+ peek ();
+
+ // The next function parses (or finishes parsing after peek) the
+ // next element including its nested content. It returns NULL if
+ // there are no more elements at this level (there could still
+ // be on outer levels in case of nested streaming).
+ //
+ // If doc is not NULL, then it should be the document returned
+ // by peek(). That is, a document with only the root element.
+ // In this case next() finishes parsing this element.
+ //
+ // If outer_doc is not NULL, then next() will first add doc to
+ // outer_doc as a child of the document root.
+ //
+ document_ptr
+ next (document_ptr doc = document_ptr (),
+ document_ptr outer_doc = document_ptr ());
+
+private:
+ parser (const parser&);
+
+ parser&
+ operator= (const parser&);
+
+private:
+ std::unique_ptr<parser_impl> impl_;
+};
+
+#endif // PARSER_HXX
diff --git a/xsd-examples/cxx/tree/streaming/position.xml b/xsd-examples/cxx/tree/streaming/position.xml
new file mode 100644
index 0000000..3308306
--- /dev/null
+++ b/xsd-examples/cxx/tree/streaming/position.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/streaming/position.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<op:object xmlns:op="http://www.codesynthesis.com/op"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/op position.xsd"
+ id="123">
+
+ <header>
+ <name>Lion's Head</name>
+ <type>rock</type>
+ </header>
+
+ <position lat="-33.8569" lon="18.5083"/>
+ <position lat="-33.8568" lon="18.5083"/>
+ <position lat="-33.8568" lon="18.5082"/>
+ <position lat="-33.8570" lon="18.5083"/>
+ <position lat="-33.8569" lon="18.5084"/>
+ <position lat="-33.8570" lon="18.5084"/>
+ <position lat="-33.8570" lon="18.5082"/>
+ <position lat="-33.8569" lon="18.5082"/>
+
+</op:object>
diff --git a/xsd-examples/cxx/tree/streaming/position.xsd b/xsd-examples/cxx/tree/streaming/position.xsd
new file mode 100644
index 0000000..0fbcf87
--- /dev/null
+++ b/xsd-examples/cxx/tree/streaming/position.xsd
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/streaming/position.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:op="http://www.codesynthesis.com/op"
+ targetNamespace="http://www.codesynthesis.com/op">
+
+
+ <xsd:complexType name="header">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="type" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="position">
+ <xsd:attribute name="lat" type="xsd:float" use="required"/>
+ <xsd:attribute name="lon" type="xsd:float" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="object">
+ <xsd:sequence>
+ <xsd:element name="header" type="op:header"/>
+ <xsd:element name="position" type="op:position" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:unsignedInt" use="required"/>
+ </xsd:complexType>
+
+ <xsd:element name="object" type="op:object"/>
+
+</xsd:schema>
diff --git a/xsd-examples/cxx/tree/streaming/serializer.cxx b/xsd-examples/cxx/tree/streaming/serializer.cxx
new file mode 100644
index 0000000..b903a49
--- /dev/null
+++ b/xsd-examples/cxx/tree/streaming/serializer.cxx
@@ -0,0 +1,636 @@
+#include <vector>
+#include <cassert>
+#include <cstddef>
+
+#include <xercesc/util/XMLUni.hpp>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/dom/impl/DOMDocumentImpl.hpp>
+#include <xercesc/dom/impl/DOMLSSerializerImpl.hpp>
+
+#include <xsd/cxx/xml/string.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+#include <xsd/cxx/xml/dom/serialization-source.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+#include "serializer.hxx"
+
+using namespace std;
+using namespace xercesc;
+
+namespace xml = xsd::cxx::xml;
+namespace tree = xsd::cxx::tree;
+
+static const XMLCh gEOLSeq[] =
+{
+ chLF, chNull
+};
+
+static const XMLCh gUTF8[] =
+{
+ chLatin_U, chLatin_T, chLatin_F, chDash, chDigit_8, chNull
+};
+
+static const XMLCh gEndElement[] =
+{
+ chOpenAngle, chForwardSlash, chNull
+};
+
+static const int DISCARD_DEFAULT_CONTENT_ID = 0x1;
+static const int ENTITIES_ID = 0x2;
+static const int FORMAT_PRETTY_PRINT_1ST_LEVEL_ID = 0xA;
+
+class StreamingDOMSerializer: public DOMLSSerializerImpl
+{
+public:
+ StreamingDOMSerializer (MemoryManager* manager)
+ : DOMLSSerializerImpl (manager)
+ {
+ }
+
+ bool
+ startOpen (const DOMElement* e, DOMLSOutput* const destination)
+ {
+ const DOMDocument* docu (e->getOwnerDocument ());
+ assert (docu != 0);
+
+ // Code adapted from DOMLSSerializerImpl::write().
+ //
+ target_ = destination->getByteStream();
+
+ fEncodingUsed = gUTF8;
+
+ const XMLCh* lsEncoding=destination->getEncoding();
+ if (lsEncoding && *lsEncoding)
+ {
+ fEncodingUsed = lsEncoding;
+ }
+ else if (docu)
+ {
+ const XMLCh* tmpEncoding = docu->getInputEncoding();
+
+ if ( tmpEncoding && *tmpEncoding)
+ {
+ fEncodingUsed = tmpEncoding;
+ }
+ else
+ {
+ tmpEncoding = docu->getXmlEncoding();
+
+ if ( tmpEncoding && *tmpEncoding)
+ {
+ fEncodingUsed = tmpEncoding;
+ }
+ }
+ }
+
+ fNewLineUsed = (fNewLine && *fNewLine)? fNewLine : gEOLSeq;
+
+ fDocumentVersion = (docu->getXmlVersion() && *(docu->getXmlVersion()))
+ ? docu->getXmlVersion()
+ : XMLUni::fgVersion1_0;
+
+ fErrorCount = 0;
+
+ fLineFeedInTextNodePrinted = false;
+ fLastWhiteSpaceInTextNode = 0;
+
+ level_ = 0;
+ namespace_map_.clear ();
+
+ fFormatter = new (fMemoryManager) XMLFormatter( fEncodingUsed
+ ,fDocumentVersion
+ ,target_
+ ,XMLFormatter::NoEscapes
+ ,XMLFormatter::UnRep_CharRef
+ ,fMemoryManager);
+ formatter_.reset (fFormatter);
+
+ // Write out the XML declaration, etc. Here we assume that the document
+ // has no children (i.e., no root element).
+ //
+ processNode (docu, 0);
+ fLineFeedInTextNodePrinted = true;
+
+ return writeOpen (e);
+ }
+
+ bool
+ writeOpen (const DOMElement* e)
+ {
+ // Code adapted from the first part of ELEMENT_NODE case in
+ // DOMLSSerializerImpl::processNode().
+ //
+
+ if (!fLineFeedInTextNodePrinted)
+ {
+ if(level_ == 1 && getFeature(FORMAT_PRETTY_PRINT_1ST_LEVEL_ID))
+ printNewLine();
+
+ printNewLine();
+ }
+ else
+ {
+ fLineFeedInTextNodePrinted = false;
+ }
+
+ printIndent(level_);
+
+ RefHashTableOf<XMLCh>* namespaceMap = NULL;
+
+ *fFormatter << XMLFormatter::NoEscapes << chOpenAngle <<
+ e->getNodeName ();
+
+ setURCharRef();
+ DOMNamedNodeMap *attributes = e->getAttributes();
+ XMLSize_t attrCount = attributes->getLength();
+
+ const XMLCh* prefix = e->getPrefix();
+ const XMLCh* uri = e->getNamespaceURI();
+ if((uri && uri[0]) ||
+ ((prefix==0 || prefix[0]==0) && isDefaultNamespacePrefixDeclared()))
+ {
+ if(prefix==0 || prefix[0]==0)
+ prefix=XMLUni::fgZeroLenString;
+ if(!isNamespaceBindingActive(prefix, uri))
+ {
+ if(namespaceMap==NULL)
+ {
+ namespaceMap=new (fMemoryManager) RefHashTableOf<XMLCh>(12, false, fMemoryManager);
+ fNamespaceStack->addElement(namespaceMap);
+ }
+ namespaceMap->put((void*)prefix,(XMLCh*)uri);
+ *fFormatter << XMLFormatter::NoEscapes
+ << chSpace << XMLUni::fgXMLNSString;
+
+ if(!XMLString::equals(prefix,XMLUni::fgZeroLenString))
+ *fFormatter << chColon << prefix;
+
+ *fFormatter << chEqual << chDoubleQuote
+ << XMLFormatter::AttrEscapes
+ << uri
+ << XMLFormatter::NoEscapes
+ << chDoubleQuote;
+ }
+ }
+
+ bool discard = getFeature(DISCARD_DEFAULT_CONTENT_ID);
+ for (XMLSize_t i = 0; i < attrCount; i++)
+ {
+ DOMAttr* attribute = (DOMAttr*)attributes->item(i);
+
+ if (discard && !((DOMAttr*)attribute )->getSpecified())
+ continue;
+
+ // if this attribute is a namespace declaration, add it to the namespace map for the current level
+ const XMLCh* ns = attribute->getNamespaceURI();
+ if (ns != 0 )
+ {
+ if(XMLString::equals(ns, XMLUni::fgXMLNSURIName))
+ {
+ if(namespaceMap==NULL)
+ {
+ namespaceMap=new (fMemoryManager) RefHashTableOf<XMLCh>(12, false, fMemoryManager);
+ fNamespaceStack->addElement(namespaceMap);
+ }
+ const XMLCh* nsPrefix = attribute->getLocalName();
+ if(XMLString::equals(attribute->getNodeName(),XMLUni::fgXMLNSString))
+ nsPrefix = XMLUni::fgZeroLenString;
+ if(namespaceMap->containsKey((void*)nsPrefix))
+ continue;
+ namespaceMap->put((void*)attribute->getLocalName(),(XMLCh*)attribute->getNodeValue());
+ }
+ else if(!XMLString::equals(ns, XMLUni::fgXMLURIName))
+ {
+ // check if the namespace for the current node is already defined
+ const XMLCh* prefix = attribute->getPrefix();
+ if(prefix && prefix[0])
+ {
+ const XMLCh* uri = attribute->getNamespaceURI();
+ if(!isNamespaceBindingActive(prefix, uri))
+ {
+ if(namespaceMap==NULL)
+ {
+ namespaceMap=new (fMemoryManager) RefHashTableOf<XMLCh>(12, false, fMemoryManager);
+ fNamespaceStack->addElement(namespaceMap);
+ }
+ namespaceMap->put((void*)prefix,(XMLCh*)uri);
+
+ *fFormatter << XMLFormatter::NoEscapes
+ << chSpace << XMLUni::fgXMLNSString << chColon << prefix
+ << chEqual << chDoubleQuote
+ << XMLFormatter::AttrEscapes
+ << uri
+ << XMLFormatter::NoEscapes
+ << chDoubleQuote;
+ }
+ }
+ }
+ }
+
+ if (XMLString::equals(ns, XMLUni::fgXMLNSURIName) || checkFilter(attribute) == DOMNodeFilter::FILTER_ACCEPT)
+ {
+ *fFormatter << XMLFormatter::NoEscapes
+ << chSpace << attribute->getNodeName()
+ << chEqual << chDoubleQuote
+ << XMLFormatter::AttrEscapes;
+
+ if (getFeature(ENTITIES_ID))
+ {
+ DOMNode* child = attribute->getFirstChild();
+ while( child != 0)
+ {
+ if(child->getNodeType()==DOMNode::TEXT_NODE)
+ *fFormatter << child->getNodeValue();
+ else if(child->getNodeType()==DOMNode::ENTITY_REFERENCE_NODE)
+ *fFormatter << XMLFormatter::NoEscapes
+ << chAmpersand << child->getNodeName() << chSemiColon
+ << XMLFormatter::AttrEscapes;
+ child = child->getNextSibling();
+ }
+ }
+ else
+ *fFormatter << attribute->getNodeValue();
+
+ *fFormatter << XMLFormatter::NoEscapes << chDoubleQuote;
+ }
+ }
+
+ *fFormatter << XMLFormatter::NoEscapes << chCloseAngle;
+
+ // Keep track of whether we have added a namespace map for this
+ // element. Used to pop it in writeClose().
+ //
+ namespace_map_.push_back (namespaceMap != 0);
+
+ level_++;
+
+ DOMNode* child = e->getFirstChild();
+ while (child != 0)
+ {
+ processNode (child, level_);
+ child = child->getNextSibling();
+ }
+
+ return fErrorCount == 0;
+ }
+
+ bool
+ writeClose (const XMLCh* name)
+ {
+ // Code adapted from the second part of ELEMENT_NODE case in
+ // DOMLSSerializerImpl::processNode().
+ //
+ level_--;
+
+ // Assume we are not on the same line (nodeLine != fCurrentLine).
+ //
+ {
+ if (!fLineFeedInTextNodePrinted)
+ {
+ printNewLine();
+ }
+ else
+ {
+ fLineFeedInTextNodePrinted = false;
+ }
+
+ if(level_ == 0 && getFeature(FORMAT_PRETTY_PRINT_1ST_LEVEL_ID))
+ printNewLine();
+
+ printIndent(level_);
+ }
+
+ *fFormatter << XMLFormatter::NoEscapes << gEndElement <<
+ name << chCloseAngle;
+
+ if (namespace_map_.back ())
+ fNamespaceStack->removeLastElement();
+
+ namespace_map_.pop_back ();
+
+ if (level_ == 0)
+ {
+ printNewLine();
+ target_->flush ();
+ }
+
+ return fErrorCount == 0;
+ }
+
+ bool
+ write (const DOMElement* e)
+ {
+ processNode (e, level_);
+ return fErrorCount == 0;
+ }
+
+ using DOMLSSerializerImpl::write; // Whole document.
+
+public:
+ // Update the namespace stack to point to the strings from the
+ // new document's string pool.
+ //
+ void
+ update_namespace_stack (DOMDocument& d)
+ {
+ DOMDocumentImpl& di (dynamic_cast<DOMDocumentImpl&> (d));
+
+ for (XMLSize_t i (0); i != fNamespaceStack->size (); ++i)
+ {
+ RefHashTableOf<XMLCh>& t (*fNamespaceStack->elementAt (i));
+ RefHashTableOfEnumerator<XMLCh> e (&t, false, fMemoryManager);
+ while (e.hasMoreElements ())
+ {
+ XMLCh* k ((XMLCh*) (e.nextElementKey ()));
+ XMLCh* v (t.get (k));
+ t.put ((void*) (di.getPooledString (k)),
+ (XMLCh*) (di.getPooledString (v)));
+ }
+ }
+ }
+
+private:
+ XMLFormatTarget* target_;
+ std::unique_ptr<XMLFormatter> formatter_;
+ int level_;
+
+ std::vector<bool> namespace_map_;
+};
+
+class serializer_impl
+{
+public:
+ typedef serializer::namespace_infomap namespace_infomap;
+
+ serializer_impl ();
+
+ void
+ start (ostream& os, const string& encoding);
+
+ DOMElement*
+ create (const string& name, const namespace_infomap&);
+
+ DOMElement*
+ create (const string& ns, const string& qname, const namespace_infomap&);
+
+ void
+ serialize (xml::dom::unique_ptr<DOMElement>);
+
+ void
+ serialize_open (xml::dom::unique_ptr<DOMElement>);
+
+ void
+ serialize_close (const string&);
+
+private:
+ void
+ clear_document ();
+
+private:
+ bool start_;
+
+ // Serializer.
+ //
+ xml::dom::unique_ptr<DOMLSOutput> out_;
+ xml::dom::unique_ptr<StreamingDOMSerializer> serializer_;
+
+ unique_ptr<xml::dom::ostream_format_target> oft_;
+
+ tree::error_handler<char> error_handler_;
+ xml::dom::bits::error_handler_proxy<char> error_proxy_;
+
+ // DOM document that we use to create the elements.
+ //
+ DOMImplementation& dom_impl_;
+ xml::dom::unique_ptr<DOMDocument> doc_;
+ vector<DOMElement*> element_stack_;
+
+ size_t element_count_; // Number of elements serialized using current doc.
+ static const size_t element_count_limit_ = 500;
+};
+
+const XMLCh ls[] = {chLatin_L, chLatin_S, chNull};
+
+serializer_impl::
+serializer_impl ()
+ : error_proxy_ (error_handler_),
+ dom_impl_ (*DOMImplementationRegistry::getDOMImplementation (ls))
+{
+ serializer_.reset (
+ new (XMLPlatformUtils::fgMemoryManager)
+ StreamingDOMSerializer (XMLPlatformUtils::fgMemoryManager));
+
+ DOMConfiguration* conf (serializer_->getDomConfig ());
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &error_proxy_);
+ conf->setParameter (XMLUni::fgDOMXMLDeclaration, true);
+ conf->setParameter (XMLUni::fgDOMWRTDiscardDefaultContent, true);
+ conf->setParameter (XMLUni::fgDOMWRTFormatPrettyPrint, true);
+ conf->setParameter (XMLUni::fgDOMWRTXercesPrettyPrint, false);
+}
+
+void serializer_impl::
+start (ostream& os, const string& encoding)
+{
+ element_stack_.clear ();
+ doc_.reset (dom_impl_.createDocument ());
+ element_count_ = 0;
+
+ error_handler_.reset ();
+ oft_.reset (new xml::dom::ostream_format_target (os));
+
+ out_.reset (dom_impl_.createLSOutput ());
+ out_->setEncoding (xml::string (encoding).c_str ());
+ out_->setByteStream (oft_.get ());
+
+ start_ = true;
+}
+
+DOMElement* serializer_impl::
+create (const string& name, const namespace_infomap& map)
+{
+ DOMElement* r (doc_->createElement (xml::string (name).c_str ()));
+
+ if (!map.empty ())
+ xml::dom::add_namespaces<char> (*r, map);
+
+ // Add the element as the child of the stack "tip" so that it
+ // "sees" all the namespace declarations active from this point.
+ //
+ if (!element_stack_.empty ())
+ element_stack_.back ()->appendChild (r);
+
+ return r;
+}
+
+DOMElement* serializer_impl::
+create (const string& ns, const string& qname, const namespace_infomap& map)
+{
+ DOMElement* r (
+ doc_->createElementNS (
+ xml::string (ns).c_str (), xml::string (qname).c_str ()));
+
+ if (!map.empty ())
+ xml::dom::add_namespaces<char> (*r, map);
+
+ // Add the element as the child of the stack "tip" so that it
+ // "sees" all the namespace declarations active from this point.
+ //
+ if (!element_stack_.empty ())
+ element_stack_.back ()->appendChild (r);
+
+ return r;
+}
+
+void serializer_impl::
+serialize (xml::dom::unique_ptr<DOMElement> p)
+{
+ DOMElement* e (p.get ());
+
+ if (start_)
+ {
+ serializer_->write (e, out_.get ());
+ start_ = false;
+ }
+ else
+ serializer_->write (e);
+
+ error_handler_.throw_if_failed<tree::serialization<char> > ();
+
+ // Remove this element from its parent before we release.
+ //
+ if (!element_stack_.empty ())
+ element_stack_.back ()->removeChild (e);
+
+ p.reset (); // Release it before we may clear the document below.
+
+ if (element_count_++ > element_count_limit_)
+ clear_document ();
+}
+
+void serializer_impl::
+serialize_open (xml::dom::unique_ptr<DOMElement> p)
+{
+ DOMElement* e (p.get ());
+
+ if (start_)
+ {
+ serializer_->startOpen (e, out_.get ());
+ start_ = false;
+ }
+ else
+ serializer_->writeOpen (e);
+
+ error_handler_.throw_if_failed<tree::serialization<char> > ();
+
+ // Add this element to the element stack. serialize_close() is
+ // responsible for its removal and releasing.
+ //
+ element_stack_.push_back (e);
+ p.release ();
+}
+
+void serializer_impl::
+serialize_close (const string& name)
+{
+ serializer_->writeClose (xml::string (name).c_str ());
+ error_handler_.throw_if_failed<tree::serialization<char> > ();
+
+ // Release the element.
+ //
+ DOMElement* e (element_stack_.back ());
+ element_stack_.pop_back ();
+
+ if (!element_stack_.empty ())
+ element_stack_.back ()->removeChild (e);
+
+ e->release ();
+
+ if (element_count_++ > element_count_limit_)
+ clear_document ();
+}
+
+void serializer_impl::
+clear_document ()
+{
+ // Re-create the document in order to force deallocation of its
+ // internal heap. While Xerces-C++ DOM tries to re-use memory,
+ // it still accumulates no longer used memory blocks.
+ //
+ xml::dom::unique_ptr<DOMDocument> doc (dom_impl_.createDocument ());
+
+ if (!element_stack_.empty ())
+ {
+ DOMElement* e (
+ static_cast<DOMElement*> (
+ doc->importNode (element_stack_.front (), true)));
+
+ for (vector<DOMElement*>::iterator i (element_stack_.begin ());
+ i != element_stack_.end ();
+ ++i)
+ {
+ *i = e;
+ e = static_cast<DOMElement*> (e->getFirstChild ());
+ }
+ }
+
+ // Update the namespace stack to use the new document.
+ //
+ serializer_->update_namespace_stack (*doc);
+
+ doc_ = move (doc);
+ element_count_ = 0;
+}
+
+//
+// serializer
+//
+
+serializer::
+~serializer ()
+{
+}
+
+serializer::
+serializer ()
+ : impl_ (new serializer_impl)
+{
+}
+
+void serializer::
+start (ostream& os, const string& encoding)
+{
+ impl_->start (os, encoding);
+}
+
+DOMElement* serializer::
+create (const string& name, const namespace_infomap& map)
+{
+ return impl_->create (name, map);
+}
+
+DOMElement* serializer::
+create (const string& ns, const string& qname, const namespace_infomap& map)
+{
+ return impl_->create (ns, qname, map);
+}
+
+void serializer::
+serialize (xml::dom::unique_ptr<DOMElement> e)
+{
+ impl_->serialize (move (e));
+}
+
+void serializer::
+serialize_open (xml::dom::unique_ptr<DOMElement> e)
+{
+ impl_->serialize_open (move (e));
+}
+
+void serializer::
+serialize_close (const string& name)
+{
+ impl_->serialize_close (name);
+}
diff --git a/xsd-examples/cxx/tree/streaming/serializer.hxx b/xsd-examples/cxx/tree/streaming/serializer.hxx
new file mode 100644
index 0000000..585bd76
--- /dev/null
+++ b/xsd-examples/cxx/tree/streaming/serializer.hxx
@@ -0,0 +1,209 @@
+// file : cxx/tree/streaming/serializer.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef SERIALIZER_HXX
+#define SERIALIZER_HXX
+
+#include <string>
+#include <iosfwd>
+#include <memory> // std::unique_ptr
+
+#include <xercesc/dom/DOMElement.hpp>
+
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+#include <xsd/cxx/xml/dom/serialization-header.hxx> // namespace_infomap
+
+class serializer_impl;
+
+class serializer
+{
+public:
+ typedef xsd::cxx::xml::dom::namespace_infomap<char> namespace_infomap;
+
+ ~serializer ();
+ serializer ();
+
+ // Start the serialization process.
+ //
+ void
+ start (std::ostream& is, const std::string& encoding = "UTF-8");
+
+ // Serialize next object model fragment into an element with the specified
+ // name.
+ //
+ template <typename T>
+ void
+ next (const std::string& name, const T& x);
+
+ // Serialize next object model fragment into an element with the specified
+ // name and namespace declarations.
+ //
+ template <typename T>
+ void
+ next (const std::string& name, const namespace_infomap&, const T& x);
+
+ // Serialize next object model fragment into an element with the specified
+ // namespace and qualified name.
+ //
+ template <typename T>
+ void
+ next (const std::string& ns, const std::string& name, const T& x);
+
+ // Serialize next object model fragment into an element with the specified
+ // namespace and qualified name as well as namespace declarations.
+ //
+ template <typename T>
+ void
+ next (const std::string& ns,
+ const std::string& name,
+ const namespace_infomap&,
+ const T& x);
+
+ // The next_open/close functions are like next() but split into two steps.
+ // next_open() serializes the object model fragment into an element leaving
+ // it open while next_close() closes the element.
+ //
+ template <typename T>
+ void
+ next_open (const std::string& name, const T& x);
+
+ template <typename T>
+ void
+ next_open (const std::string& name, const namespace_infomap&, const T& x);
+
+ template <typename T>
+ void
+ next_open (const std::string& ns, const std::string& name, const T& x);
+
+ template <typename T>
+ void
+ next_open (const std::string& ns,
+ const std::string& name,
+ const namespace_infomap&,
+ const T& x);
+
+ void
+ next_close (const std::string& name);
+
+private:
+ serializer (const serializer&);
+
+ serializer&
+ operator= (const serializer&);
+
+private:
+ xercesc::DOMElement*
+ create (const std::string& name, const namespace_infomap&);
+
+ xercesc::DOMElement*
+ create (const std::string& ns,
+ const std::string& name,
+ const namespace_infomap&);
+
+ void
+ serialize (xsd::cxx::xml::dom::unique_ptr<xercesc::DOMElement>);
+
+ void
+ serialize_open (xsd::cxx::xml::dom::unique_ptr<xercesc::DOMElement>);
+
+ void
+ serialize_close (const std::string& name);
+
+private:
+ std::unique_ptr<serializer_impl> impl_;
+};
+
+template <typename T>
+inline void serializer::
+next (const std::string& name, const T& x)
+{
+ xsd::cxx::xml::dom::unique_ptr<xercesc::DOMElement> e (
+ create (name, namespace_infomap ()));
+ *e << x;
+ serialize (std::move (e));
+}
+
+template <typename T>
+inline void serializer::
+next (const std::string& name, const namespace_infomap& map, const T& x)
+{
+ xsd::cxx::xml::dom::unique_ptr<xercesc::DOMElement> e (create (name, map));
+ *e << x;
+ serialize (std::move (e));
+}
+
+template <typename T>
+inline void serializer::
+next (const std::string& ns, const std::string& name, const T& x)
+{
+ xsd::cxx::xml::dom::unique_ptr<xercesc::DOMElement> e (
+ create (ns, name, namespace_infomap ()));
+ *e << x;
+ serialize (std::move (e));
+}
+
+template <typename T>
+inline void serializer::
+next (const std::string& ns,
+ const std::string& name,
+ const namespace_infomap& map,
+ const T& x)
+{
+ xsd::cxx::xml::dom::unique_ptr<xercesc::DOMElement> e (
+ create (ns, name, map));
+
+ *e << x;
+ serialize (std::move (e));
+}
+
+template <typename T>
+inline void serializer::
+next_open (const std::string& name, const T& x)
+{
+ xsd::cxx::xml::dom::unique_ptr<xercesc::DOMElement> e (
+ create (name, namespace_infomap ()));
+ *e << x;
+ serialize_open (std::move (e));
+}
+
+template <typename T>
+inline void serializer::
+next_open (const std::string& name, const namespace_infomap& map, const T& x)
+{
+ xsd::cxx::xml::dom::unique_ptr<xercesc::DOMElement> e (create (name, map));
+ *e << x;
+ serialize_open (std::move (e));
+}
+
+template <typename T>
+inline void serializer::
+next_open (const std::string& ns, const std::string& name, const T& x)
+{
+ xsd::cxx::xml::dom::unique_ptr<xercesc::DOMElement> e (
+ create (ns, name, namespace_infomap ()));
+ *e << x;
+ serialize_open (std::move (e));
+}
+
+template <typename T>
+inline void serializer::
+next_open (const std::string& ns,
+ const std::string& name,
+ const namespace_infomap& map,
+ const T& x)
+{
+ xsd::cxx::xml::dom::unique_ptr<xercesc::DOMElement> e (
+ create (ns, name, map));
+
+ *e << x;
+ serialize_open (std::move (e));
+}
+
+inline void serializer::
+next_close (const std::string& name)
+{
+ serialize_close (name);
+}
+
+#endif // SERIALIZER_HXX
diff --git a/xsd-examples/cxx/tree/streaming/testscript b/xsd-examples/cxx/tree/streaming/testscript
new file mode 100644
index 0000000..d3c744d
--- /dev/null
+++ b/xsd-examples/cxx/tree/streaming/testscript
@@ -0,0 +1,10 @@
+# file : cxx/tree/streaming/testscript
+# license : not copyrighted - public domain
+
+: position
+:
+{
+ $* $src_base/position.xml 2>| &out.xml;
+ echo '' >|;
+ cat out.xml >|
+}
diff --git a/xsd-examples/cxx/tree/wildcard/.gitignore b/xsd-examples/cxx/tree/wildcard/.gitignore
new file mode 100644
index 0000000..234645e
--- /dev/null
+++ b/xsd-examples/cxx/tree/wildcard/.gitignore
@@ -0,0 +1 @@
+email.?xx
diff --git a/xsd-examples/cxx/tree/wildcard/README b/xsd-examples/cxx/tree/wildcard/README
new file mode 100644
index 0000000..d451509
--- /dev/null
+++ b/xsd-examples/cxx/tree/wildcard/README
@@ -0,0 +1,34 @@
+This example shows how to use the optional wildcard mapping provided
+by C++/Tree to parse, access, modify, and serialize the XML data
+matched by XML Schema wildcards (any and anyAttribute). For an
+alternative approach that employes type customization see the
+custom/wildcard example.
+
+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.hxx
+email.ixx
+email.cxx
+ C++ types that represent the given vocabulary, a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model, and a set of serialization functions that convert the
+ object model back to XML. These are generated by XSD from email.xsd.
+ Note that the --generate-wildcard option is used to request the
+ wildcard mapping.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input file. It then prints
+ the content of the object model to STDERR. Next the driver creates a
+ reply email which is then serialized to XML.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver email.xml
diff --git a/xsd-examples/cxx/tree/wildcard/buildfile b/xsd-examples/cxx/tree/wildcard/buildfile
new file mode 100644
index 0000000..5bc63c5
--- /dev/null
+++ b/xsd-examples/cxx/tree/wildcard/buildfile
@@ -0,0 +1,30 @@
+# file : cxx/tree/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} {hxx ixx cxx}{email} $libs
+
+exe{driver}: xml{email}: test.input = true
+
+<{hxx ixx cxx}{email}>: xsd{email} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --generate-wildcard \
+ --generate-serialization \
+ --root-element message \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/wildcard/driver.cxx b/xsd-examples/cxx/tree/wildcard/driver.cxx
new file mode 100644
index 0000000..146a2d9
--- /dev/null
+++ b/xsd-examples/cxx/tree/wildcard/driver.cxx
@@ -0,0 +1,159 @@
+// file : cxx/tree/wildcard/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <string>
+#include <memory> // std::unique_ptr
+#include <cstring> // std::memcpy
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include "email.hxx"
+
+// The following string class keeps us sane when working with Xerces.
+// Include it after the generated header in order to get only char or
+// wchar_t version depending on how you compiled your schemas.
+//
+#include <xsd/cxx/xml/string.hxx>
+
+using std::cerr;
+using std::endl;
+using std::string;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " email.xml" << endl;
+ return 1;
+ }
+
+ using namespace xercesc;
+
+ int r (0);
+
+ // The Xerces-C++ DOM objects that will be used to store the
+ // content matched by wildcards "out-live" the call to the
+ // parsing function. Therefore we need to initialize the
+ // Xerces-C++ runtime ourselves.
+ //
+ XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ using namespace email;
+ namespace xml = xsd::cxx::xml;
+
+ // Read in the message.
+ //
+ std::unique_ptr<envelope> msg (
+ message (argv[1], xml_schema::flags::dont_initialize));
+
+ // Print what we've got.
+ //
+ cerr << "To: " << msg->to () << endl
+ << "From: " << msg->from () << endl
+ << "Subject: " << msg->subject () << endl;
+
+ envelope::any_sequence& body (msg->any ());
+
+ for (envelope::any_iterator i (body.begin ()); i != body.end (); ++i)
+ {
+ DOMElement& e (*i);
+ string name (xml::transcode<char> (e.getLocalName ()));
+
+ if (name == "text")
+ {
+ // Create object representation for the text element.
+ //
+ xml_schema::string text (e);
+
+ cerr << text << endl
+ << endl;
+ }
+ else if (name == "binary")
+ {
+ // Create object representation for the binary element.
+ //
+ binary bin (e);
+
+ cerr << "binary: " << bin.name () << " type: " << bin.mime () << endl
+ << endl;
+ }
+ else
+ {
+ cerr << "unknown body type: " << name << endl;
+ }
+ }
+
+ // Create a reply message.
+ //
+ envelope reply (msg->from (), msg->to (), "Re: " + msg->subject ());
+
+ // Copy the thread-id attribute from the original message if any.
+ //
+ envelope::any_attribute_set& as (msg->any_attribute ());
+ envelope::any_attribute_iterator ti (
+ as.find ("http://www.codesynthesis.com/email", "thread-id"));
+
+ if (ti != as.end ())
+ reply.any_attribute ().insert (*ti);
+
+ // Add a text body.
+ //
+ DOMDocument& doc (reply.dom_document ());
+ envelope::any_sequence& rbody (reply.any ());
+
+ xml_schema::string text ("Hi!\n\n"
+ "Indeed nice pictures. Check out mine.\n\n"
+ "Jane");
+
+ DOMElement* e (
+ doc.createElementNS (
+ xml::string ("http://www.codesynthesis.com/email").c_str (),
+ xml::string ("eml:text").c_str ()));
+
+ *e << text;
+ rbody.push_back (e);
+
+ // Add a (fake) image.
+ //
+ binary pic ("pic.jpg", "image/jpeg");
+ pic.size (3);
+ std::memcpy (pic.data (), "123", 3);
+
+ e = doc.createElementNS (
+ xml::string ("http://www.codesynthesis.com/email").c_str (),
+ xml::string ("eml:binary").c_str ());
+
+ *e << pic;
+ rbody.push_back (e);
+
+
+ // Prepare namespace mapping and schema location information for
+ // serialization.
+ //
+ xml_schema::namespace_infomap map;
+
+ map["eml"].name = "http://www.codesynthesis.com/email";
+ map["eml"].schema = "email.xsd";
+
+ // Write it out.
+ //
+ message (std::cout,
+ reply,
+ map,
+ "UTF-8",
+ xml_schema::flags::dont_initialize);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+
+ XMLPlatformUtils::Terminate ();
+ return r;
+}
diff --git a/xsd-examples/cxx/tree/wildcard/email.xml b/xsd-examples/cxx/tree/wildcard/email.xml
new file mode 100644
index 0000000..a9331e5
--- /dev/null
+++ b/xsd-examples/cxx/tree/wildcard/email.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/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/tree/wildcard/email.xsd b/xsd-examples/cxx/tree/wildcard/email.xsd
new file mode 100644
index 0000000..c051e85
--- /dev/null
+++ b/xsd-examples/cxx/tree/wildcard/email.xsd
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/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>
diff --git a/xsd-examples/cxx/tree/xpath/.gitignore b/xsd-examples/cxx/tree/xpath/.gitignore
new file mode 100644
index 0000000..83d0a51
--- /dev/null
+++ b/xsd-examples/cxx/tree/xpath/.gitignore
@@ -0,0 +1 @@
+people.?xx
diff --git a/xsd-examples/cxx/tree/xpath/README b/xsd-examples/cxx/tree/xpath/README
new file mode 100644
index 0000000..1187743
--- /dev/null
+++ b/xsd-examples/cxx/tree/xpath/README
@@ -0,0 +1,43 @@
+This example shows how to use the C++/Tree mapping together with XPath.
+In particular, it shows how to execute an XPath query on the underlying
+DOM document and then handle the result using the more convenient object
+model representation. For more information on maintaining association
+with the underlying DOM document, refer to Section 5.1, "DOM Association"
+in the C++/Tree Mapping User Manual.
+
+You will need the XQilla library[1] which provides XQuery and XPath 2
+support on top of Xerces-C++ in order to build and run this example.
+
+[1] http://xqilla.sourceforge.net
+
+The example consists of the following files:
+
+people.xsd
+ XML Schema definition for a simple person record vocabulary.
+
+people.xml
+ Sample XML instance document.
+
+people.hxx
+people.cxx
+ C++ types that represent the person record vocabulary and a set of
+ parsing functions that convert XML instance documents to a tree-like
+ in-memory object model. These are generated by XSD from people.xsd.
+
+dom-parse.hxx
+dom-parse.cxx
+ Definition and implementation of the parse() function that parses an
+ XML document to a DOM document.
+
+driver.cxx
+ Driver for the example. It first calls the above parse() function to
+ parse the input file to a DOM document using XQilla-provided DOM
+ Implementation with support for XPath 2. It then parses the DOM
+ document to the object model. Finally, it prepares and executes
+ an XPath query on the underlying DOM document and then handles
+ the result by getting back from the returned DOM nodes to object
+ model nodes.
+
+To run the example on the sample XML document simply execute:
+
+$ ./driver people.xml
diff --git a/xsd-examples/cxx/tree/xpath/buildfile b/xsd-examples/cxx/tree/xpath/buildfile
new file mode 100644
index 0000000..c6f090a
--- /dev/null
+++ b/xsd-examples/cxx/tree/xpath/buildfile
@@ -0,0 +1,28 @@
+# file : cxx/tree/xpath/buildfile
+# license : not copyrighted - public domain
+
+import libs = libxsd%lib{xsd}
+import libs += libxerces-c%lib{xerces-c}
+import libs += libxqilla%lib{xqilla}
+
+./: exe{driver} doc{README}
+
+exe{driver}: {hxx cxx}{* -people} {hxx ixx cxx}{people} $libs
+
+exe{driver}: xml{people}: test.input = true
+
+<{hxx ixx cxx}{people}>: xsd{people} $xsd
+{{
+ diag xsd ($<[0]) # @@ TMP
+
+ $xsd cxx-tree --std c++11 \
+ --generate-inline \
+ --output-dir $out_base \
+ $path($<[0])
+}}
+
+cxx.poptions =+ "-I$out_base" "-I$src_base"
+
+# Define XSD_CXX11 since we include libxsd headers directly.
+#
+cxx.poptions += -DXSD_CXX11
diff --git a/xsd-examples/cxx/tree/xpath/dom-parse.cxx b/xsd-examples/cxx/tree/xpath/dom-parse.cxx
new file mode 100644
index 0000000..f033de6
--- /dev/null
+++ b/xsd-examples/cxx/tree/xpath/dom-parse.cxx
@@ -0,0 +1,88 @@
+// file : cxx/tree/xpath/dom-parse.cxx
+// copyright : not copyrighted - public domain
+
+#include "dom-parse.hxx"
+
+#include <istream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+using namespace xercesc;
+namespace xml = xsd::cxx::xml;
+namespace tree = xsd::cxx::tree;
+
+xml::dom::unique_ptr<DOMDocument>
+parse (std::istream& is,
+ const std::string& id,
+ bool validate,
+ DOMImplementation* impl)
+{
+ xml::dom::unique_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable/Disable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, validate);
+ conf->setParameter (XMLUni::fgXercesSchema, validate);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // Xerces-C++ 3.1.0 is the first version with working multi import
+ // support.
+ //
+#if _XERCES_VERSION >= 30100
+ conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+#endif
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ // Set error handler.
+ //
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+ // Prepare input stream.
+ //
+ xml::sax::std_input_source isrc (is, id);
+ Wrapper4InputSource wrap (&isrc, false);
+
+ xml::dom::unique_ptr<DOMDocument> doc (parser->parse (&wrap));
+
+ eh.throw_if_failed<tree::parsing<char> > ();
+
+ return doc;
+}
diff --git a/xsd-examples/cxx/tree/xpath/dom-parse.hxx b/xsd-examples/cxx/tree/xpath/dom-parse.hxx
new file mode 100644
index 0000000..61dbbfe
--- /dev/null
+++ b/xsd-examples/cxx/tree/xpath/dom-parse.hxx
@@ -0,0 +1,25 @@
+// file : cxx/tree/xpath/dom-parse.hxx
+// copyright : not copyrighted - public domain
+
+#ifndef DOM_PARSE
+#define DOM_PARSE
+
+#include <string>
+#include <iosfwd>
+
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xercesc/dom/DOMImplementation.hpp>
+
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+
+// Parse an XML document from the standard input stream with an
+// optional resource id. Resource id is used in diagnostics as
+// well as to locate schemas referenced from inside the document.
+//
+xsd::cxx::xml::dom::unique_ptr<xercesc::DOMDocument>
+parse (std::istream& is,
+ const std::string& id,
+ bool validate,
+ xercesc::DOMImplementation*);
+
+#endif // DOM_PARSE
diff --git a/xsd-examples/cxx/tree/xpath/driver.cxx b/xsd-examples/cxx/tree/xpath/driver.cxx
new file mode 100644
index 0000000..246f804
--- /dev/null
+++ b/xsd-examples/cxx/tree/xpath/driver.cxx
@@ -0,0 +1,137 @@
+// file : cxx/tree/xpath/driver.cxx
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::unique_ptr
+#include <utility> // std::move()
+#include <string>
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+
+#include <xqilla/xqilla-dom3.hpp>
+
+#include <xsd/cxx/xml/string.hxx> // xml::string, xml::transcode
+
+#include "dom-parse.hxx"
+
+#include "people.hxx"
+
+using namespace std;
+using namespace xercesc;
+namespace xml = xsd::cxx::xml;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " people.xml" << endl;
+ return 1;
+ }
+
+ int r (0);
+
+ // Initialise Xerces-C++ and XQilla.
+ //
+ XQillaPlatformUtils::initialize();
+
+ // Get the XQilla DOMImplementation object with support for XPath.
+ //
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation(
+ xml::string ("XPath2 3.0").c_str ()));
+
+ try
+ {
+ using namespace people;
+
+ ifstream ifs;
+ ifs.exceptions (ifstream::badbit | ifstream::failbit);
+ ifs.open (argv[1]);
+
+ // Parse the XML file to DOM using the XQilla DOMImplementation.
+ //
+ xml_schema::dom::unique_ptr<xercesc::DOMDocument> dom (
+ parse (ifs, argv[1], true, impl));
+
+ // Parse the DOM document to the object model. We also request that
+ // the DOM document to be associated with the object model.
+ //
+ std::unique_ptr<directory> d (
+ directory_ (move (dom),
+ xml_schema::flags::keep_dom | xml_schema::flags::own_dom));
+
+ // Obtain the root element and document corresponding to the
+ // directory object.
+ //
+ DOMElement* root (static_cast<DOMElement*> (d->_node ()));
+ DOMDocument* doc (root->getOwnerDocument ());
+
+ // Obtain namespace resolver.
+ //
+ xml_schema::dom::unique_ptr<DOMXPathNSResolver> resolver (
+ doc->createNSResolver (root));
+
+ // Set the namespace prefix for the people namespace that we can
+ // use reliably in XPath expressions regardless of what is used
+ // in XML documents.
+ //
+ resolver->addNamespaceBinding (
+ xml::string ("p").c_str (),
+ xml::string ("http://www.codesynthesis.com/people").c_str ());
+
+ // Create XPath expression.
+ //
+ xml_schema::dom::unique_ptr<DOMXPathExpression> expr (
+ doc->createExpression (
+ xml::string ("p:directory/person[age > 30]").c_str (),
+ resolver.get ()));
+
+ // Execute the query.
+ //
+ xml_schema::dom::unique_ptr<DOMXPathResult> r (
+ expr->evaluate (doc, DOMXPathResult::ITERATOR_RESULT_TYPE, 0));
+
+ // Iterate over the result.
+ //
+ cerr << "Records matching the query:" << endl;
+
+ while (r->iterateNext ())
+ {
+ DOMNode* n (r->getNodeValue ());
+
+ // Obtain the object model node corresponding to this DOM node.
+ //
+ person* p (
+ static_cast<person*> (
+ n->getUserData (xml_schema::dom::tree_node_key)));
+
+ // Print the data using the object model.
+ //
+ cerr << endl
+ << "First : " << p->first_name () << endl
+ << "Last : " << p->last_name () << endl
+ << "Gender : " << p->gender () << endl
+ << "Age : " << p->age () << endl;
+ }
+ }
+ catch(const DOMException& e)
+ {
+ cerr << xml::transcode<char> (e.getMessage ()) << std::endl;
+ r = 1;
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ r = 1;
+ }
+
+ XQillaPlatformUtils::terminate();
+ return r;
+}
diff --git a/xsd-examples/cxx/tree/xpath/people.xml b/xsd-examples/cxx/tree/xpath/people.xml
new file mode 100644
index 0000000..3ce6e38
--- /dev/null
+++ b/xsd-examples/cxx/tree/xpath/people.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/xpath/people.xml
+copyright : not copyrighted - public domain
+
+-->
+
+<ppl:directory xmlns:ppl="http://www.codesynthesis.com/people"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/people people.xsd">
+
+ <person>
+ <first-name>John</first-name>
+ <last-name>Doe</last-name>
+ <gender>male</gender>
+ <age>32</age>
+ </person>
+
+ <person>
+ <first-name>Jane</first-name>
+ <last-name>Doe</last-name>
+ <gender>female</gender>
+ <age>28</age>
+ </person>
+
+</ppl:directory>
diff --git a/xsd-examples/cxx/tree/xpath/people.xsd b/xsd-examples/cxx/tree/xpath/people.xsd
new file mode 100644
index 0000000..951d410
--- /dev/null
+++ b/xsd-examples/cxx/tree/xpath/people.xsd
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : cxx/tree/xpath/people.xsd
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:ppl="http://www.codesynthesis.com/people"
+ targetNamespace="http://www.codesynthesis.com/people">
+
+ <xsd:simpleType name="gender">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="male"/>
+ <xsd:enumeration value="female"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="first-name" type="xsd:string"/>
+ <xsd:element name="last-name" type="xsd:string"/>
+ <xsd:element name="gender" type="ppl:gender"/>
+ <xsd:element name="age" type="xsd:unsignedShort"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="directory">
+ <xsd:sequence>
+ <xsd:element name="person" type="ppl:person" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="directory" type="ppl:directory"/>
+
+</xsd:schema>